--- /dev/null
+[submodule "src/forb"]
+ path = src/forb
+ url = ../forb
+[submodule "src/fwp"]
+ path = src/fwp
+ url = ../fwp
+[submodule "src/ulut"]
+ path = src/ulut
+ url = git://rtime.felk.cvut.cz/ulut.git
+[submodule "src/frsh-include"]
+ path = src/frsh-include
+ url = ../frsh-include
+[submodule "src/fna"]
+ path = src/fna
+ url = ../fna
+[submodule "src/fosa"]
+ path = src/fosa
+ url = ../fosa
+[submodule "src/frsh"]
+ path = src/frsh
+ url = ../frsh
+[submodule "src/wvtest"]
+ path = src/wvtest
+ url = git://rtime.felk.cvut.cz/wvtest.git
--- /dev/null
+* FRSH/FORB FRAMEWORK
+
+ FRSH/FORB is a contract-based resource reservation framework for
+ distributed real-time applications. In general, it provides timing
+ isolation between applications, i.e. multiple applications can use
+ the same resources such as CPU, networks, etc., without influencing
+ timing of the other applications. The main principle is that
+ application developers use FRSH API to specify their resource
+ requirements needed to achieve desired timeliness and the framework
+ uses schedulability analysis to check these requirements. If the
+ check is successful an application is granted a "virtual resource"
+ which allow the application to use the requested resource while
+ enforcing the application not to use more than requested.
+
+ The development of the framework begun in FRESCOR project
+ (http://frescor.org) and now it is developed as a stand-alone
+ project on SourceForge (http://frsh-forb.sf.net).
+
+* BUILDING FRSH/FORB FRAMEWORK
+
+1) Initialize and download additional submodules:
+
+ git submodule init
+ git submodule update
+
+2) Install prerequisites. On Debian/Ubuntu:
+
+ apt-get install libidl-dev libcpufreq-dev libacpi-dev \
+ libcgroup-dev libncurses5-dev
+
+ To build camera demo, you need to:
+
+ apt-get install freeglut3-dev
+
+3) Go to build directory and configure the build:
+
+ cd build/aquosa
+ make default-config
+
+ If you are not satisfied with configuration found in
+ config.omk-default or config.target, you can override it in
+ config.omk.
+
+ To be able to use CPU reservations AQuoSA
+ (http://aquosa.sourceforge.net) has to be installed. If you cannot
+ use AQuoSA, the framework can also be compiled without CPU support
+ (echo CONFIG_AQUOSA=n >> config.omk) or can use cgroups (echo
+ CONFIG_CPUCG=y >> config.omk). Note, that cgroups support is not
+ well tested, but we plan to work on it.
+
+4) Compile it:
+
+ make
+
+5) Test it:
+
+ ./_compiled/bin/fcb &
+ ./_compiled/bin/frm_dummy &
+ ./_compiled/bin/frm_gui &
+ ./_compiled/bin-tests/dummy_renegotiation
+
+* DIRECTORY STRUCTURE
+
+ * build/* - configuration for different build targets
+
+ * build/aquosa - default build for linux
+
+ * build/marte - build for MarteOS. Not completely supported now.
+
+ * src - all sources
+
+ * src/forb - CORBA-like middle for interprocess and inter-node
+ communication.
+
+ * src/frsh - The core of resource reservation framework.
+
+ * src/frsh-include - FRSH API headers from FRESCOR project. Our FRSH
+ framework implements this API.
+
+ * src/fosa - Operating system adaptation layer
+
+ * src/ulut - library providing generic data types and algorithms
+ (AVL trees etc.).
+
+ * src/fna - Network adaptation layer = unified API for plugging in
+ different network protocols.
+
+ * src/fwp - Communication protocol and resource management for WiFi
+ (also works with Ethernet).
+
+* OLD HOWTO - may be out of date
+
+ Linux + AQuoSA
+
+ * Install AQuoSA (http://aquosa.sourceforge.net)
+ * $HOME/frescor/src/omk-build/aquosa
+ * Adjust symlinks to FRESCOR modules (fosa, frsh, utils, ...) or use ./create-links script
+ * Create config.omk containing (or use a shell variable in your .bashrc)
+
+ AQUOSA_ROOT=/path/to/aquosa/install/path
+
+ * Actually, my preferred way of working is adding the following
+ variables in .bashrc:
+
+ # AQuoSA environment
+
+ export AQUOSA_ROOT=/usr/local/aquosa
+ export PATH="$PATH:$AQUOSA_ROOT/bin"
+ export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$AQUOSA_ROOT/lib"
+
+ # FRESCOR environment
+
+ export PLATFORM=AQuoSA
+ export FOSA_ROOT=$HOME/path/to/fosa
+ export FRSH_ROOT=$HOME/path/to/frsh
+ export UTILS_ROOT=$HOME/path/to/utils
+ LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$FOSA_ROOT/lib:$FRSH_ROOT/lib:$UTILS_ROOT/lib"
+
+ # OMK environment
+
+ # Use `omk' for OMK-enabled sources
+ alias omk="make -f $HOME/path/to/Makefile.rules"
+ # link headers instead of copying them
+ export LN_HEADERS=y
+
+ * Create default-configuration by running
+
+ make default-config
+
+ * Run
+
+ make
+
+** Further remarks
+
+- If we are not interested in compilation of some component (because
+ it is currently in uncompilable state), we can simply delete the
+ link to it.
+
+- It might be possible that you will need to change some configuration
+ value from config.target. You can override any variable declared
+ there in config.omk. For example, if you have MARTE installed in a
+ different directory that the one specified in config.target, you can
+ put the following in config.omk:
+
+ MARTE_PATH=/path/to/marte/
+
+- To compile the FRESCOR for Marte, it is not necessary to set PATH
+ variable to GNAT compiler since OMK uses full paths to call the
+ compiler.
+
+- Since there are many things in uncompilable state, you may want to
+ use `make -k' to ignore compilation errors.
+
+- Since we don't want to modify the original Makefiles, in order to
+ compile only a part of the tree, you cannot simply run make in the
+ desired directory, but you have to specify -f flag with the path to
+ Makefile.rules. For this reason, we recommend defining the following
+ alias:
+
+ alias omk="make -f $HOME/frescor/src/omk-build/marte/Makefile.rules"
+
+** Why is OMK good for FRESCOR
+
+ * It is not easy to test FRESCOR simultaneously on multiple platforms.
+ With OMK, you can have the same sources compiled for multiple
+ platforms/targets at the same time because it uses out of source
+ directory compilation.
+ * Dependencies are not handled correctly in current Makefiles. For
+ example headers (in most tests) and some libraries (fosa_xxx) are not
+ specified as dependencies. OMK handles dependencies automatically, so
+ developers don't have to care about them.
+ * With OMK it is easy to combine multiple components/libraries (from
+ different developers) together and compile them with the same
+ configuration (e.g. PLATFORM variable). The structure of leaf
+ makefiles (Makefile for every component) is very simple and *well
+ specified*. Because of this it is easy to combine components from
+ multiple developers.
+ * Directory structure for compilation with current makefiles must be
+ fixed. In makefiles there is many "..". This prevents the use of
+ symbolic links to create desired directory structure because make
+ always treats ".." physically (i.e. it don't respect the directory
+ structure created by symbolic links). In OMK, the position of
+ directories in the source tree is not important. This is another
+ reason, why integration is simpler with OMK.
+ * OMK already supports compilation for user-space programs/libraries,
+ Linux and RTLinux modules, RTEMS and several other platforms. Now we
+ have also added support for Marte. It works under MinGW and Cygwin, so
+ it can be used to compile for OSE. In Pisa, they already use OMK for
+ Aquosa.
+
+** FAQ
+
+- How do I debug my Makefile.omk set-up ?
+
+ Just activate verbose compilation (V=1 or V=2):
+
+ make -f /path/to/Makefile.rules binary-pass V=1
+
+- How do I get back syntax highlighting in Emacs while editing .omk files ?
+
+ Just add these lines to your $(HOME)/.emacs:
+
+ (setq auto-mode-alist
+ (append '(("\.omk$" . makefile-mode))
+ auto-mode-alist))
--- /dev/null
+_compiled/
+_build/
+config.omk-default
+config.omk
--- /dev/null
+cscope.files
+cscope.out
--- /dev/null
+SUBDIRS=$(ALL_OMK_SUBDIRS) wvtest/c
+EXTRA_RULES_SUBDIRS = forb/forb-idl
+
--- /dev/null
+# Makefile.rules - OCERA make framework common project rules -*- makefile-gmake -*- #OMK:base.omk
+#
+# (C) Copyright 2003, 2006, 2007, 2008, 2009 by Pavel Pisa - OCERA team member
+# (C) Copyright 2006, 2007, 2008, 2009, 2010 by Michal Sojka - Czech Technical University, FEE, DCE
+#
+# Homepage: http://rtime.felk.cvut.cz/omk/
+# Version: 0.2-29-gac7ec3c
+#
+# The OMK build system is distributed under the GNU General Public
+# License. See file COPYING for details.
+#
+#
+# Version for Linux/RTLinux builds. #OMK:linux.omk
+#
+#
+# input variables #OMK:base.omk
+# V .. if set to 1, full command text is shown else short form is used
+# W .. whole tree - if set to 1, make is always called from the top-level directory
+# SUBDIRS .. list of subdirectories intended for make from actual directory
+# default_CONFIG .. list of default config assignments CONFIG_XXX=y/n ...
+# wvtest_SCRIPTS .. list of scripts producing wvtest output #OMK:wvtest.omk
+# wvtest_PROGRAMS .. list of the testing programs producing wvtest output
+# LN_HEADERS .. if "y", header files are symbolicaly linked instead of copied. #OMK:include.omk
+# input variables #OMK:linux.omk
+# lib_LIBRARIES .. list of the user-space libraries
+# shared_LIBRARIES .. list of the user-space shared libraries
+# kernel_LIBRARIES .. list of the kernel-space libraries
+# rtlinux_LIBRARIES.. list of the RT-Linux kernel-space libraries
+# include_HEADERS .. list of the user-space public header files
+# nobase_include_HEADERS .. public headers copied even with directory part
+# renamed_include_HEADERS .. public headers copied to the different target name
+# kernel_HEADERS .. list of the kernel-space public header files
+# rtlinux_HEADERS .. list of the RT-Linux kernel-space public header files
+# bin_PROGRAMS .. list of the require binary programs
+# utils_PROGRAMS .. list of the development utility programs
+# test_PROGRAMS .. list of the testing programs
+# kernel_MODULES .. list of the kernel side modules/applications
+# rtlinux_MODULES .. list of RT-Linux the kernel side modules/applications
+# xxx_SOURCES .. list of specific target sources
+# xxx_LIBS .. list of specific target libraries (-l prefix is automatically added)
+# xxx_LDFLAGS .. list of specific target LDFLAGS
+# lib_LOADLIBES .. list of libraries linked to each executable
+# INCLUDES .. additional include directories and defines for user-space
+# kernel_INCLUDES .. additional include directories and defines for kernel-space
+# rtlinux_INCLUDES .. additional include directories and defines for RT-Linux
+# OMIT_KERNEL_PASSES if defined, all kernel passes are omited
+#
+# LINUX_DIR .. location of Linux kernel sources
+# RTL_DIR .. location of RT-Linux sources
+# CFLAGS .. C compiler flags
+# CXXFLAGS .. C++ compiler flags
+# CPPFLAGS .. C preprocessor flags
+# LDFLAGS .. linker flags for programs linking
+# LOCAL_CONFIG_H .. name of local config.h file generated from values #OMK:config_h.omk
+# of options defined in the current directory
+# config_include_HEADERS .. names of global config files (possibly
+# with subdirectories)
+# xxx_DEFINES .. list of config directives to be included in
+# config header file of the name <somedir>/xxx.h
+# DOXYGEN .. if non-empty, generated headers includes Doxygen's @file
+# command, so it is possible to document config
+# variables.
+# QT_PROJECTS .. list of QT .pro file to use for compilation #OMK:qt.omk
+# QT_SUBDIRS .. subdirectories where to build QT applications using qmake (depricated)
+# QTDIR .. where QT resides
+OMK_RULES_TYPE=linux #OMK:Makefile.rules.linux@
+ #OMK:base.omk@Makefile.rules.linux
+# If we are not called by OMK leaf Makefile...
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(abspath $(dir $(filter %Makefile.rules,$(MAKEFILE_LIST))))
+endif
+
+# OUTPUT_DIR is the place where _compiled, _build and possible other
+# files/directories are created. By default is the same as
+# $(MAKERULES_DIR).
+ifndef OUTPUT_DIR
+OUTPUT_DIR := $(MAKERULES_DIR)
+endif
+
+# We need to ensure definition of sources directory first
+ifndef SOURCES_DIR
+# Only shell built-in pwd understands -L
+SOURCES_DIR := $(shell ( pwd -L ) )
+INVOCATION_DIR := $(SOURCES_DIR:$(OUTPUT_DIR)%=%)
+INVOCATION_DIR := $(INVOCATION_DIR:/%=%)
+INVOCATION_DIR := $(INVOCATION_DIR:\\%=%)
+endif
+
+.PHONY: all default check-make-ver print-hints omkize
+
+ifdef W
+ ifeq ("$(origin W)", "command line")
+ OMK_WHOLE_TREE:=$(W)
+ endif
+endif
+ifndef OMK_WHOLE_TREE
+ OMK_WHOLE_TREE:=0
+endif
+
+ifneq ($(OMK_WHOLE_TREE),1)
+all: check-make-ver print-hints default
+ @echo "Compilation finished"
+else
+# Run make in the top-level directory
+all:
+ @$(MAKE) -C $(MAKERULES_DIR) OMK_SERIALIZE_INCLUDED=n SOURCES_DIR=$(MAKERULES_DIR) RELATIVE_DIR="" $(MAKECMDGOALS) W=0
+endif
+
+ifdef OMK_TESTSROOT
+# Usage: $(call canttest,<error message>)
+define canttest
+ ( echo "$(1)" > $(OUTPUT_DIR)/_canttest; echo "$(1)"; exit 1 )
+endef
+else
+define canttest
+ echo "$(1)"
+endef
+endif
+
+#=========================
+# Include the config file
+
+ifndef CONFIG_FILE
+CONFIG_FILE := $(OUTPUT_DIR)/config.omk
+endif
+
+$(CONFIG_FILE)-default:
+ $(MAKE) default-config
+
+ifeq ($(MAKECMDGOALS),default-config)
+export DEFAULT_CONFIG_PASS=1
+endif
+
+ifneq ($(DEFAULT_CONFIG_PASS),1)
+include $(CONFIG_FILE)-default
+endif
+
+-include $(OUTPUT_DIR)/config.target
+
+ifneq ($(wildcard $(CONFIG_FILE)),)
+-include $(CONFIG_FILE)
+endif
+
+
+CONFIG_FILES ?= $(wildcard $(CONFIG_FILE)-default) $(wildcard $(OUTPUT_DIR)/config.target) $(wildcard $(CONFIG_FILE))
+
+
+export SOURCES_DIR MAKERULES_DIR RELATIVE_DIR INVOCATION_DIR
+export CONFIG_FILE CONFIG_FILES OMK_SERIALIZE_INCLUDED OMK_VERBOSE OMK_SILENT
+# OMK_SERIALIZE_INCLUDED has to be exported to submakes because passes
+# must to be serialized only in the toplevel make.
+
+ifndef RELATIVE_DIR
+RELATIVE_DIR := $(SOURCES_DIR:$(OUTPUT_DIR)%=%)
+endif
+#$(warning === RELATIVE_DIR = "$(RELATIVE_DIR)" ===)
+override RELATIVE_DIR := $(RELATIVE_DIR:/%=%)
+override RELATIVE_DIR := $(RELATIVE_DIR:\\%=%)
+#$(warning RELATIVE_DIR = "$(RELATIVE_DIR)")
+#override BACK2TOP_DIR := $(shell echo $(RELATIVE_DIR)/ | sed -e 's_//_/_g' -e 's_/\./_/_g' -e 's_^\./__g' -e 's_\([^/][^/]*\)_.._g' -e 's_/$$__')
+#$(warning BACK2TOP_DIR = "$(BACK2TOP_DIR)")
+
+#$(warning SOURCES_DIR = "$(SOURCES_DIR)")
+#$(warning MAKERULES_DIR = "$(OUTPUT_DIR)")
+#$(warning RELATIVE_DIR = "$(RELATIVE_DIR)")
+
+# We have to use RELATIVE_PREFIX because of mingw
+override RELATIVE_PREFIX := $(RELATIVE_DIR)/
+override RELATIVE_PREFIX := $(RELATIVE_PREFIX:/%=%)
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+# Define srcdir for Automake compatibility
+srcdir = $(SOURCES_DIR)
+
+# Defines for quiet compilation
+ifdef V
+ ifeq ("$(origin V)", "command line")
+ OMK_VERBOSE = $(V)
+ endif
+endif
+ifndef OMK_VERBOSE
+ OMK_VERBOSE = 0
+endif
+ifneq ($(OMK_VERBOSE),0)
+ Q =
+else
+ Q = @
+endif
+ifneq ($(findstring s,$(MAKEFLAGS)),)
+ QUIET_CMD_ECHO = true
+ OMK_SILENT = 1
+else
+ QUIET_CMD_ECHO = echo
+endif
+
+MAKEFILE_OMK=Makefile.omk
+# All subdirectories (even linked ones) containing Makefile.omk
+# Usage in Makefile.omk: SUBDIRS = $(ALL_OMK_SUBDIRS)
+ALL_OMK_SUBDIRS = $(patsubst %/$(MAKEFILE_OMK),%,$(patsubst $(SOURCES_DIR)/%,%,$(wildcard $(SOURCES_DIR)/*/$(MAKEFILE_OMK))))
+
+# ===================================================================
+# We have set up all important variables, so we can check and include
+# real OCERA style Makefile.omk now
+ifndef OMK_INCLUDED
+include $(SOURCES_DIR)/$(MAKEFILE_OMK)
+ifeq ($(AUTOMATIC_SUBDIRS),y)
+SUBDIRS?=$(ALL_OMK_SUBDIRS)
+endif
+OMK_INCLUDED := 1
+endif
+
+print-hints:
+ @echo 'Use "make V=1" to see the verbose compile lines.'
+
+check-make-ver:
+ @GOOD_MAKE_VERSION=`echo $(MAKE_VERSION) | sed -n -e 's/^[4-9]\..*\|^3\.9[0-9].*\|^3\.8[1-9].*/y/p'` ; \
+ if [ x$$GOOD_MAKE_VERSION != xy ] ; then \
+ echo "Your make program version is too old and does not support OMK system." ; \
+ echo "Please update to make program 3.81beta1 or newer." ; exit 1 ; \
+ fi
+
+distclean dist-clean:
+ @$(QUIET_CMD_ECHO) " RM $(COMPILED_DIR_NAME) $(BUILD_DIR_NAME)"
+ @rm -fr $(OUTPUT_DIR)/$(COMPILED_DIR_NAME) $(OUTPUT_DIR)/$(BUILD_DIR_NAME)
+
+# Common OMK templates
+# ====================
+
+# Syntax: $(call mkdir,<dir name>)
+define mkdir_def
+ [ -d $(1) ] || mkdir -p $(1) || exit 1
+endef
+
+ifneq ($(OMK_VERBOSE),2)
+NO_PRINT_DIRECTORY := --no-print-directory
+endif
+
+ifeq ($(USE_LEAF_MAKEFILES),n)
+export USE_LEAF_MAKEFILES
+SUBDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+SOURCESDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+else
+SUBDIR_MAKEFILE=$(SOURCES_DIR)/$(3)/Makefile
+SOURCESDIR_MAKEFILE=$(SOURCES_DIR)/Makefile
+endif
+
+pass = $(strip $(1))
+
+unexport SUBDIRS
+
+# Call a pass in a subdirectory
+# Usage: $(call omk_pass_subdir_template,<pass name>,<build dir>,<subdir>)
+define omk_pass_subdir_template
+.PHONY: $(pass)-$(3)-subdir
+$(pass)-submakes: $(pass)-$(3)-subdir
+$(pass)-$(3)-subdir: MAKEOVERRIDES:=$(filter-out SUBDIRS=%,$(MAKEOVERRIDES))
+$(pass)-$(3)-subdir:
+ @$(call mkdir_def,$(2)/$(3))
+ +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(3) $(NO_PRINT_DIRECTORY) \
+ RELATIVE_DIR=$(RELATIVE_PREFIX)$(3) -C $(2)/$(3) \
+ -f $(SUBDIR_MAKEFILE) $(pass)-submakes
+# In subdirectories we can call submakes directly since passes are
+# already serialized on the toplevel make.
+endef
+
+ifdef OMK_TESTSROOT
+check-target = $(1:%=%-check)
+endif
+
+# Call a pass in a subdirectory
+# Usage: $(call extra_rules_subdir_template,<subdir>)
+define extra_rules_subdir_template
+extra-rules-subdirs: extra-rules-$(1)
+extra-rules-$(1):
+ +@$(MAKE) OMK_SERIALIZE_INCLUDED=n MAKERULES_DIR=$(SOURCES_DIR)/$(1) OUTPUT_DIR=$(OUTPUT_DIR) \
+ SOURCES_DIR=$(SOURCES_DIR)/$(1) RELATIVE_DIR=$(RELATIVE_PREFIX)$(1) -C $(SOURCES_DIR)/$(1)
+endef
+
+.PHONY: extra-rules-subdirs
+extra-rules-subdirs:
+
+$(foreach subdir,$(EXTRA_RULES_SUBDIRS),$(eval $(call extra_rules_subdir_template,$(subdir))))
+
+# Usage: $(call omk_pass_template,<pass name>,<build dir>,[<local make flags>],[<local enable condition>])
+define omk_pass_template
+.PHONY: $(pass) $(pass)-local $(pass)-check $(pass)-submakes
+$(foreach subdir,$(SUBDIRS),$(eval $(call omk_pass_subdir_template,$(pass),$(2),$(subdir))))
+$(pass):
+# Submakes have to be called this way and not as dependecies for pass
+# serialization to work
+ +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR) $(NO_PRINT_DIRECTORY) \
+ RELATIVE_DIR=$(RELATIVE_DIR) \
+ -f $(SOURCESDIR_MAKEFILE) $(pass)-submakes
+$(pass)-submakes:
+ @true # Do not emit "nothing to be done" messages
+
+ifneq ($(4)$($(pass)_HOOKS),)
+$(pass)-submakes: $(pass)-this-dir
+$(pass)-this-dir: $(foreach subdir,$(SUBDIRS),$(pass)-$(subdir)-subdir)
+ +@echo "make[omk]: $(pass) in $(RELATIVE_DIR)"
+ @$(call mkdir_def,$(2))
+ +@$(MAKE) $(NO_PRINT_DIRECTORY) SOURCES_DIR=$(SOURCES_DIR) RELATIVE_DIR=$(RELATIVE_DIR) -C $(2) \
+ -f $(SOURCESDIR_MAKEFILE) $(3) $(check-target) $(1:%=%-local)
+$(pass)-local: $($(pass)_HOOKS)
+endif
+endef
+
+# =======================
+# DEFAULT CONFIG PASS
+
+default-config:
+ @echo "# Start of OMK config file" > "$(CONFIG_FILE)-default"
+ @echo "# This file should not be altered manually" >> "$(CONFIG_FILE)-default"
+ @echo "# Overrides should be stored in file $(notdir $(CONFIG_FILE))" >> "$(CONFIG_FILE)-default"
+ @echo >> "$(CONFIG_FILE)-default"
+ @$(MAKE) $(NO_PRINT_DIRECTORY) -C $(OUTPUT_DIR) \
+ RELATIVE_DIR="" SOURCES_DIR=$(OUTPUT_DIR) \
+ -f $(OUTPUT_DIR)/Makefile default-config-pass
+
+$(eval $(call omk_pass_template,default-config-pass,$$(LOCAL_BUILD_DIR),,always))
+
+default-config-pass-local:
+# @echo Default config for $(RELATIVE_DIR)
+ @echo "# Config for $(RELATIVE_DIR)" >> "$(CONFIG_FILE)-default"
+ @$(foreach x, $(default_CONFIG), echo '$(x)' | \
+ sed -e 's/^[^=]*=x$$/#\0/' >> "$(CONFIG_FILE)-default" ; )
+
+
+omkize:
+ $(Q)if ! grep -q MAKERULES_DIR Makefile; then \
+ echo "Makefile is not OMK leaf makefile!" >&2; exit 1; \
+ fi
+ $(Q)for i in `find -L . -name Makefile.omk` ; do \
+ d=`dirname $${i}`; \
+ if ! test -f "$${d}/Makefile.rules" && ( test -f "$${d}/Makefile" && ! cmp --silent Makefile "$${d}/Makefile" ); then \
+ rm -f "$${d}/Makefile"; \
+ cp -v Makefile "$${d}/Makefile"; \
+ fi \
+ done
+ #OMK:wvtest.omk@Makefile.rules.linux
+# Documentation: wvtest_PROGRAMS is equivalent to test_PROGRAMS. The
+# difference is that it is automatically run during "make wvtest".
+test_PROGRAMS += $(wvtest_PROGRAMS)
+
+# Documentation: If your project uses wvtest, it is recomended to put
+# the "test: wvtest" rule to config.target.
+wvtest:
+ $(Q)$(MAKERULES_DIR)/wvtestrun $(MAKE) wvtest-pass
+
+.PHONY: wvtest
+
+$(eval $(call omk_pass_template,wvtest-pass,$$(LOCAL_BUILD_DIR),,$(wvtest_SCRIPTS)$(wvtest_PROGRAMS)))
+
+# Usage: $(call wvtest_template,<shell command>)
+define wvtest_template
+wvtest-pass-local: wvtest-run-$(1)
+.PHONY: wvtest-run-$(1)
+wvtest-run-$(1):
+ mkdir -p $(1).wvtest
+ cd $(1).wvtest && $(1)
+endef
+
+# Documentation: Write the test so, that it can be run from arbitrary
+# directory, i.e. in case of a script ensure that the wvtest library
+# is sourced like this:
+#
+# . $(dirname $0)/wvtest.sh
+
+$(foreach script,$(wvtest_SCRIPTS),$(eval $(call wvtest_template,$(SOURCES_DIR)/$(script))))
+# Hack!!!
+USER_TESTS_DIR := $(OUTPUT_DIR)/_compiled/bin-tests
+$(foreach prog,$(wvtest_PROGRAMS),$(eval $(call wvtest_template,$(USER_TESTS_DIR)/$(prog))))
+ifeq ($(OMK_VERBOSE),1) #OMK:include.omk@Makefile.rules.linux
+CPHEADER_FLAGS += -v
+LNHEADER_FLAGS += -v
+endif
+
+ifneq ($(LN_HEADERS),y)
+define cp_cmd
+if ! cmp --quiet $(1) $(2); then \
+ echo " CP $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; \
+ install -C -D $(CPHEADER_FLAGS) $(1) $(2) || exit 1; \
+fi
+endef
+else
+define cp_cmd
+if ! cmp --quiet $(1) $(2); then \
+ echo " LN $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; \
+ if [ -f $(1) ]; then d=$(2); mkdir -p $${d%/*} && ln -sf $(LNHEADER_FLAGS) $(1) $(2) || exit 1; else exit 1; fi; \
+fi
+endef
+endif
+
+# TODO: Check modification date of changed header files. If it is
+# newer that in source dir, show a warning.
+
+# Syntax: $(call include-pass-template,<include dir>,<keyword>)
+define include-pass-template
+include-pass-local: include-pass-local-$(2)
+include-pass-local-$(2): $$($(2)_GEN_HEADERS) $$(foreach f,$$(renamed_$(2)_GEN_HEADERS),$$(shell f='$$(f)'; echo $$$${f%->*}))
+ @$$(foreach f, $$($(2)_HEADERS),$$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(notdir $$(f))); )
+# FIXME: Use correct build dir, then document it (in the line bellow)
+ @$$(foreach f, $$($(2)_GEN_HEADERS),$$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$(f),$(1)/$$(notdir $$(f))); )
+ @$$(foreach f, $$(nobase_$(2)_HEADERS), $$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(f)); )
+ @$$(foreach f, $$(renamed_$(2)_HEADERS), \
+ f='$$(f)'; srcfname=$$$${f%->*}; destfname=$$$${f#*->}; \
+ $$(call cp_cmd,$$(SOURCES_DIR)/$$$${srcfname},$(1)/$$$${destfname}); )
+ @$$(foreach f, $$(renamed_$(2)_GEN_HEADERS), \
+ f='$$(f)'; srcfname=$$$${f%->*}; destfname=$$$${f#*->}; \
+ $$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$$${srcfname},$(1)/$$$${destfname}); )
+# Suppress "Nothing to be done for `include-pass-local'" message if no headers are defined in Makefile.omk
+ @$$(if $$($(2)_HEADERS)$$($(2)_GEN_HEADERS)$$(nobase_$(2)_HEADERS)$$(renamed_$(2)_HEADERS)$$(renamed_$(2)_GEN_HEADERS),,true)
+endef
+ #OMK:linux.omk@Makefile.rules.linux
+# Hack to check RT-Linux rules
+#LINUX_DIR := /home/cvs/ocera/ocera-build/kernel/linux
+#RTL_DIR := /home/cvs/ocera/ocera-build/kernel/rtlinux
+#CONFIG_RTLINUX = y
+#OCERA_DIR := $(shell ( cd -L $(OUTPUT_DIR)/../../.. ; pwd -L ) )
+
+-include $(OUTPUT_DIR)/OCERA_TOP_DIR
+
+BUILD_DIR_NAME = _build
+COMPILED_DIR_NAME = _compiled
+ifndef GROUP_DIR_NAME
+GROUP_DIR_NAME = nogroup
+endif
+
+ifdef OCERA_DIR
+ifeq ($(wildcard $(OCERA_DIR)/ocera.mk),)
+$(warning "ocera.mk" file does not exist. Adapt Makefile.rules for standalone compilation)
+$(warning (comment out definition of OCERA_DIR line and optionally select RTL_DIR) )
+$(error or go to the ocera/ directory and do 'make' to generate the "ocera.mk" file first, please)
+endif
+include $(OCERA_DIR)/ocera.mk
+KERN_INCLUDE_DIR := $(OCERA_KERNEL_INCLUDES_DIR)
+KERN_LIB_DIR := $(OCERA_KERNEL_LIBRARIES_DIR)
+KERN_MODULES_DIR := $(OCERA_MODULES_DIR)
+KERN_BUILD_DIR := $(BUILD_DIR)/kern/$(GROUP_DIR_NAME)
+KERN_MODPOST_DIR := $(BUILD_DIR)/kern-modpost
+USER_INCLUDE_DIR := $(OCERA_USER_INCLUDES_DIR)
+USER_LIB_DIR := $(OCERA_USER_LIBRARIES_DIR)
+USER_UTILS_DIR := $(TARGET_DIR)/usr/bin
+USER_TESTS_DIR := $(TARGET_DIR)/usr/bin
+USER_BIN_DIR := $(TARGET_DIR)/usr/bin
+USER_BUILD_DIR := $(BUILD_DIR)/user/$(GROUP_DIR_NAME)
+#LINUX_DIR := $(OCERA_DIR)/kernel/linux
+#RTL_DIR := $(OCERA_DIR)/kernel/rtlinux
+#CONFIG_FILE := $(OCERA_DIR)/emdebsys/.config
+ifneq ($(wildcard $(CONFIG_FILE)),)
+CONFIG_FILE_OK = y
+endif
+else # OCERA_DIR
+KERN_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include-kern
+KERN_LIB_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib-kern
+KERN_MODULES_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/modules
+KERN_BUILD_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern
+KERN_MODPOST_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern-modpost
+USER_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include
+USER_LIB_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib
+USER_UTILS_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-utils
+USER_TESTS_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-tests
+USER_BIN_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin
+USER_BUILD_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/user
+
+ifndef LINUX_VERSION
+LINUX_VERSION=$(shell uname -r)
+endif
+ifndef LINUX_DIR
+LINUX_DIR=/lib/modules/$(LINUX_VERSION)/build
+endif
+endif # OCERA_DIR
+
+ifeq ($(BUILD_OS),)
+ # Check for target
+ ifeq ($(OS),Windows_NT)
+ BUILD_OS := win32
+ else
+ BUILD_OS := $(shell uname | tr '[A-Z]' '[a-z]' )
+ #$(warning BUILD_OS=$(BUILD_OS))
+ endif
+endif
+
+ifeq ($(TARGET_OS),)
+ TARGET_OS := $(BUILD_OS)
+endif
+
+export TARGET_OS
+export BUILD_OS
+
+LOCAL_BUILD_DIR = $(USER_OBJS_DIR)
+
+# Assign default values to CFLAGS variable. If the variable is defined
+# earlier (i.g. in config.omk), it is not overriden here.
+CFLAGS ?= -O2 -Wall
+CXXFLAGS ?= -O2 -Wall
+
+
+CPPFLAGS += -I $(USER_INCLUDE_DIR)
+
+LOADLIBES += -L$(USER_LIB_DIR)
+
+LOADLIBES += $(lib_LOADLIBES:%=-l%)
+
+LIB_CPPFLAGS += $(CPPFLAGS)
+LIB_CFLAGS += $(CFLAGS)
+
+ifeq ($(TARGET_OS),win32)
+ EXE_SUFFIX = .exe
+ SOLIB_EXT = dll
+else
+ SOLIB_EXT = so
+ SOLIB_PICFLAGS += -fpic
+endif
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+USER_OBJS_DIR = $(USER_BUILD_DIR)/$(RELATIVE_DIR)
+KERN_OBJS_DIR = $(KERN_BUILD_DIR)/$(RELATIVE_DIR)
+OMK_WORK_DIR = $(USER_OBJS_DIR)
+
+.PHONY: dep subdirs clean clean-custom cleandepend check-dir
+
+# Some support to serialize some targets for parallel make
+ifneq ($(OMK_SERIALIZE_INCLUDED),y)
+include-pass: check-dir
+library-pass: include-pass
+link-pseudo-pass: library-pass
+binary-pass: link-pseudo-pass
+kernel-lib-pass: include-pass
+kernel-mod-pass: kernel-lib-pass
+kernel-modpost-pass: kernel-mod-pass
+kernel-pass: kernel-mod-pass kernel-modpost-pass
+
+override OMK_SERIALIZE_INCLUDED = y
+MAKEOVERRIDES := $(filter-out OMK_SERIALIZE_INCLUDED=n,$(MAKEOVERRIDES))
+endif
+
+# Checks for OMK tester
+ifdef OMK_TESTSROOT
+default-config-pass-check include-pass-check:
+library-pass-check binary-pass-check:
+ @[ -x "$(shell which $(CC))" ] || $(call canttest,Cannot find compiler: $(CC))
+endif
+
+#=====================================================================
+# User-space rules and templates to compile programs, libraries etc.
+
+ifdef USER_RULE_TEMPLATES
+
+USER_SOURCES2OBJS = .o/.c .o/.cc .o/.cxx .o/.S .o/.o
+
+USER_SOURCES2OBJSLO = .lo/.c .lo/.cc .lo/.cxx .lo/.S .lo/.lo
+
+#%.lo: %.c
+# $(CC) -o $@ $(LCFLAGS) -c $<
+
+c_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+cc_o_COMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+S_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(ASFLAGS) -DOMK_FOR_USER
+
+idl_COMPILE = $(IDL_COMPILER)
+
+# Check GCC version for user build
+ifndef CC_MAJOR_VERSION
+CC_MAJOR_VERSION := $(shell $(CC) -dumpversion | sed -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(CC_MAJOR_VERSION),2)
+CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+
+# Syntax: $(call COMPILE_c_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_c_o_template
+$(2): $(1) $$(GEN_HEADERS)
+ @$(QUIET_CMD_ECHO) " CC $$@"
+ $(Q) if $$(c_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+# Syntax: $(call COMPILE_cc_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_cc_o_template
+$(2): $(1) $$(GEN_HEADERS)
+ @$(QUIET_CMD_ECHO) " CXX $$@"
+ $(Q) if $$(cc_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+# Syntax: $(call COMPILE_S_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_S_o_template
+$(2): $(1) $$(GEN_HEADERS)
+ @$(QUIET_CMD_ECHO) " AS $$@"
+ $(Q) if $$(S_o_COMPILE) -D__ASSEMBLY__ $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+NM ?= nm
+
+# Syntax: $(call CMETRIC_o_h_template,<object_file>,<target_header>)
+define CMETRIC_o_h_template
+$(2): $(1)
+ @$(QUIET_CMD_ECHO) " CMETRIC $$@"
+ $(Q)if [ -n `dirname $$@` ] ; then \
+ if [ ! -e `dirname $$@` ] ; then \
+ mkdir -p `dirname $$@` ; fi ; fi
+ $(Q)echo >$$@.tmp '/* Automatically generated from $$< */'
+ $(Q)echo >>$$@.tmp '/* Conditionals to control compilation */'
+# Bellow, the tricks with redirection are for shells without set -o pipefail
+# (see http://www.mail-archive.com/dash@vger.kernel.org/msg00149.html)
+ $(Q)exec 3>&1; status=`exec 4>&1 >&3; { $(NM) $$<; echo $$$$? >&4; }\
+ | sed -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2cond_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+ | sort >>$$@.tmp` && exit $$$$status
+ $(Q)echo >>$$@.tmp '/* Defines from the values defined to symbols in hexadecimal format */'
+ $(Q)exec 3>&1; status=`exec 4>&1 >&3; { $(NM) $$<; echo $$$$? >&4; }\
+ | sed -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2def_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+ | sort >>$$@.tmp` && exit $$$$status
+ $(Q)echo >>$$@.tmp '/* Defines from the values defined to symbols in decimal format */'
+ $(Q)exec 3>&1; status=`exec 4>&1 >&3; { $(NM) -td $$<; echo $$$$? >&4; }\
+ | sed -n 's/^ *0*\(0\|[1-9][0-9]*\) *A *_cmetric2defdec_\([A-Za-z_0-9]*\) */#define \2 \1/p' \
+ | sort >>$$@.tmp` && exit $$$$status
+ $(Q)mv $$@.tmp $$@
+endef
+
+
+
+define COMPILE_idl_template
+$(2).c $(2)-stubs.c $(2)-skels.c $(2)-common.c $(2).h: $(1) $$(wildcard $$(firstword $$(idl_COMPILE)))
+ @$(QUIET_CMD_ECHO) " IDL $$@"
+ $(Q) $$(idl_COMPILE) $$($(2)_IDLFLAGS) $(1)
+endef
+
+
+# Syntax: $(call PROGRAM_template,<dir>,<executable-name>,<executable-suffix>,<linker-sript>)
+# FIXME: ???????? asi je tu blbej komentar
+define PROGRAM_template
+
+USER_IDLS += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+USER_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+ $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+USER_OBJS += $$($(1)_OBJS)
+USER_SOURCES += $$($(1)_SOURCES)
+
+$(2)/$(1)$(3): $$($(1)_OBJS)
+ @$(QUIET_CMD_ECHO) " LINK $$@"
+ $(Q) $$(if $$(filter %.cc,$$($(1)_SOURCES:%.cxx=%.cc)),$$(CXX),$$(CC)) \
+ $$($(1)_OBJS) $$($(1)_LIBS:%=-l%) $$(LOADLIBES) $$(LDFLAGS) $$($(1)_LDFLAGS) -Wl,-rpath-link,$(USER_LIB_DIR) -Wl,-Map,$(USER_OBJS_DIR)/$(1).exe.map -o $$@
+ @echo "$(2)/$(1)$(3): \\" >$(USER_OBJS_DIR)/$(1).exe.d
+ @sed -n -e 's|^LOAD \(.*\)$$$$| \1 \&|p' $(USER_OBJS_DIR)/$(1).exe.map|tr '&' '\134' >>$(USER_OBJS_DIR)/$(1).exe.d
+ @echo >>$(USER_OBJS_DIR)/$(1).exe.d
+endef
+
+
+# Syntax: $(call LIBRARY_template,<library-name>)
+define LIBRARY_template
+
+USER_IDLS += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+USER_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+ $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+USER_OBJS += $$($(1)_OBJS)
+USER_SOURCES += $$($(1)_SOURCES)
+
+$(USER_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+ @$(QUIET_CMD_ECHO) " AR $$@"
+ $(Q) $(AR) rcs $$@ $$^
+endef
+
+.PHONY: FORCE
+
+# Syntax: $(call SOLIB_template,<library-name>)
+define SOLIB_template
+
+USER_IDLS += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+SOLIB_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJSLO),
+$(1)_OBJSLO += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+ $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJSLO := $$(sort $$($(1)_OBJSLO:%/=%))
+
+SOLIB_OBJS += $$($(1)_OBJSLO)
+SOLIB_SOURCES += $$($(1)_SOURCES)
+
+$(OMK_WORK_DIR)/lib$(1).$(SOLIB_EXT).omkvar: $$($(1)_OBJSLO) FORCE
+ $(Q)echo '$(1)_objslo += $$$$(addprefix $(USER_OBJS_DIR)/,$$($(1)_OBJSLO))' > $$@.tmp; \
+ echo '$(1)_libs += $$($(1)_LIBS) $$(lib_LOADLIBES)' >> $$@.tmp; \
+ echo '$(1)_ldflags += $$($(1)_LDFLAGS) $$(lib_LDFLAGS)' >> $$@.tmp; \
+ echo 'shared_libs := $$$$(sort $(1) $$$$(shared_libs))' >> $$@.tmp; \
+ if cmp -s $$@.tmp $$@; then rm $$@.tmp; else mv $$@.tmp $$@; fi
+endef
+
+library-pass-local: $(addprefix $(USER_INCLUDE_DIR)/,$(cmetric_include_HEADERS)) \
+ $(lib_LIBRARIES:%=$(USER_LIB_DIR)/lib%.a) $(shared_LIBRARIES:%=$(OMK_WORK_DIR)/lib%.$(SOLIB_EXT).omkvar)
+
+binary-pass-local: $(bin_PROGRAMS:%=$(USER_BIN_DIR)/%$(EXE_SUFFIX)) $(utils_PROGRAMS:%=$(USER_UTILS_DIR)/%$(EXE_SUFFIX)) $(test_PROGRAMS:%=$(USER_TESTS_DIR)/%$(EXE_SUFFIX))
+
+# Special rules for CMETRIC generated headers
+
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call COMPILE_c_o_template,\
+ $(SOURCES_DIR)/$($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES),\
+ $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),)))
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call CMETRIC_o_h_template,\
+ $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),\
+ $(addprefix $(USER_INCLUDE_DIR)/,$(cmetrh)))))
+
+GEN_HEADERS+=$(cmetric_include_HEADERS:%=$(USER_INCLUDE_DIR)/%)
+
+GEN_HEADERS+=$(filter %.h,$(USER_IDLS:%.idl=%.h))
+
+# Generate rules for compilation of programs and libraries
+
+$(foreach prog,$(utils_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_UTILS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(test_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_TESTS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(bin_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_BIN_DIR),$(EXE_SUFFIX))))
+
+$(foreach lib,$(lib_LIBRARIES),$(eval $(call LIBRARY_template,$(lib))))
+
+$(foreach lib,$(shared_LIBRARIES),$(eval $(call SOLIB_template,$(lib))))
+
+-include $(USER_OBJS_DIR)/*.d
+#FIXME: This doesn't include dependencies of source files from
+#subdirectories (i.s. *_SOURCES=dir/file.c. I'm currently not sure,
+#how to handle this.
+
+endif # USER_RULE_TEMPLATES
+
+.PHONY: link-pseudo-pass
+link-pseudo-pass:
+ $(Q)$(MAKE) $(NO_PRINT_DIRECTORY) -C $(USER_BUILD_DIR) -f $(SOURCESDIR_MAKEFILE) link-shared-libs
+
+ifeq ($(MAKECMDGOALS),link-shared-libs)
+
+# Syntax: $(call solib_link_template,<library-name>)
+define solib_link_template
+$(1)_shared_libs = $$(patsubst %,$(USER_LIB_DIR)/lib%.$(SOLIB_EXT),$$(filter $$(shared_libs),$$($(1)_libs)))
+#$$(warning $(1)_shared_libs = $$($(1)_shared_libs))
+$(USER_LIB_DIR)/lib$(1).$(SOLIB_EXT): $$($(1)_shared_libs) $$($(1)_objslo)
+ @$(QUIET_CMD_ECHO) " LINK $$@"
+ $(Q)$(CC) --shared -Xlinker -soname=lib$(1).$(SOLIB_EXT) -Wl,-Map,$(USER_OBJS_DIR)/lib$(1).$(SOLIB_EXT).map -o $$@ $$($(1)_objslo) $$(LOADLIBES) $$($(1)_libs:%=-l%) $$(lib_ldflags) $$($(1)_ldflags)
+endef
+
+-include $(shell true; find $(USER_BUILD_DIR) -name 'lib*.omkvar') # `true' is a hack for MinGW
+#$(warning $(shared_libs))
+$(foreach lib,$(shared_libs),$(eval $(call solib_link_template,$(lib))))
+
+.PHONY: link-shared-libs
+link-shared-libs: $(shared_libs:%=$(USER_LIB_DIR)/lib%.$(SOLIB_EXT))
+endif # link-shared-libs
+
+#=====================================================================
+# Kernel-space rules and templates to compile modules, libraries etc.
+
+ifdef KERN_RULE_TEMPLATES
+
+$(KERN_LIB_DIR)/kernel.mk: $(LINUX_DIR)/.config $(MAKERULES_DIR)/kernelcfg2mk
+ @$(QUIET_CMD_ECHO) " KCFG2MK $@"
+ $(Q) $(MAKERULES_DIR)/kernelcfg2mk $(LINUX_DIR) $(KERN_LIB_DIR)
+
+ifeq ($(CONFIG_RTLINUX),y)
+include $(RTL_DIR)/rtl.mk
+
+KERN_CC = $(CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(CC) -print-search-dirs | sed -n -e 's/^install: \(.*\)$$/\1/p' )
+INCLUDES := -I $(KERN_INCLUDE_DIR) $(INCLUDE) $(rtlinux_INCLUDES) $(kernel_INCLUDES)
+#-DEXPORT_NO_SYMBOLS
+c_o_kern_COMPILE = $(KERN_CC) -idirafter $(kern_GCCLIB_DIR)/include $(INCLUDES) $(CFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(CXX) $(INCLUDES) $(CXXFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+KERN_EXE_SUFFIX := .o
+KERN_ARCH = $(ARCH)
+KERN_LD = $(LD)
+KERN_AR = $(AR)
+
+else # CONFIG_RTLINUX
+
+include $(KERN_LIB_DIR)/kernel.mk
+
+ifeq ($(LINUX_SRC),)
+LINUX_SRC = $(LINUX_DIR)
+endif
+kernel_INCLUDES += -I $(KERN_INCLUDE_DIR) -I $(LINUX_DIR) -idirafter $(LINUX_SRC)/include/linux
+
+ifdef LINUX_CC
+KERN_CC = $(LINUX_CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(LINUX_CC) -print-search-dirs | sed -n -e 's/^install: \(.*\)$$/\1/p' )
+else
+KERN_CC = echo KERN_CC not defined - compilation skipped
+endif
+c_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+S_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_AFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+KERN_EXE_SUFFIX := $(LINUX_MODULE_EXT)
+KERN_LDFLAGS = $(LINUX_LDFLAGS)
+ifdef LINUX_ARCH
+KERN_ARCH = $(LINUX_ARCH)
+else
+KERN_ARCH = echo KERN_ARCH not defined - skipped
+endif
+ifdef LINUX_LD
+KERN_LD = $(LINUX_LD)
+else
+KERN_LD = echo KERN_LD not defined - skipped
+endif
+ifneq ($(LINUX_AR),)
+KERN_AR = $(LINUX_AR)
+else
+KERN_AR = $(AR)
+endif
+ifeq ($(LINUX_QUOTE_MODNAME),y)
+KERN_MQ=\"
+KERN_KBUILD_MODNAME=-D"KBUILD_MODNAME=((THIS_MODULE)!=NULL?(THIS_MODULE)->name:NULL)"
+endif
+endif # CONFIG_RTLINUX
+
+KERN_LOADLIBES += -L$(KERN_LIB_DIR)
+
+KERN_LOADLIBES += $(rtlinux_LOADLIBES:%=-l%)
+KERN_LOADLIBES += $(kernel_LOADLIBES:%=-l%)
+
+
+
+# Check GCC version for kernel part of build
+ifndef kern_CC_MAJOR_VERSION
+kern_CC_MAJOR_VERSION := $(shell $(KERN_CC) -dumpversion | sed -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(kern_CC_MAJOR_VERSION),2)
+kern_CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+kern_CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+ifeq ($(KERN_EXE_SUFFIX),.ko)
+ifeq ($(wildcard $(LINUX_DIR)/scripts/mod/modpost),)
+KERN_MODPOST = $(LINUX_DIR)/scripts/modpost
+else
+KERN_MODPOST = $(LINUX_DIR)/scripts/mod/modpost
+endif
+KERN_MODULES_LINK_DIR = $(KERN_MODPOST_DIR)
+KERN_LINK_SUFFIX = .o
+else
+KERN_MODULES_LINK_DIR = $(KERN_MODULES_DIR)
+KERN_LINK_SUFFIX = $(KERN_EXE_SUFFIX)
+endif
+
+ifeq ($(LINUX_CONFIG_MODVERSIONS),y)
+MODPOST_OPTS += -m
+MODPOST_OPTS += -i $(LINUX_DIR)/Module.symvers
+ifneq ($(LINUX_BUILDHOST),) # this is not correct point, it should look for 2.6.17 kernel
+MODPOST_OPTS += -I $(KERN_LIB_DIR)/Module.symvers
+endif
+MODPOST_OPTS += -o $(KERN_LIB_DIR)/Module.symvers
+endif
+
+ifeq ($(LINUX_CONFIG_DEBUG_SECTION_MISMATCH),y)
+MODPOST_OPTS += -S
+endif
+
+ifeq ($(LINUX_CONFIG_MARKERS),y)
+MODPOST_OPTS += -K $(LINUX_DIR)/Module.markers
+MODPOST_OPTS += -M $(KERN_LIB_DIR)/Module.markers
+endif
+
+ifeq ($(LINUX_KBUILD_MODPOST_WARN),y)
+MODPOST_OPTS += -w
+endif
+
+ifneq ($(LINUX_BUILDHOST),)
+ifneq ($(LINUX_BUILDHOST),$(LINUX_ARCH))
+MODPOST_OPTS += -c
+endif
+endif
+
+define COMPILE_c_o_kern_template
+
+$(2): $(1)
+ @$(QUIET_CMD_ECHO) " CC [K] $$@"
+ $(Q) if $$(c_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+ -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+ -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+
+define COMPILE_cc_o_kern_template
+
+$(2): $(1)
+ @$(QUIET_CMD_ECHO) " CXX [K] $$@"
+ $(Q) if $$(cc_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+ -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+ -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+
+define COMPILE_S_o_kern_template
+
+$(2): $(1)
+ @$(QUIET_CMD_ECHO) " AS [K] $$@"
+ $(Q) if $$(S_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+ -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+ -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+
+define MODULE_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+# this is hack to build "__this_module" structure for 2.6.x kernels
+# modpost is used for that purpose now
+
+#$(1).mod.c:
+# echo "\
+# #include <linux/version.h>@\
+# #include <linux/module.h>@\
+# #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,5))@\
+# #include <linux/vermagic.h>@\
+# #include <linux/compiler.h>@\
+# @\
+# MODULE_INFO(vermagic, VERMAGIC_STRING);@\
+# @\
+# #undef unix@\
+# struct module __this_module@\
+# __attribute__((section(\".gnu.linkonce.this_module\"))) = {@\
+# .name = __stringify(KBUILD_MODNAME),@\
+# .init = init_module,@\
+# #ifdef CONFIG_MODULE_UNLOAD@\
+# .exit = cleanup_module,@\
+# #endif@\
+# };@\
+# #endif@\
+# " | tr @ \\n >$$@
+
+
+#$(eval $(call COMPILE_c_o_kern_template,$(1).mod.c,$(1).mod.o,-DKBUILD_MODNAME=$(1)))
+
+$(2)/$(1)$(KERN_LINK_SUFFIX): $$($(1)_OBJS)
+ @$(QUIET_CMD_ECHO) " LD [K] $$@"
+ $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) -r $$($(1)_OBJS) -L$$(kern_GCCLIB_DIR) $$($(1)_LIBS:%=-l%) $$(KERN_LOADLIBES) -Map $(KERN_OBJS_DIR)/$(1).mod.map -o $$@
+ @echo "$(2)/$(1)$(KERN_LINK_SUFFIX): \\" >$(KERN_OBJS_DIR)/$(1).mod.d
+ @sed -n -e 's/^LOAD \(.*\)$$$$/ \1 \\/p' $(KERN_OBJS_DIR)/$(1).mod.map >>$(KERN_OBJS_DIR)/$(1).mod.d
+ @echo >>$(KERN_OBJS_DIR)/$(1).mod.d
+ @if [ "$(KERN_EXE_SUFFIX)" = ".ko" ] ; then \
+ echo $(1) >>$(KERN_MODPOST_DIR)/module-changes ; \
+ echo $(1) >$(KERN_MODPOST_DIR)/$(1).mod.stamp ; \
+ fi
+
+endef
+
+
+
+define LIBRARY_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+$(KERN_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+ @$(QUIET_CMD_ECHO) " AR [K] $$@"
+ $(Q) $(KERN_AR) rcs $$@ $$^
+endef
+
+
+ifdef LINUX_DIR
+
+kernel-lib-pass-local: $(kernel_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+kernel-mod-pass-local: $(kernel_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+$(foreach module,$(kernel_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(kernel_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+
+ifeq ($(CONFIG_RTLINUX),y)
+
+kernel-mod-pass-local: $(rtlinux_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+kernel-lib-pass-local: $(rtlinux_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+$(foreach module,$(rtlinux_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(rtlinux_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+ifeq ($(KERN_MODPOST_PASS),y)
+
+MODULES_LIST := $(wildcard *.mod.stamp)
+MODULES_LIST := $(MODULES_LIST:%.mod.stamp=%)
+
+define MODPOST_kern_template
+$(2) : $(1)$(KERN_LINK_SUFFIX) $(1).mod.c
+ @$(QUIET_CMD_ECHO) " LD [M] $$@"
+ $(Q) $$(c_o_kern_COMPILE) -D"KBUILD_BASENAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+ -D"KBUILD_MODNAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+ -o $(1).mod.o -c $(1).mod.c
+ $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) $(1)$(KERN_LINK_SUFFIX) $(1).mod.o -r -o $$@
+endef
+
+kernel-modpost-versions: $(wildcard $(LINUX_DIR)/Module.symvers)
+ @$(QUIET_CMD_ECHO) " MODPOST $(KERN_MODPOST_DIR)"
+ @echo >$(KERN_MODPOST_DIR)/modpost-running
+ @rm -f $(KERN_MODPOST_DIR)/module-changes
+ $(Q) $(KERN_MODPOST) $(MODPOST_OPTS) $(MODULES_LIST:%=%$(KERN_LINK_SUFFIX))
+
+$(MODULES_LIST:%=%.mod.c) : kernel-modpost-versions
+
+kernel-modpost-pass-local: $(MODULES_LIST:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX))
+ @rm -f $(KERN_MODPOST_DIR)/modpost-running
+
+$(foreach module,$(MODULES_LIST),$(eval $(call MODPOST_kern_template,$(module),$(module:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX)))))
+
+endif
+
+-include $(KERN_OBJS_DIR)/*.d
+
+endif
+
+#=====================================================================
+
+# Kernel requires its own set of configuration header-files
+ifneq ($(kernel_LIBRARIES)$(rtlinux_LIBRARIES)$(kernel_MODULES)$(rtlinux_MODULES)$(kernel_HEADERS)$(rtlinux_HEADERS)$(kernel_HEADERS)$(rtlinux_HEADERS)$(nobase_kernel_HEADERS)$(nobase_rtlinux_HEADERS)$(renamed_kernel_HEADERS)$(renamed_rtlinux_HEADERS),)
+KERN_CONFIG_HEADERS_REQUIRED = y
+endif
+
+$(eval $(call omk_pass_template, kernel-lib-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_LIBRARIES)$(rtlinux_LIBRARIES)))
+$(eval $(call omk_pass_template, kernel-mod-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_MODULES)$(rtlinux_MODULES)))
+
+kernel-modpost-pass:
+ +@if [ -e "$(KERN_MODPOST_DIR)/module-changes" -o -e "$(KERN_MODPOST_DIR)/modpost-running" ] ; \
+ then \
+ $(MAKE) --no-print-directory -C $(KERN_MODPOST_DIR) \
+ -f $(SOURCES_DIR)/Makefile KERN_RULE_TEMPLATES=y KERN_MODPOST_PASS=y $(@:%=%-local) ; \
+ fi
+
+$(eval $(call omk_pass_template, library-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(lib_LIBRARIES)$(shared_LIBRARIES)))
+$(eval $(call omk_pass_template, binary-pass, $(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(bin_PROGRAMS)$(utils_PROGRAMS)$(test_PROGRAMS)))
+
+$(eval $(call omk_pass_template,clean,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,install,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,include-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,always))
+
+check-dir::
+ @$(call mkdir_def,$(USER_BUILD_DIR))
+ @$(call mkdir_def,$(KERN_BUILD_DIR))
+ @$(call mkdir_def,$(USER_INCLUDE_DIR))
+ @$(call mkdir_def,$(KERN_INCLUDE_DIR))
+ @$(call mkdir_def,$(USER_LIB_DIR))
+ @$(call mkdir_def,$(KERN_LIB_DIR))
+ @$(call mkdir_def,$(USER_BIN_DIR))
+ @$(call mkdir_def,$(USER_UTILS_DIR))
+ @$(call mkdir_def,$(USER_TESTS_DIR))
+ @$(call mkdir_def,$(KERN_MODULES_DIR))
+ @$(call mkdir_def,$(KERN_MODPOST_DIR))
+
+install-local: # TODO
+
+$(eval $(call include-pass-template,$(USER_INCLUDE_DIR),include))
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),kernel))
+ifeq ($(CONFIG_RTLINUX),y)
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),rtlinux))
+endif
+
+
+ifdef USER_RULE_TEMPLATES
+
+# User-space static libraries and applications object files
+
+USER_SOURCES := $(sort $(USER_SOURCES))
+
+USER_GEN_SOURCES := $(sort $(USER_GEN_SOURCES))
+
+#$(warning USER_SOURCES = $(USER_SOURCES))
+
+$(foreach src,$(filter %.c,$(USER_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(USER_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(USER_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+
+$(foreach src,$(filter %.c,$(USER_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.o),)))
+
+# User-space shared libraries object files
+
+SOLIB_SOURCES := $(sort $(SOLIB_SOURCES))
+
+SOLIB_GEN_SOURCES := $(sort $(SOLIB_GEN_SOURCES))
+
+#$(warning SOLIB_SOURCES = $(SOLIB_SOURCES))
+#$(warning SOLIB_GEN_SOURCES = $(SOLIB_GEN_SOURCES))
+
+$(foreach src,$(filter %.c,$(SOLIB_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.cc,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.cxx,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.S,$(SOLIB_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.c,$(SOLIB_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+# Create _build directories for sources in subdirectories i.e. *_SOURCES=dir/file.c
+_dirs_to_create=$(filter-out ./,$(sort $(dir $(USER_SOURCES) $(SOLIB_SOURCES))))
+ifneq ($(_dirs_to_create),)
+$(shell mkdir -p $(addprefix $(LOCAL_BUILD_DIR)/,$(_dirs_to_create)))
+endif
+
+# IDL compilation
+
+USER_IDLS := $(sort $(USER_IDLS))
+
+$(foreach src,$(filter %.idl,$(USER_IDLS)),$(eval $(call COMPILE_idl_template,$(SOURCES_DIR)/$(src),$(src:%.idl=%))))
+
+endif
+
+ifdef KERN_RULE_TEMPLATES
+
+KERN_SOURCES := $(sort $(KERN_SOURCES))
+
+#$(warning KERN_SOURCES = $(KERN_SOURCES))
+
+$(foreach src,$(filter %.c,$(KERN_SOURCES)),$(eval $(call COMPILE_c_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+endif
+
+clean-local: clean-custom
+ @echo Cleaning in $(KERN_OBJS_DIR) and $(USER_OBJS_DIR)
+ @rm -f $(KERN_OBJS_DIR)/*.o $(USER_OBJS_DIR)/*.[och] $(USER_OBJS_DIR)/*.lo\
+ $(KERN_OBJS_DIR)/*.d $(USER_OBJS_DIR)/*.d \
+ $(KERN_OBJS_DIR)/*.map $(USER_OBJS_DIR)/*.map \
+ $(KERN_OBJS_DIR)/*.mod.c \
+ $(kernel_MODULES:%=$(KERN_MODPOST_DIR)/%.*) \
+ $(LOCAL_CONFIG_H:%=$(KERN_OBJS_DIR)/%) \
+ $(LOCAL_CONFIG_H:%=$(USER_OBJS_DIR)/%)
+ @if [ -e $(KERN_LIB_DIR)/kernel.mk ] ; then \
+ touch -t 200001010101 $(KERN_LIB_DIR)/kernel.mk ; \
+ fi
+
+include-pass-submakes: extra-rules-subdirs
+
+# We must go to EXTRA_RULES_SUBDIRS before going to any other
+# directory, since the executables compiled in EXTRA_RULES_SUBDIRS
+# might be needed there.
+include-pass-this-dir $(foreach subdir,$(SUBDIRS),include-pass-$(subdir)-subdir): extra-rules-subdirs
+
+default: include-pass library-pass binary-pass
+ifndef OMIT_KERNEL_PASSES
+# Also make kernel passes if not disabled
+default: kernel-lib-pass kernel-pass
+endif
+ #OMK:config_h.omk@Makefile.rules.linux
+# Syntax: $(call BUILD_CONFIG_H_template,<stamp_dir>,<header_file_path>,<list_of_options_to_export>,<header_barrier>)
+define BUILD_CONFIG_H_template
+
+$(addprefix $(1)/,$(notdir $(addsuffix .stamp,$(2)))) : $(CONFIG_FILES)
+ @$(QUIET_CMD_ECHO) " CONFGEN $(notdir $(2))"
+ @if [ ! -d `dirname $(2).tmp` ] ; then \
+ mkdir -p `dirname $(2).tmp` ; fi
+ @echo "/* Automatically generated from */" > "$(2).tmp"
+ @echo "/* config files: $$(^:$(OUTPUT_DIR)/%=%) */" >> "$(2).tmp"
+ $(if $(DOXYGEN),@echo "/** @file */" >> "$(2).tmp")
+ @echo "#ifndef $(4)" >> "$(2).tmp"
+ @echo "#define $(4)" >> "$(2).tmp"
+ @( $(foreach x, $(shell echo '$($(3))' | tr 'x\t ' 'x\n\n' | sed -e 's/^\([^ =]*\)\(=[^ ]\+\|\)$$/\1/' ), \
+ echo '$(x).$($(x))' ; ) echo ; ) | \
+ sed -e '/^[^.]*\.n$$$$/d' -e '/^[^.]*\.$$$$/d' -e 's/^\([^.]*\)\.[ym]$$$$/\1.1/' | \
+ sed -n -e 's/^\([^.]*\)\.\(.*\)$$$$/#define \1 \2/p' \
+ >> "$(2).tmp"
+ @echo "#endif /*$(4)*/" >> "$(2).tmp"
+ @touch "$$@"
+ @if cmp --quiet "$(2).tmp" "$(2)" ; then rm "$(2).tmp"; \
+ else mv "$(2).tmp" "$(2)" ; \
+ echo "Updated configuration $(2)" ; fi
+
+endef
+
+ifdef LOCAL_CONFIG_H
+
+# This must be declared after the default cflags are assigned!
+# Override is used to override command line assignemnt.
+override CFLAGS += -I $(USER_OBJS_DIR)
+override kernel_INCLUDES += -I $(KERN_OBJS_DIR)
+$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(USER_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+
+endif
+
+# Special rules for configuration exported headers
+
+#FIXME: The directory for headers should not be specified here.
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(addprefix $(USER_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+config_h_stamp_files = $(addprefix $(USER_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(config_h_stamp_files)
+
+ifneq ($(KERN_CONFIG_HEADERS_REQUIRED),)
+
+ifdef LOCAL_CONFIG_H
+$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(KERN_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+endif
+
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(addprefix $(KERN_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+kern_config_h_stamp_files = $(addprefix $(KERN_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(kern_config_h_stamp_files)
+
+endif
+
+clean-local: clean-local-config-h
+
+clean-local-config-h:
+ @$(foreach confh,$(config_h_stamp_files) $(kern_config_h_stamp_files),\
+ if [ -e $(confh) ] ; then rm $(confh) ; fi ; \
+ )
+ #OMK:qt.omk@Makefile.rules.linux
+ifneq ($(QT_SUBDIRS)$(QT_PROJECTS),)
+
+# Usage: $(call qt_project_template,<.pro_file relative to SOURCES_DIR>)
+define qt_project_template
+
+.PHONY: qt-subpass-$(1) clean-qt-$(dir $(1))
+
+# FIXME: Handle multiple .pro files correctly
+$(LOCAL_BUILD_DIR)/$(dir $(1))Makefile: $(SOURCES_DIR)/$(1)
+ $(Q)mkdir -p $$(dir $$(@)) && cd $$(dir $$(@)) && \
+ $(if $(QMAKE),$(QMAKE),$(QTDIR:%=%/bin/)qmake) \
+ TOP_DIR=$(OUTPUT_DIR) \
+ RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir $(1)) \
+ $(QTDIR:%=QTDIR=%) CC=$(CC) CXX=$(CXX) \
+ LIBS+="-L$(USER_LIB_DIR)" DESTDIR=$(USER_BIN_DIR) \
+ INCLUDEPATH+="$(USER_INCLUDE_DIR)" \
+ QMAKE_LFLAGS="-Wl,-rpath-link,$(USER_LIB_DIR) $$(QMAKE_LFLAGS)" \
+ $(SOURCES_DIR)/$(1)
+
+# This horrible substitution is here to properly escape
+# -Wl,-rpath,$ORIGIN flags. It includes escaping for make, shell,
+# qmake and again make and shell run on qmake generated makefile.
+QMAKE_LFLAGS = $$(subst $$$$,\\\\\\$$$$\$$$$,$$(LDFLAGS))
+
+# Hook to binary pass
+binary-pass-submakes: qt-subpass-$(1)
+qt-subpass-$(1): $(LOCAL_BUILD_DIR)/$(dir $(1))Makefile
+ $(Q)$(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir $(1)) \
+ RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir $(1)) -C $(LOCAL_BUILD_DIR)/$(dir $(1)) || exit 1 ;
+
+# Hook to clean pass
+clean-local: clean-qt-$(dir $(1))
+clean-qt-$(dir $(1)): $(LOCAL_BUILD_DIR)/$(dir $(1))Makefile
+ @$(QUIET_CMD_ECHO) " QT CLEAN $(dir $(1))"
+ $(Q)$(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir $(1)) \
+ RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir $(1)) \
+ -C $(LOCAL_BUILD_DIR)/$(dir $(1)) clean
+ $(Q)rm $(LOCAL_BUILD_DIR)/$(dir $(1))Makefile
+endef
+
+$(foreach pro,$(QT_PROJECTS), $(eval $(call qt_project_template,$(pro))))
+$(foreach pro,$(foreach dir,$(QT_SUBDIRS), $(wildcard $(dir)/*.pro)), $(eval $(call qt_project_template,$(pro))))
+
+endif
+ #OMK:sources-list.omk@Makefile.rules.linux
+# Rules that creates the list of files which are used during
+# compilation. The list reflects conditional compilation depending on
+# config.omk and other variables.
+
+SOURCES_LIST_FN=sources.txt
+ifndef SOURCES_LIST
+SOURCES_LIST_DIR:=$(RELATIVE_DIR)
+SOURCES_LIST:=$(OUTPUT_DIR)/$(SOURCES_LIST_DIR)/$(SOURCES_LIST_FN)
+SOURCES_LIST_D := $(LOCAL_BUILD_DIR)/$(SOURCES_LIST_FN).d
+export SOURCES_LIST SOURCES_LIST_DIR SOURCES_LIST_D
+endif
+
+ifneq ($(filter sources-list TAGS tags cscope,$(MAKECMDGOALS)),)
+NEED_SOURCES_LIST=y
+endif
+
+ifeq ($(NEED_SOURCES_LIST),y) # avoid execution of find command bellow if it is not useful
+.PHONY: sources-list
+sources-list: $(SOURCES_LIST)
+
+$(SOURCES_LIST): $(CONFIG_FILES) $(shell find -name $(MAKEFILE_OMK))
+ @$(call mkdir_def,$(dir $(SOURCES_LIST_D)))
+ @echo -n "" > "$(SOURCES_LIST).tmp"
+ @echo -n "" > "$(SOURCES_LIST_D).tmp"
+ @$(MAKE) --no-print-directory sources-list-pass
+ @echo "# Automatically generated list of files in '$(RELATIVE_DIR)' that are used during OMK compilation" > "$(SOURCES_LIST).tmp2"
+ @cat "$(SOURCES_LIST).tmp"|sort|uniq >> "$(SOURCES_LIST).tmp2"
+ @rm "$(SOURCES_LIST).tmp"
+ @mv "$(SOURCES_LIST).tmp2" "$(SOURCES_LIST)"
+ @echo "$(SOURCES_LIST): \\" > "$(SOURCES_LIST_D).tmp2"
+ @cat "$(SOURCES_LIST_D).tmp"|grep -v "$(SOURCES_LIST_D).tmp"|sort|uniq|\
+ sed -e 's/$$/\\/' >> "$(SOURCES_LIST_D).tmp2"
+ @rm "$(SOURCES_LIST_D).tmp"
+ @mv "$(SOURCES_LIST_D).tmp2" "$(SOURCES_LIST_D)"
+endif
+
+$(eval $(call omk_pass_template,sources-list-pass,$$(LOCAL_BUILD_DIR),,always))
+
+sources-list-pass-local:
+ @$(foreach m,$(MAKEFILE_LIST),echo ' $(m)' >> "$(SOURCES_LIST_D).tmp";)
+ @$(foreach h,$(include_HEADERS) $(nobase_include_HEADERS) $(kernel_HEADERS),\
+ echo "$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))$(h)" >> "$(SOURCES_LIST).tmp";)
+ @$(foreach ch,$(config_include_HEADERS), \
+ echo "$(USER_INCLUDE_DIR:$(OUTPUT_DIR)/$(addsuffix /,$(SOURCES_LIST_DIR))%=%)/$(ch)" >> "$(SOURCES_LIST).tmp";)
+ @$(foreach h,$(renamed_include_HEADERS),echo '$(h)'|sed -e 's|\(.*\)->.*|$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))\1|' >> "$(SOURCES_LIST).tmp";)
+ @$(foreach bin,$(lib_LIBRARIES) $(shared_LIBRARIES) $(bin_PROGRAMS) $(test_PROGRAMS) $(utils_PROGRAMS) \
+ $(kernel_LIBRARIES) $(rtlinux_LIBRARIES) $(kernel_MODULES),\
+ $(foreach src,$(filter-out %.o,$($(bin)_SOURCES)),echo "$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))$(src)" >> "$(SOURCES_LIST).tmp";))
+
+############ TAGS ###########
+
+ifeq ($(MAKECMDGOALS),TAGS)
+ETAGS=etags
+TAGS_CMD = $(ETAGS)
+TAGS: $(SOURCES_LIST)
+ @$(MAKE) --no-print-directory do-tags
+endif
+ifeq ($(MAKECMDGOALS),tags)
+CTAGS=ctags -N
+TAGS_CMD = $(CTAGS)
+tags: $(SOURCES_LIST)
+ @$(MAKE) --no-print-directory do-tags
+endif
+export TAGS_CMD
+
+ifeq ($(MAKECMDGOALS),do-tags)
+.PHONY: do-tags
+do-tags: $(shell sed -e '/^\#/d' $(SOURCES_LIST))
+ @$(QUIET_CMD_ECHO) " TAGS $(SOURCES_LIST_FN)"
+ $(Q)$(TAGS_CMD) $^
+endif
+
+############ CSCOPE ###########
+
+cscope: $(SOURCES_LIST)
+ @$(QUIET_CMD_ECHO) " CSCOPE < $(SOURCES_LIST_FN)"
+ $(Q)sed -e '/^#/d' $(SOURCES_LIST) > cscope.files
+ $(Q)cscope -b -icscope.files
+#FIXME: see doc to -i in cscope(1)
--- /dev/null
+# -*- makefile -*-
+# Config file for compilation by OMK for AQuoSA/Linux OS target
+
+# You can override these variables in config.omk
+AQUOSA_ROOT ?= $(wildcard /usr/local/aquosa)
+QTDIR ?= $(wildcard /usr/share/qt4)
+
+test: wvtest
+.PHONY: test
+
+export PLATFORM=AQuoSA
+
+# Create symbolic links to headers instead of copying them. Useful
+# during development.
+LN_HEADERS=y
+
+# We do not want to overwrite original FRESCOR Makefiles
+USE_LEAF_MAKEFILES=n
+
+OMIT_KERNEL_PASSES=y
+
+########################################
+# Setting of compiler
+########################################
+
+# Instead, we call normal gcc with parameters which mgcc adds
+
+CFLAGS=$(ARCH_GCC_OPTS) -fpic -Wall -Wuninitialized -g -O1 -D_REENTRANT -D$(PLATFORM) -D_XOPEN_SOURCE=600 -D_BSD_SOURCE
+LDFLAGS=$(ARCH_LD_OPTS) $(LIBS_PATH) $(LIBS)
+LDFLAGS += '-Wl,-rpath,$$ORIGIN/../lib' -z origin --enable-new-dtags
+
+IDL_COMPILER = $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin/forb-idl
+
+# Other config
+FRSH_DISTRIBUTED_MODULE_SUPPORTED=true
+CONFIG_FORB_PROTO_UNIX=n
+CONFIG_FORB_PROTO_INET_DEFAULT=y
+
+# Disable tests which do not compile with FRSH_FORB
+
+CONFIG_FRSH_TEST_context_switch=n # Needs timespec_operations.h and frsh_os_compatibility.h
+CONFIG_FRSH_TEST_demo_september2007=n # Needs frsh_thread_get_vres_id()
+CONFIG_FRSH_TEST_demo_september2007_with_signals=n # Some problem with signal constants and non-int vres_id
+CONFIG_FRSH_TEST_dl_test=n # Needs different Makefile.omk
+CONFIG_FRSH_TEST_example_d-ac1_frescor=n # Needs int vres_id
+CONFIG_FRSH_TEST_frsh_shared_obj_test=n # Needs eat.h and timespec_operations.h
+CONFIG_FRSH_TEST_functions=n # Needs timespec_operations.h and frsh_os_compatibility.h
+CONFIG_FRSH_TEST_jitter_test=n # Needs timespec_operations.h and frsh_os_compatibility.h
+CONFIG_FRSH_TEST_sharedobj_prototype=n # Needs frsh_sharedobj_XXX
+CONFIG_FRSH_TEST_test_bind=n # Needs eat.h and timespec_operations.h
+CONFIG_FRSH_TEST_test_contract_labels=n # Needs eat.h and timespec_operations.h
+CONFIG_FRSH_TEST_test_eat=n # Needs eat.h
+CONFIG_FRSH_TEST_test_frsh_performance=n # Needs more frsh api - todo
+CONFIG_FRSH_TEST_test_frsh_renegotiate_async=n # Needs eat.h and timespec_operations.h
+CONFIG_FRSH_TEST_test_frsh_synch_obj=n # Needs frsh_thread_id_t to be simple type - Aquosa declares it as structure
+CONFIG_FRSH_TEST_test_memory=n # Needs different Makefile.omk and then we will see :)
+CONFIG_FRSH_TEST_demo_sept07_negotiate_and_send=n # Needs RTEP
+CONFIG_FRSH_TEST_demo_sept07_negotiations_limit=n # Needs RTEP
+CONFIG_FRSH_TEST_demo_sept07_renegotiate_and_send=n # Needs RTEP
+CONFIG_FRSH_TEST_test_endpoints=n # Needs RTEP
+CONFIG_FRSH_TEST_test_frsh_distributed_contract_negotiate=n # Nedds vres_id to be int
+CONFIG_FRSH_TEST_test_frsh_distributed_contract_renegotiate=n # Needs RTEP
+CONFIG_FRSH_TEST_test_frsh_distributed_init=n # Needs THE_FRSH_CPU_ID
+CONFIG_FRSH_TEST_test_frsh_marshal=n # Accesses frsh_contract_t fields directly
+CONFIG_FRSH_TEST_test_frsh_send_receive_basic=n # Needs RTEP
+CONFIG_FRSH_TEST_test_get_network_info=n # Needs RTEP
+CONFIG_FRSH_TEST_test_self_bind=n # Needs eat.h and timespec_operations.h
+CONFIG_FRSH_TEST_test_sizes=n # Needs frsh_internal.h - TODO
+CONFIG_FRSH_TEST_test_spare_capacity=n # Needs more frsh api - TODO
+CONFIG_FRSH_TEST_test_timespec_operations=n # Needs timespec_operations.h
+CONFIG_FRSH_TEST_test_vres_id_bits=n # Depends on bit-fields in integer vres_id
+CONFIG_FSA_TESTS=n # Depends on bit-fields in integer vres_id
--- /dev/null
+#!/bin/sh
+
+# Usage: ./create-links [path/to/frescor/root]
+#
+# path/to/frescor/root defaults to ../..
+
+LINKS="
+fna
+forb
+fosa
+frsh
+frsh_forb
+fwp/fwp
+ulut
+utils
+"
+
+FRESCOR_SRC=${1:-../..}
+
+for link in $LINKS; do
+ ln -s $FRESCOR_SRC/$link .
+done
+
--- /dev/null
+../../src/fna
\ No newline at end of file
--- /dev/null
+../../src/forb
\ No newline at end of file
--- /dev/null
+../../src/fosa
\ No newline at end of file
--- /dev/null
+../../src/frsh
\ No newline at end of file
--- /dev/null
+#!/bin/sh -x
+
+[ -d _compiled/bin ] && PATH=_compiled/bin:$PATH
+
+fcb&
+FCB_PID=$!
+sleep 1
+frm_gui &
+GUI_PID=$!
+frm_dummy &
+DUMMY_PID=$!
+sleep 1
+dummy_spare_capacity &
+S1=$!
+dummy_renegotiation &
+R1=$!
+sleep 1
+dummy_renegotiation &
+R1=$!
+frm_fwp &
+FWP_PID=$!
+wait $GUI_PID
+kill $FWP_PID $DUMMY_PID $FCB_PID $R1 $R2 $S1
--- /dev/null
+../../src/frsh-include
\ No newline at end of file
--- /dev/null
+../../src/fwp/fwp
\ No newline at end of file
--- /dev/null
+#!/bin/bash
+
+if [ $# -lt 1 ] ; then
+ echo "kernelcfg2mk: requires linux kernel directory as the first argument"
+ exit 2
+fi
+
+LINUX_DIR="$1"
+
+if [ $# -gt 1 ] ; then
+ KERN_MODULES_DIR="$2"
+fi
+
+if [ ! -e $LINUX_DIR/.config ] ; then
+ echo "kernelcfg2mk: the provided locations doesnot point to configured kernel sources"
+ echo " check directory $LINUX_DIR"
+ exit 2
+fi
+
+if [ ! -e $LINUX_DIR/.config ] ; then
+ echo "kernelcfg2mk: the provided locations doesnot point to configured kernel sources"
+ echo " check directory $LINUX_DIR"
+ exit 2
+fi
+
+if [ -z "$KERN_BUILD_DIR" ] ; then
+ KERN_BUILD_DIR=`pwd`
+fi
+
+if [ -z "$KERN_MODULES_DIR" ] ; then
+ KERN_MODULES_DIR=`pwd`
+fi
+
+
+if [ -z "$MAKE" ] ; then
+ MAKE="make"
+fi
+
+
+KERN_TEST_DIR="$KERN_BUILD_DIR/kern-test-mk"
+
+mkdir -p $KERN_TEST_DIR
+
+#echo MAKERULES_DIR $MAKERULES_DIR
+#echo LINUX_DIR $LINUX_DIR
+#echo KERN_BUILD_DIR $KERN_BUILD_DIR
+#echo KERN_MODULES_DIR $KERN_MODULES_DIR
+
+RETVAL="0"
+
+LINUX_VERSION=$(grep UTS_RELEASE ${LINUX_DIR}/include/linux/version.h | \
+ sed 's/[^"]*"\(.*\)\{1\}"/\1/')
+if [ -z "$LINUX_VERSION" ] ; then
+ LINUX_VERSION=$(grep UTS_RELEASE ${LINUX_DIR}/include/linux/utsrelease.h | \
+ sed 's/[^"]*"\(.*\)\{1\}"/\1/')
+fi
+if [ -z "$LINUX_VERSION" ] ; then
+ LINUX_VERSION=$(grep UTS_RELEASE ${LINUX_DIR}/include/generated/utsrelease.h | \
+ sed 's/[^"]*"\(.*\)\{1\}"/\1/')
+fi
+
+LINUX_VERSION_MAJOR=$(echo ${LINUX_VERSION} | cut -d. -f1)
+LINUX_VERSION_MINOR=$(echo ${LINUX_VERSION} | cut -d. -f2)
+
+#echo $LINUX_VERSION
+#echo $LINUX_VERSION_MAJOR
+#echo $LINUX_VERSION_MINOR
+
+
+case $LINUX_VERSION_MAJOR.$LINUX_VERSION_MINOR in
+
+
+#=====================================================================
+# test for 2.4.x kernels
+ 2.[01234])
+
+ rm -f ${KERN_BUILD_DIR}/kernel.mk
+ rm -rf ${KERN_TEST_DIR}
+ mkdir ${KERN_TEST_DIR}
+ if [ $? -ne 0 ] ; then
+ echo "Cannot create Linux kernel test build directory \"${KERN_TEST_DIR}\""
+ exit 3
+ fi
+ cd ${KERN_TEST_DIR}
+
+ cat >${KERN_TEST_DIR}/Makefile <<EOF
+
+.PHONY: modules
+modules:
+ @echo LINUX_ARCH="\$(ARCH)" >>flags
+ @echo LINUX_LDFLAGS="" >>flags
+ @echo LINUX_ARFLAGS="\$(ARFLAGS)" >>flags
+ @echo LINUX_CROSS_COMPILE="\$(CROSS_COMPILE)" >>flags
+ @echo LINUX_KERNELRELEASE="\$(KERNELRELEASE)" >>flags
+ @echo LINUX_AFLAGS="\$(AFLAGS)" | sed 's#Iinclude#I"\$(LINUXDIR)/include"#g'>>flags
+ @echo LINUX_CFLAGS="\$(CFLAGS)" | sed 's#Iinclude#I"\$(LINUXDIR)/include"#g'>>flags
+ @echo LINUX_MODFLAGS="\$(MODFLAGS)"
+ @echo LINUX_CC="\$(CC)" >>flags
+ @echo LINUX_LD="\$(LD) \$(LDFLAGS)" >>flags
+ @echo LINUX_AS="\$(AS)" >>flags
+ @echo LINUX_AR="\$(AR)" >>flags
+ @echo LINUX_MODULE_EXT=".o" >>flags
+
+EOF
+
+ #echo ${MAKE} -C ${LINUX_DIR} SUBDIRS=${KERN_TEST_DIR} modules
+ ${MAKE} -C ${LINUX_DIR} SUBDIRS=${KERN_TEST_DIR} modules
+ if [ $? == 0 ] ; then
+ cp -v flags ${KERN_MODULES_DIR}/kernel.mk
+ if [ ! $? == 0 ] ; then
+ RETVAL="2"
+ fi
+ else
+ RETVAL="1"
+ fi
+
+ cd ${KERN_BUILD_DIR}
+ rm -rf ${KERN_TEST_DIR}
+ ;;
+
+#=====================================================================
+# test for 2.6.x kernels
+
+ 2.6)
+
+ rm -f ${KERN_BUILD_DIR}/kernel.mk
+ rm -rf ${KERN_TEST_DIR}
+ mkdir ${KERN_TEST_DIR}
+ if [ $? -ne 0 ] ; then
+ echo "Cannot create Linux kernel test build directory \"${KERN_TEST_DIR}\""
+ exit 3
+ fi
+ cd ${KERN_TEST_DIR}
+
+ cat >${KERN_TEST_DIR}/Makefile <<EOF
+obj-m += fake.o
+
+\$(obj)/fake.c: flags
+ touch \$(obj)/fake.c
+
+ifeq (\$(KBUILD_SRC),)
+OMK_LINUX_SRC = \$(LINUXDIR)
+else
+OMK_LINUX_SRC = \$(KBUILD_SRC)
+endif
+#\$(warning Test \$OMK_LINUX_SRC)
+
+.PHONY: flags
+flags:
+ @echo LINUX_SRC="\$(OMK_LINUX_SRC)" >>\$(obj)/flags
+ @echo LINUX_ARCH="\$(ARCH)" >>\$(obj)/flags
+ @echo LINUX_BUILDHOST="\$(KBUILD_BUILDHOST)" >>\$(obj)/flags
+ @echo LINUX_LDFLAGS="" >>\$(obj)/flags
+ @echo LINUX_ARFLAGS="\$(ARFLAGS)" >>\$(obj)/flags
+ @echo LINUX_CROSS_COMPILE="\$(CROSS_COMPILE)" >>\$(obj)/flags
+ @echo LINUX_KERNELRELEASE="\$(KERNELRELEASE)" >>\$(obj)/flags
+ifdef KBUILD_CFLAGS
+ @echo LINUX_CPPFLAGS="\$(KBUILD_CPPFLAGS)\$(if \$(filter -I,\$(KBUILD_CPPFLAGS)),, \$(LINUXINCLUDE))" | sed 's#-I\(include\|arch\)#-I"\$(LINUXDIR)/\1"#g'>>\$(obj)/flags
+ @echo LINUX_AFLAGS="\$(KBUILD_AFLAGS)" | sed 's#-I\(include\|arch\)#-I"\$(OMK_LINUX_SRC)/\1"#g'>>\$(obj)/flags
+ @echo LINUX_CFLAGS="\$(KBUILD_CFLAGS)" | sed 's#-I\(include\|arch\)#-I"\$(OMK_LINUX_SRC)/\1"#g'>>\$(obj)/flags
+else
+ @echo LINUX_CPPFLAGS="\$(CPPFLAGS)" | sed 's#Iinclude#I"\$(LINUXDIR)/include"#g'>>\$(obj)/flags
+ @echo LINUX_AFLAGS="\$(AFLAGS)" | sed 's#Iinclude#I"\$(OMK_LINUX_SRC)/include"#g'>>\$(obj)/flags
+ @echo LINUX_CFLAGS="\$(CFLAGS)" | sed 's#Iinclude#I"\$(OMK_LINUX_SRC)/include"#g'>>\$(obj)/flags
+endif
+ @echo LINUX_CFLAGS_MODULE="\$(CFLAGS_MODULE)" >>\$(obj)/flags
+ @echo LINUX_CC="\$(CC)" >>\$(obj)/flags
+ @echo LINUX_LD="\$(LD) \$(LDFLAGS) \$(LDFLAGS_MODULE)" | sed 's#\(\<arch/[^ ]*\.o\>\)#"\$(LINUXDIR)/\1"#g' >>\$(obj)/flags
+ @echo LINUX_AS="\$(AS)" >>\$(obj)/flags
+ @echo LINUX_AR="\$(AR)" >>\$(obj)/flags
+ @echo LINUX_MODULE_EXT=".ko" >>\$(obj)/flags
+ @echo LINUX_QUOTE_MODNAME=\$(if \$(findstring KBUILD_STR,\$(basename_flags)),y,) >>\$(obj)/flags
+ @echo LINUX_CONFIG_MODVERSIONS=\$(CONFIG_MODVERSIONS) >>\$(obj)/flags
+ @echo LINUX_CONFIG_MODULE_SRCVERSION_ALL=\$(CONFIG_MODULE_SRCVERSION_ALL) >>\$(obj)/flags
+ @echo LINUX_CONFIG_DEBUG_SECTION_MISMATCH=\$(CONFIG_DEBUG_SECTION_MISMATCH) >>\$(obj)/flags
+ @echo LINUX_CONFIG_MARKERS=\$(CONFIG_MARKERS) >>\$(obj)/flags
+ @echo LINUX_KBUILD_EXTMOD=\$(KBUILD_EXTMOD) >>\$(obj)/flags
+ @echo LINUX_KBUILD_EXTRA_SYMBOLS=\$(KBUILD_EXTRA_SYMBOLS) >>\$(obj)/flags
+ @echo LINUX_KBUILD_MODPOST_WARN=\$(KBUILD_MODPOST_WARN) >>\$(obj)/flags
+ @echo LINUX_CROSS_BUILD=\$(cross_build) >>\$(obj)/flags
+EOF
+
+ # modkern_cflags := $(CFLAGS_KERNEL) / $(CFLAGS_MODULE)
+
+ # _c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o)
+ # _a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o)
+ # _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F))
+
+ # export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
+ # export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
+ # export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
+
+ # -p V=1
+ #echo ${MAKE} -C ${LINUX_DIR} SUBDIRS=${KERN_TEST_DIR} LINUXDIR=${LINUX_DIR} MODVERDIR=${KERN_TEST_DIR} modules
+ ${MAKE} -C ${LINUX_DIR} M=${KERN_TEST_DIR} LINUXDIR=${LINUX_DIR} MODVERDIR=${KERN_TEST_DIR}/modver modules
+ #if [ $? == 0 ] ; then
+ cp -v flags ${KERN_MODULES_DIR}/kernel.mk
+ if [ ! $? == 0 ] ; then
+ RETVAL="2"
+ fi
+ #else
+ # RETVAL="1"
+ #fi
+
+ cd ${KERN_BUILD_DIR}
+ rm -rf ${KERN_TEST_DIR}
+ ;;
+
+#=====================================================================
+
+ *)
+ echo "Unsupported Linux version $LINUX_VERSION_MAJOR.$LINUX_VERSION_MINOR"
+ ;;
+esac
+
+
+exit ${RETVAL}
--- /dev/null
+../../src/ulut/ulut
\ No newline at end of file
--- /dev/null
+
+include_HEADERS = wvtest.h
+
+CFLAGS += -DWVTEST_CONFIGURED
+
+lib_LIBRARIES = wvtest
+wvtest_SOURCES = wvtestmain.c wvtest.c wvtestfrsh.c
--- /dev/null
+/*
+ * WvTest:
+ * Copyright (C) 1997-2009 Net Integration Technologies, Inc.
+ * Licensed under the GNU Library General Public License, version 2.
+ * See the included file named LICENSE for license information.
+ */
+#include "wvtest.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#ifdef _WIN32
+#include <direct.h>
+#else
+#include <unistd.h>
+#include <sys/wait.h>
+#endif
+#include <errno.h>
+#include <signal.h>
+
+#include <stdlib.h>
+
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+# include <valgrind/memcheck.h>
+# include <valgrind/valgrind.h>
+#else
+# define VALGRIND_COUNT_ERRORS 0
+# define VALGRIND_DO_LEAK_CHECK
+# define VALGRIND_COUNT_LEAKS(a,b,c,d) (a=b=c=d=0)
+#endif
+
+#define MAX_TEST_TIME 40 // max seconds for a single test to run
+#define MAX_TOTAL_TIME 120*60 // max seconds for the entire suite to run
+
+#define TEST_START_FORMAT "! %s:%-5d %-40s "
+
+static int fails, runs;
+static time_t start_time;
+static bool run_twice;
+
+static void alarm_handler(int sig);
+
+static int memerrs()
+{
+ return (int)VALGRIND_COUNT_ERRORS;
+}
+
+static int memleaks()
+{
+ int leaked = 0, dubious = 0, reachable = 0, suppressed = 0;
+ VALGRIND_DO_LEAK_CHECK;
+ VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed);
+ printf("memleaks: sure:%d dubious:%d reachable:%d suppress:%d\n",
+ leaked, dubious, reachable, suppressed);
+ fflush(stdout);
+
+ // dubious+reachable are normally non-zero because of globals...
+ // return leaked+dubious+reachable;
+ return leaked;
+}
+
+// Return 1 if no children are running or zombies, 0 if there are any running
+// or zombie children.
+// Will wait for any already-terminated children first.
+// Passes if no rogue children were running, fails otherwise.
+// If your test gets a failure in here, either you're not killing all your
+// children, or you're not calling waitpid(2) on all of them.
+static bool no_running_children()
+{
+#ifndef _WIN32
+ pid_t wait_result;
+
+ // Acknowledge and complain about any zombie children
+ do
+ {
+ int status = 0;
+ wait_result = waitpid(-1, &status, WNOHANG);
+
+ if (wait_result > 0)
+ {
+ char buf[256];
+ snprintf(buf, sizeof(buf) - 1, "%d", wait_result);
+ buf[sizeof(buf)-1] = '\0';
+ WVFAILEQ("Unclaimed dead child process", buf);
+ }
+ } while (wait_result > 0);
+
+ // There should not be any running children, so waitpid should return -1
+ WVPASS(errno == ECHILD);
+ WVPASS(wait_result == -1);
+ return (wait_result == -1 && errno == ECHILD);
+#endif
+ return true;
+}
+
+
+static void alarm_handler(int sig)
+{
+ printf("\n! WvTest Current test took longer than %d seconds! FAILED\n",
+ MAX_TEST_TIME);
+ fflush(stdout);
+ abort();
+}
+
+
+static const char *pathstrip(const char *filename)
+{
+ const char *cptr;
+ cptr = strrchr(filename, '/');
+ if (cptr) filename = cptr + 1;
+ cptr = strrchr(filename, '\\');
+ if (cptr) filename = cptr + 1;
+ return filename;
+}
+
+static bool prefix_match(const char *s, char * const *prefixes)
+{
+ char *const *prefix;
+ for (prefix = prefixes; prefix && *prefix; prefix++)
+ {
+ if (!strncasecmp(s, *prefix, strlen(*prefix)))
+ return true;
+ }
+ return false;
+}
+
+extern struct WvTest *__start_wvtest, *__stop_wvtest;
+
+int wvtest_run_all(char * const *prefixes)
+{
+ int old_valgrind_errs = 0, new_valgrind_errs;
+ int old_valgrind_leaks = 0, new_valgrind_leaks;
+
+#ifdef _WIN32
+ /* I should be doing something to do with SetTimer here,
+ * not sure exactly what just yet */
+#else
+ char *disable = getenv("WVTEST_DISABLE_TIMEOUT");
+ if (disable != NULL && disable[0] != '\0' && disable[0] != '0')
+ signal(SIGALRM, SIG_IGN);
+ else
+ signal(SIGALRM, alarm_handler);
+ alarm(MAX_TEST_TIME);
+#endif
+ start_time = time(NULL);
+
+ // make sure we can always start out in the same directory, so tests have
+ // access to their files. If a test uses chdir(), we want to be able to
+ // reverse it.
+ char wd[1024];
+ if (!getcwd(wd, sizeof(wd)))
+ strcpy(wd, ".");
+
+ const char *slowstr1 = getenv("WVTEST_MIN_SLOWNESS");
+ const char *slowstr2 = getenv("WVTEST_MAX_SLOWNESS");
+ int min_slowness = 0, max_slowness = 65535;
+ if (slowstr1) min_slowness = atoi(slowstr1);
+ if (slowstr2) max_slowness = atoi(slowstr2);
+
+#ifdef _WIN32
+ run_twice = false;
+#else
+ char *parallel_str = getenv("WVTEST_PARALLEL");
+ if (parallel_str)
+ run_twice = atoi(parallel_str) > 0;
+#endif
+
+ // there are lots of fflush() calls in here because stupid win32 doesn't
+ // flush very often by itself.
+ fails = runs = 0;
+ struct WvTest *cur, **p;
+ for (p = &__start_wvtest; p < &__stop_wvtest; p++)
+ {
+ cur = *p;
+ if (cur->slowness <= max_slowness
+ && cur->slowness >= min_slowness
+ && (!prefixes
+ || prefix_match(cur->idstr, prefixes)
+ || prefix_match(cur->descr, prefixes)))
+ {
+#ifndef _WIN32
+ // set SIGPIPE back to default, helps catch tests which don't set
+ // this signal to SIG_IGN (which is almost always what you want)
+ // on startup
+ signal(SIGPIPE, SIG_DFL);
+
+ pid_t child = 0;
+ if (run_twice)
+ {
+ // I see everything twice!
+ printf("Running test in parallel.\n");
+ child = fork();
+ }
+#endif
+
+ printf("\nTesting \"%s\" in %s:\n", cur->descr, cur->idstr);
+ fflush(stdout);
+
+ cur->main();
+ chdir(wd);
+
+ new_valgrind_errs = memerrs();
+ WVPASS(new_valgrind_errs == old_valgrind_errs);
+ old_valgrind_errs = new_valgrind_errs;
+
+ new_valgrind_leaks = memleaks();
+ WVPASS(new_valgrind_leaks == old_valgrind_leaks);
+ old_valgrind_leaks = new_valgrind_leaks;
+
+ fflush(stderr);
+ printf("\n");
+ fflush(stdout);
+
+#ifndef _WIN32
+ if (run_twice)
+ {
+ if (!child)
+ {
+ // I see everything once!
+ printf("Child exiting.\n");
+ _exit(0);
+ }
+ else
+ {
+ printf("Waiting for child to exit.\n");
+ int result;
+ while ((result = waitpid(child, NULL, 0)) == -1 &&
+ errno == EINTR)
+ printf("Waitpid interrupted, retrying.\n");
+ }
+ }
+#endif
+
+ WVPASS(no_running_children());
+ }
+ }
+
+ WVPASS(runs > 0);
+
+ if (prefixes && *prefixes && **prefixes)
+ printf("WvTest: WARNING: only ran tests starting with "
+ "specifed prefix(es).\n");
+ else
+ printf("WvTest: ran all tests.\n");
+ printf("WvTest: %d test%s, %d failure%s.\n",
+ runs, runs==1 ? "" : "s",
+ fails, fails==1 ? "": "s");
+ fflush(stdout);
+
+ return fails != 0;
+}
+
+
+// If we aren't running in parallel, we want to output the name of the test
+// before we run it, so we know what happened if it crashes. If we are
+// running in parallel, outputting this information in multiple printf()s
+// can confuse parsers, so we want to output everything in one printf().
+//
+// This function gets called by both start() and check(). If we're not
+// running in parallel, just print the data. If we're running in parallel,
+// and we're starting a test, save a copy of the file/line/description until
+// the test is done and we can output it all at once.
+//
+// Yes, this is probably the worst API of all time.
+static void print_result_str(bool start, const char *_file, int _line,
+ const char *_condstr, const char *result)
+{
+ static char *file;
+ static char *condstr;
+ static int line;
+ char *cptr;
+
+ if (start)
+ {
+ if (file)
+ free(file);
+ if (condstr)
+ free(condstr);
+ file = strdup(pathstrip(_file));
+ condstr = strdup(_condstr);
+ line = _line;
+
+ for (cptr = condstr; *cptr; cptr++)
+ {
+ if (!isprint((unsigned char)*cptr))
+ *cptr = '!';
+ }
+ }
+
+ if (run_twice)
+ {
+ if (!start)
+ printf(TEST_START_FORMAT "%s\n", file, line, condstr, result);
+ }
+ else
+ {
+ if (start)
+ printf(TEST_START_FORMAT, file, line, condstr);
+ else
+ printf("%s\n", result);
+ }
+ fflush(stdout);
+
+ if (!start)
+ {
+ if (file)
+ free(file);
+ if (condstr)
+ free(condstr);
+ file = condstr = NULL;
+ }
+}
+
+static inline void
+print_result(bool start, const char *file, int line,
+ const char *condstr, bool result)
+{
+ print_result_str(start, file, line, condstr, result ? "ok" : "FAILED");
+}
+
+void wvtest_start(const char *file, int line, const char *condstr)
+{
+ // Either print the file, line, and condstr, or save them for later.
+ print_result(true, file, line, condstr, false);
+}
+
+
+void wvtest_check(bool cond, const char *reason)
+{
+#ifndef _WIN32
+ alarm(MAX_TEST_TIME); // restart per-test timeout
+#endif
+ if (!start_time) start_time = time(NULL);
+
+ if (time(NULL) - start_time > MAX_TOTAL_TIME)
+ {
+ printf("\n! WvTest Total run time exceeded %d seconds! FAILED\n",
+ MAX_TOTAL_TIME);
+ fflush(stdout);
+ abort();
+ }
+
+ runs++;
+
+ print_result_str(false, NULL, 0, NULL, cond ? "ok" : (reason ? reason : "FAILED"));
+
+ if (!cond)
+ {
+ fails++;
+
+ if (getenv("WVTEST_DIE_FAST"))
+ abort();
+ }
+}
+
+
+bool wvtest_start_check_eq(const char *file, int line,
+ const char *a, const char *b, bool expect_pass)
+{
+ if (!a) a = "";
+ if (!b) b = "";
+
+ size_t len = strlen(a) + strlen(b) + 8 + 1;
+ char str[len];
+ sprintf(str, "[%s] %s [%s]", a, expect_pass ? "==" : "!=", b);
+
+ wvtest_start(file, line, str);
+
+ bool cond = !strcmp(a, b);
+ if (!expect_pass)
+ cond = !cond;
+
+ wvtest_check(cond, NULL);
+ return cond;
+}
+
+
+bool wvtest_start_check_lt(const char *file, int line,
+ const char *a, const char *b)
+{
+ if (!a) a = "";
+ if (!b) b = "";
+
+ size_t len = strlen(a) + strlen(b) + 8 + 1;
+ char *str = malloc(len);
+ sprintf(str, "[%s] < [%s]", a, b);
+
+ wvtest_start(file, line, str);
+ free(str);
+
+ bool cond = strcmp(a, b) < 0;
+ wvtest_check(cond, NULL);
+ return cond;
+}
--- /dev/null
+/* -*- Mode: C -*-
+ * WvTest:
+ * Copyright (C) 1997-2009 Net Integration Technologies, Inc.
+ * Licensed under the GNU Library General Public License, version 2.
+ * See the included file named LICENSE for license information.
+ */
+#ifndef __WVTEST_H
+#define __WVTEST_H
+
+#ifndef WVTEST_CONFIGURED
+# error "Missing settings: HAVE_VALGRIND_MEMCHECK_H HAVE_WVCRASH WVTEST_CONFIGURED"
+#endif
+
+#include <time.h>
+#include <string.h>
+#include <stdbool.h>
+
+typedef void wvtest_mainfunc();
+
+struct WvTest {
+ const char *descr, *idstr;
+ wvtest_mainfunc *main;
+ int slowness;
+ struct WvTest *next;
+};
+
+int wvtest_run_all(char * const *prefixes);
+void wvtest_start(const char *file, int line, const char *condstr);
+void wvtest_check(bool cond, const char *reason);
+static inline bool wvtest_start_check(const char *file, int line,
+ const char *condstr, bool cond)
+{ wvtest_start(file, line, condstr); wvtest_check(cond, NULL); return cond; }
+bool wvtest_start_check_eq(const char *file, int line,
+ const char *a, const char *b, bool expect_pass);
+bool wvtest_start_check_lt(const char *file, int line,
+ const char *a, const char *b);
+int wvtest_start_check_frsh(const char *file, int line,
+ const char *condstr, int frsh_retval);
+
+
+#define WVPASS(cond) \
+ wvtest_start_check(__FILE__, __LINE__, #cond, (cond))
+#define WVPASSEQ(a, b) \
+ wvtest_start_check_eq(__FILE__, __LINE__, (a), (b), true)
+#define WVPASSLT(a, b) \
+ wvtest_start_check_lt(__FILE__, __LINE__, (a), (b))
+#define WVFAIL(cond) \
+ wvtest_start_check(__FILE__, __LINE__, "NOT(" #cond ")", !(cond))
+#define WVFAILEQ(a, b) \
+ wvtest_start_check_eq(__FILE__, __LINE__, (a), (b), false)
+#define WVPASSNE(a, b) WVFAILEQ(a, b)
+#define WVFAILNE(a, b) WVPASSEQ(a, b)
+#define WVFRSH(frshretval) \
+ wvtest_start_check_frsh(__FILE__, __LINE__, #frshretval, (frshretval))
+
+
+#define WVTEST_MAIN3(_descr, ff, ll, _slowness) \
+ static void _wvtest_main_##ll(); \
+ struct WvTest _wvtest_##ll = \
+ { .descr = _descr, .idstr = ff ":" #ll, .main = _wvtest_main_##ll, .slowness = _slowness }, \
+ *_wvtest_ptr_##ll __attribute__ ((section ("wvtest"))) = &_wvtest_##ll; \
+ static void _wvtest_main_##ll()
+#define WVTEST_MAIN2(descr, ff, ll, slowness) \
+ WVTEST_MAIN3(descr, ff, ll, slowness)
+#define WVTEST_MAIN(descr) WVTEST_MAIN2(descr, __FILE__, __LINE__, 0)
+#define WVTEST_SLOW_MAIN(descr) WVTEST_MAIN2(descr, __FILE__, __LINE__, 1)
+
+
+#endif // __WVTEST_H
--- /dev/null
+#include "wvtest.h"
+#include <frsh_error.h>
+
+int wvtest_start_check_frsh(const char *file, int line,
+ const char *condstr, int frsh_retval)
+{
+ char errstr[80] = "ok";
+ wvtest_start(file, line, condstr);
+ if (frsh_retval != 0)
+ frsh_strerror (frsh_retval, errstr, sizeof(errstr));
+
+ wvtest_check(frsh_retval == 0, errstr);
+
+ return frsh_retval;
+}
--- /dev/null
+/*
+ * WvTest:
+ * Copyright (C) 1997-2009 Net Integration Technologies, Inc.
+ * Licensed under the GNU Library General Public License, version 2.
+ * See the included file named LICENSE for license information.
+ */
+#include "wvtest.h"
+#ifdef HAVE_WVCRASH
+# include "wvcrash.h"
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#ifdef _WIN32
+#include <io.h>
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <fcntl.h>
+#endif
+
+static bool fd_is_valid(int fd)
+{
+#ifdef _WIN32
+ if ((HANDLE)_get_osfhandle(fd) != INVALID_HANDLE_VALUE) return true;
+#endif
+ int nfd = dup(fd);
+ if (nfd >= 0)
+ {
+ close(nfd);
+ return true;
+ }
+ return false;
+
+}
+
+
+static int fd_count(const char *when)
+{
+ int count = 0;
+ int fd;
+ printf("fds open at %s:", when);
+
+ for (fd = 0; fd < 1024; fd++)
+ {
+ if (fd_is_valid(fd))
+ {
+ count++;
+ printf(" %d", fd);
+ fflush(stdout);
+ }
+ }
+ printf("\n");
+
+ return count;
+}
+
+
+int main(int argc, char **argv)
+{
+ char buf[200];
+#if defined(_WIN32) && defined(HAVE_WVCRASH)
+ setup_console_crash();
+#endif
+
+ // test wvtest itself. Not very thorough, but you have to draw the
+ // line somewhere :)
+ WVPASS(true);
+ WVPASS(1);
+ WVFAIL(false);
+ WVFAIL(0);
+ int startfd, endfd;
+ char * const *prefixes = NULL;
+
+ if (argc > 1)
+ prefixes = argv + 1;
+
+ startfd = fd_count("start");
+ int ret = wvtest_run_all(prefixes);
+
+// if (ret == 0) // don't pollute the strace output if we failed anyway
+ if (0)
+ {
+ endfd = fd_count("end");
+
+ WVPASS(startfd == endfd);
+#ifndef _WIN32
+ if (startfd != endfd)
+ {
+ sprintf(buf, "ls -l /proc/%d/fd", getpid());
+ system(buf);
+ }
+#endif
+ }
+
+ // keep 'make' from aborting if this environment variable is set
+ if (getenv("WVTEST_NO_FAIL"))
+ return 0;
+ else
+ return ret;
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+
+include_HEADERS = wvtest.h
+
+CFLAGS += -DWVTEST_CONFIGURED
+
+lib_LIBRARIES = wvtest
+wvtest_SOURCES = wvtestmain.cc wvtest.cc
--- /dev/null
+/*
+ * WvTest:
+ * Copyright (C) 1997-2009 Net Integration Technologies, Inc.
+ * Licensed under the GNU Library General Public License, version 2.
+ * See the included file named LICENSE for license information.
+ */
+#include "wvtest.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#ifdef _WIN32
+#include <direct.h>
+#else
+#include <unistd.h>
+#include <sys/wait.h>
+#endif
+#include <errno.h>
+#include <signal.h>
+#include <frsh_error.h>
+
+#include <cstdlib>
+
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+# include <valgrind/memcheck.h>
+# include <valgrind/valgrind.h>
+#else
+# define VALGRIND_COUNT_ERRORS 0
+# define VALGRIND_DO_LEAK_CHECK
+# define VALGRIND_COUNT_LEAKS(a,b,c,d) (a=b=c=d=0)
+#endif
+
+#define MAX_TEST_TIME 40 // max seconds for a single test to run
+#define MAX_TOTAL_TIME 120*60 // max seconds for the entire suite to run
+
+#define TEST_START_FORMAT "! %s:%-5d %-40s "
+
+static int memerrs()
+{
+ return (int)VALGRIND_COUNT_ERRORS;
+}
+
+static int memleaks()
+{
+ int leaked = 0, dubious = 0, reachable = 0, suppressed = 0;
+ VALGRIND_DO_LEAK_CHECK;
+ VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed);
+ printf("memleaks: sure:%d dubious:%d reachable:%d suppress:%d\n",
+ leaked, dubious, reachable, suppressed);
+ fflush(stdout);
+
+ // dubious+reachable are normally non-zero because of globals...
+ // return leaked+dubious+reachable;
+ return leaked;
+}
+
+// Return 1 if no children are running or zombies, 0 if there are any running
+// or zombie children.
+// Will wait for any already-terminated children first.
+// Passes if no rogue children were running, fails otherwise.
+// If your test gets a failure in here, either you're not killing all your
+// children, or you're not calling waitpid(2) on all of them.
+static bool no_running_children()
+{
+#ifndef _WIN32
+ pid_t wait_result;
+
+ // Acknowledge and complain about any zombie children
+ do
+ {
+ int status = 0;
+ wait_result = waitpid(-1, &status, WNOHANG);
+
+ if (wait_result > 0)
+ {
+ char buf[256];
+ snprintf(buf, sizeof(buf) - 1, "%d", wait_result);
+ buf[sizeof(buf)-1] = '\0';
+ WVFAILEQ("Unclaimed dead child process", buf);
+ }
+ } while (wait_result > 0);
+
+ // There should not be any running children, so waitpid should return -1
+ WVPASSEQ(errno, ECHILD);
+ WVPASSEQ(wait_result, -1);
+ return (wait_result == -1 && errno == ECHILD);
+#endif
+ return true;
+}
+
+
+WvTest *WvTest::first, *WvTest::last;
+int WvTest::fails, WvTest::runs;
+time_t WvTest::start_time;
+bool WvTest::run_twice = false;
+
+void WvTest::alarm_handler(int)
+{
+ printf("\n! WvTest Current test took longer than %d seconds! FAILED\n",
+ MAX_TEST_TIME);
+ fflush(stdout);
+ abort();
+}
+
+
+static const char *pathstrip(const char *filename)
+{
+ const char *cptr;
+ cptr = strrchr(filename, '/');
+ if (cptr) filename = cptr + 1;
+ cptr = strrchr(filename, '\\');
+ if (cptr) filename = cptr + 1;
+ return filename;
+}
+
+
+WvTest::WvTest(const char *_descr, const char *_idstr, MainFunc *_main,
+ int _slowness) :
+ descr(_descr),
+ idstr(pathstrip(_idstr)),
+ main(_main),
+ slowness(_slowness),
+ next(NULL)
+{
+ if (first)
+ last->next = this;
+ else
+ first = this;
+ last = this;
+}
+
+
+static bool prefix_match(const char *s, const char * const *prefixes)
+{
+ for (const char * const *prefix = prefixes; prefix && *prefix; prefix++)
+ {
+ if (!strncasecmp(s, *prefix, strlen(*prefix)))
+ return true;
+ }
+ return false;
+}
+
+
+int WvTest::run_all(const char * const *prefixes)
+{
+ int old_valgrind_errs = 0, new_valgrind_errs;
+ int old_valgrind_leaks = 0, new_valgrind_leaks;
+
+#ifdef _WIN32
+ /* I should be doing something to do with SetTimer here,
+ * not sure exactly what just yet */
+#else
+ char *disable(getenv("WVTEST_DISABLE_TIMEOUT"));
+ if (disable != NULL && disable[0] != '\0' && disable[0] != '0')
+ signal(SIGALRM, SIG_IGN);
+ else
+ signal(SIGALRM, alarm_handler);
+ alarm(MAX_TEST_TIME);
+#endif
+ start_time = time(NULL);
+
+ // make sure we can always start out in the same directory, so tests have
+ // access to their files. If a test uses chdir(), we want to be able to
+ // reverse it.
+ char wd[1024];
+ if (!getcwd(wd, sizeof(wd)))
+ strcpy(wd, ".");
+
+ const char *slowstr1 = getenv("WVTEST_MIN_SLOWNESS");
+ const char *slowstr2 = getenv("WVTEST_MAX_SLOWNESS");
+ int min_slowness = 0, max_slowness = 65535;
+ if (slowstr1) min_slowness = atoi(slowstr1);
+ if (slowstr2) max_slowness = atoi(slowstr2);
+
+#ifdef _WIN32
+ run_twice = false;
+#else
+ char *parallel_str = getenv("WVTEST_PARALLEL");
+ if (parallel_str)
+ run_twice = atoi(parallel_str) > 0;
+#endif
+
+ // there are lots of fflush() calls in here because stupid win32 doesn't
+ // flush very often by itself.
+ fails = runs = 0;
+ for (WvTest *cur = first; cur; cur = cur->next)
+ {
+ if (cur->slowness <= max_slowness
+ && cur->slowness >= min_slowness
+ && (!prefixes
+ || prefix_match(cur->idstr, prefixes)
+ || prefix_match(cur->descr, prefixes)))
+ {
+#ifndef _WIN32
+ // set SIGPIPE back to default, helps catch tests which don't set
+ // this signal to SIG_IGN (which is almost always what you want)
+ // on startup
+ signal(SIGPIPE, SIG_DFL);
+
+ pid_t child = 0;
+ if (run_twice)
+ {
+ // I see everything twice!
+ printf("Running test in parallel.\n");
+ child = fork();
+ }
+#endif
+
+ printf("\nTesting \"%s\" in %s:\n", cur->descr, cur->idstr);
+ fflush(stdout);
+
+ cur->main();
+ chdir(wd);
+
+ new_valgrind_errs = memerrs();
+ WVPASS(new_valgrind_errs == old_valgrind_errs);
+ old_valgrind_errs = new_valgrind_errs;
+
+ new_valgrind_leaks = memleaks();
+ WVPASS(new_valgrind_leaks == old_valgrind_leaks);
+ old_valgrind_leaks = new_valgrind_leaks;
+
+ fflush(stderr);
+ printf("\n");
+ fflush(stdout);
+
+#ifndef _WIN32
+ if (run_twice)
+ {
+ if (!child)
+ {
+ // I see everything once!
+ printf("Child exiting.\n");
+ _exit(0);
+ }
+ else
+ {
+ printf("Waiting for child to exit.\n");
+ int result;
+ while ((result = waitpid(child, NULL, 0)) == -1 &&
+ errno == EINTR)
+ printf("Waitpid interrupted, retrying.\n");
+ }
+ }
+#endif
+
+ WVPASS(no_running_children());
+ }
+ }
+
+ WVPASS(runs > 0);
+
+ if (prefixes && *prefixes && **prefixes)
+ printf("WvTest: WARNING: only ran tests starting with "
+ "specifed prefix(es).\n");
+ else
+ printf("WvTest: ran all tests.\n");
+ printf("WvTest: %d test%s, %d failure%s.\n",
+ runs, runs==1 ? "" : "s",
+ fails, fails==1 ? "": "s");
+ fflush(stdout);
+
+ return fails != 0;
+}
+
+
+// If we aren't running in parallel, we want to output the name of the test
+// before we run it, so we know what happened if it crashes. If we are
+// running in parallel, outputting this information in multiple printf()s
+// can confuse parsers, so we want to output everything in one printf().
+//
+// This function gets called by both start() and check(). If we're not
+// running in parallel, just print the data. If we're running in parallel,
+// and we're starting a test, save a copy of the file/line/description until
+// the test is done and we can output it all at once.
+//
+// Yes, this is probably the worst API of all time.
+void WvTest::print_result(bool start, const char *_file, int _line,
+ const char *_condstr, const char *result)
+{
+ static char *file;
+ static char *condstr;
+ static int line;
+
+ if (start)
+ {
+ if (file)
+ free(file);
+ if (condstr)
+ free(condstr);
+ file = strdup(pathstrip(_file));
+ condstr = strdup(_condstr);
+ line = _line;
+
+ for (char *cptr = condstr; *cptr; cptr++)
+ {
+ if (!isprint((unsigned char)*cptr))
+ *cptr = '!';
+ }
+ }
+
+ if (run_twice)
+ {
+ if (!start)
+ printf(TEST_START_FORMAT "%s\n", file, line, condstr, result);
+ }
+ else
+ {
+ if (start)
+ printf(TEST_START_FORMAT, file, line, condstr);
+ else
+ printf("%s\n", result);
+ }
+ fflush(stdout);
+
+ if (!start)
+ {
+ if (file)
+ free(file);
+ if (condstr)
+ free(condstr);
+ file = condstr = NULL;
+ }
+}
+
+
+void WvTest::start(const char *file, int line, const char *condstr)
+{
+ // Either print the file, line, and condstr, or save them for later.
+ print_result(true, file, line, condstr, false);
+}
+
+
+void WvTest::check(bool cond, const char *reason)
+{
+#ifndef _WIN32
+ alarm(MAX_TEST_TIME); // restart per-test timeout
+#endif
+ if (!start_time) start_time = time(NULL);
+
+ if (time(NULL) - start_time > MAX_TOTAL_TIME)
+ {
+ printf("\n! WvTest Total run time exceeded %d seconds! FAILED\n",
+ MAX_TOTAL_TIME);
+ fflush(stdout);
+ abort();
+ }
+
+ runs++;
+
+ print_result(false, NULL, 0, NULL, cond ? "ok" : reason);
+
+ if (!cond)
+ {
+ fails++;
+
+ if (getenv("WVTEST_DIE_FAST"))
+ abort();
+ }
+}
+
+
+bool WvTest::start_check_eq(const char *file, int line,
+ const char *a, const char *b, bool expect_pass)
+{
+ if (!a) a = "";
+ if (!b) b = "";
+
+ size_t len = strlen(a) + strlen(b) + 8 + 1;
+ char *str = new char[len];
+ sprintf(str, "[%s] %s [%s]", a, expect_pass ? "==" : "!=", b);
+
+ start(file, line, str);
+ delete[] str;
+
+ bool cond = !strcmp(a, b);
+ if (!expect_pass)
+ cond = !cond;
+
+ check(cond);
+ return cond;
+}
+
+
+bool WvTest::start_check_eq(const char *file, int line,
+ const std::string &a, const std::string &b,
+ bool expect_pass)
+{
+ return start_check_eq(file, line, a.c_str(), b.c_str(), expect_pass);
+}
+
+
+bool WvTest::start_check_eq(const char *file, int line,
+ int a, int b, bool expect_pass)
+{
+ size_t len = 128 + 128 + 8 + 1;
+ char *str = new char[len];
+ sprintf(str, "%d %s %d", a, expect_pass ? "==" : "!=", b);
+
+ start(file, line, str);
+ delete[] str;
+
+ bool cond = (a == b);
+ if (!expect_pass)
+ cond = !cond;
+
+ check(cond);
+ return cond;
+}
+
+
+bool WvTest::start_check_lt(const char *file, int line,
+ const char *a, const char *b)
+{
+ if (!a) a = "";
+ if (!b) b = "";
+
+ size_t len = strlen(a) + strlen(b) + 8 + 1;
+ char *str = new char[len];
+ sprintf(str, "[%s] < [%s]", a, b);
+
+ start(file, line, str);
+ delete[] str;
+
+ bool cond = strcmp(a, b) < 0;
+ check(cond);
+ return cond;
+}
+
+
+bool WvTest::start_check_lt(const char *file, int line, int a, int b)
+{
+ size_t len = 128 + 128 + 8 + 1;
+ char *str = new char[len];
+ sprintf(str, "%d < %d", a, b);
+
+ start(file, line, str);
+ delete[] str;
+
+ bool cond = a < b;
+ check(cond);
+ return cond;
+}
+
+int WvTest::start_check_frsh(const char *file, int line,
+ const char *condstr, int frsh_retval)
+{
+ char errstr[80] = "ok";
+ start(file, line, condstr);
+ if (frsh_retval != 0)
+ frsh_strerror (frsh_retval, errstr, sizeof(errstr));
+
+ check(frsh_retval == 0, errstr);
+
+ return frsh_retval;
+}
--- /dev/null
+/* -*- Mode: C++ -*-
+ * WvTest:
+ * Copyright (C) 1997-2009 Net Integration Technologies, Inc.
+ * Licensed under the GNU Library General Public License, version 2.
+ * See the included file named LICENSE for license information.
+ */
+#ifndef __WVTEST_H
+#define __WVTEST_H
+
+#ifndef WVTEST_CONFIGURED
+# error "Missing settings: HAVE_VALGRIND_MEMCHECK_H HAVE_WVCRASH WVTEST_CONFIGURED"
+#endif
+
+#include <time.h>
+#include <string>
+
+class WvTest
+{
+ typedef void MainFunc();
+ const char *descr, *idstr;
+ MainFunc *main;
+ int slowness;
+ WvTest *next;
+ static WvTest *first, *last;
+ static int fails, runs;
+ static time_t start_time;
+ static bool run_twice;
+
+ static void alarm_handler(int sig);
+
+ static void
+ print_result(bool start, const char *file, int line,
+ const char *condstr, const char *result);
+
+ static inline void
+ print_result(bool start, const char *file, int line,
+ const char *condstr, bool result)
+ { print_result(start, file, line, condstr, result ? "ok" : "FAILED"); }
+public:
+ WvTest(const char *_descr, const char *_idstr, MainFunc *_main, int _slow);
+ static int run_all(const char * const *prefixes = NULL);
+ static void start(const char *file, int line, const char *condstr);
+ static void check(bool cond, const char *reason = "FAILED");
+ static inline bool start_check(const char *file, int line,
+ const char *condstr, bool cond)
+ { start(file, line, condstr); check(cond); return cond; }
+ static bool start_check_eq(const char *file, int line,
+ const char *a, const char *b, bool expect_pass);
+ static bool start_check_eq(const char *file, int line,
+ const std::string &a, const std::string &b,
+ bool expect_pass);
+ static bool start_check_eq(const char *file, int line, int a, int b,
+ bool expect_pass);
+ static bool start_check_lt(const char *file, int line,
+ const char *a, const char *b);
+ static bool start_check_lt(const char *file, int line, int a, int b);
+ static int start_check_frsh(const char *file, int line,
+ const char *condstr, int frsh_retval);
+};
+
+
+#define WVPASS(cond) \
+ WvTest::start_check(__FILE__, __LINE__, #cond, (cond))
+#define WVPASSEQ(a, b) \
+ WvTest::start_check_eq(__FILE__, __LINE__, (a), (b), true)
+#define WVPASSLT(a, b) \
+ WvTest::start_check_lt(__FILE__, __LINE__, (a), (b))
+#define WVFAIL(cond) \
+ WvTest::start_check(__FILE__, __LINE__, "NOT(" #cond ")", !(cond))
+#define WVFAILEQ(a, b) \
+ WvTest::start_check_eq(__FILE__, __LINE__, (a), (b), false)
+#define WVPASSNE(a, b) WVFAILEQ(a, b)
+#define WVFAILNE(a, b) WVPASSEQ(a, b)
+#define WVFRSH(frshretval) \
+ WvTest::start_check_frsh(__FILE__, __LINE__, #frshretval, (frshretval))
+
+
+#define WVTEST_MAIN3(descr, ff, ll, slowness) \
+ static void _wvtest_main_##ll(); \
+ static WvTest _wvtest_##ll(descr, ff, _wvtest_main_##ll, slowness); \
+ static void _wvtest_main_##ll()
+#define WVTEST_MAIN2(descr, ff, ll, slowness) \
+ WVTEST_MAIN3(descr, ff, ll, slowness)
+#define WVTEST_MAIN(descr) WVTEST_MAIN2(descr, __FILE__, __LINE__, 0)
+#define WVTEST_SLOW_MAIN(descr) WVTEST_MAIN2(descr, __FILE__, __LINE__, 1)
+
+
+#endif // __WVTEST_H
--- /dev/null
+/*
+ * WvTest:
+ * Copyright (C) 1997-2009 Net Integration Technologies, Inc.
+ * Licensed under the GNU Library General Public License, version 2.
+ * See the included file named LICENSE for license information.
+ */
+#include "wvtest.h"
+#ifdef HAVE_WVCRASH
+# include "wvcrash.h"
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#ifdef _WIN32
+#include <io.h>
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <fcntl.h>
+#endif
+
+static bool fd_is_valid(int fd)
+{
+#ifdef _WIN32
+ if ((HANDLE)_get_osfhandle(fd) != INVALID_HANDLE_VALUE) return true;
+#endif
+ int nfd = dup(fd);
+ if (nfd >= 0)
+ {
+ close(nfd);
+ return true;
+ }
+ return false;
+
+}
+
+
+static int fd_count(const char *when)
+{
+ int count = 0;
+
+ printf("fds open at %s:", when);
+
+ for (int fd = 0; fd < 1024; fd++)
+ {
+ if (fd_is_valid(fd))
+ {
+ count++;
+ printf(" %d", fd);
+ fflush(stdout);
+ }
+ }
+ printf("\n");
+
+ return count;
+}
+
+
+int main(int argc, char **argv)
+{
+ char buf[200];
+#if defined(_WIN32) && defined(HAVE_WVCRASH)
+ setup_console_crash();
+#endif
+
+ // test wvtest itself. Not very thorough, but you have to draw the
+ // line somewhere :)
+ WVPASS(true);
+ WVPASS(1);
+ WVFAIL(false);
+ WVFAIL(0);
+ int startfd, endfd;
+ char * const *prefixes = NULL;
+
+ if (argc > 1)
+ prefixes = argv + 1;
+
+ startfd = fd_count("start");
+ int ret = WvTest::run_all(prefixes);
+
+ if (ret == 0) // don't pollute the strace output if we failed anyway
+ {
+ endfd = fd_count("end");
+
+ WVPASS(startfd == endfd);
+#ifndef _WIN32
+ if (startfd != endfd)
+ {
+ sprintf(buf, "ls -l /proc/%d/fd", getpid());
+ system(buf);
+ }
+#endif
+ }
+
+ // keep 'make' from aborting if this environment variable is set
+ if (getenv("WVTEST_NO_FAIL"))
+ return 0;
+ else
+ return ret;
+}
--- /dev/null
+../../src/wvtest/wvtestrun
\ No newline at end of file
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+SUBDIRS=$(ALL_OMK_SUBDIRS)
--- /dev/null
+# Version for Linux/RTLinux builds. #OMK@linux
+#
+# Makefile.rules - OCERA make framework common project rules -*- makefile -*- #OMK@base
+#
+# (C) Copyright 2003 by Pavel Pisa - OCERA team member
+# (C) Copyright 2006 by Michal Sojka - Czech Technical University, FEE, DCE
+#
+# Homepage: http://rtime.felk.cvut.cz/omk/
+#
+# The OMK build system is distributed under the GNU General Public
+# License. See file COPYING for details.
+#
+# input variables
+# V .. if set to 1, full command text is shown else short form is used
+# W .. whole tree - if set to 1, make is always called from the top-level directory
+# SUBDIRS .. list of subdirectories intended for make from actual directory
+# default_CONFIG .. list of default config assignments CONFIG_XXX=y/n ...
+# LN_HEADERS .. if "y", header files are symbolicaly linked instead of copied. #OMK@include
+# #OMK@linux
+# input variables
+# lib_LIBRARIES .. list of the user-space libraries
+# shared_LIBRARIES .. list of the user-space shared libraries
+# kernel_LIBRARIES .. list of the kernel-space libraries
+# rtlinux_LIBRARIES.. list of the RT-Linux kernel-space libraries
+# include_HEADERS .. list of the user-space public header files
+# nobase_include_HEADERS .. public headers copied even with directory part
+# renamed_include_HEADERS .. public headers copied to the different target name
+# kernel_HEADERS .. list of the kernel-space public header files
+# rtlinux_HEADERS .. list of the RT-Linux kernel-space public header files
+# bin_PROGRAMS .. list of the require binary programs
+# utils_PROGRAMS .. list of the development utility programs
+# test_PROGRAMS .. list of the testing programs
+# kernel_MODULES .. list of the kernel side modules/applications
+# rtlinux_MODULES .. list of RT-Linux the kernel side modules/applications
+# xxx_SOURCES .. list of specific target sources
+# xxx_LIBS .. list of specific target libraries
+# INCLUDES .. additional include directories and defines for user-space
+# kernel_INCLUDES .. additional include directories and defines for kernel-space
+# rtlinux_INCLUDES .. additional include directories and defines for RT-Linux
+# OMIT_KERNEL_PASSES if defined, all kernel passes are omited
+#
+# LINUX_DIR .. location of Linux kernel sources
+# RTL_DIR .. location of RT-Linux sources
+# CFLAGS .. C compiler flags
+# CXXFLAGS .. C++ compiler flags
+# CPPFLAGS .. C preprocessor flags
+# LDFLAGS .. linker flags for programs linking
+# LOCAL_CONFIG_H .. name of local config.h file generated from values #OMK@config_h
+# of options defined in the current directory
+# config_include_HEADERS .. names of global config files (possibly
+# with subdirectories)
+# xxx_DEFINES .. list of config directives to be included in
+# config header file of the name <somedir>/xxx.h
+# DOXYGEN .. if non-empty, generated headers includes Doxygen's @file
+# command, so it is possible to document config
+# variables.
+# QT_SUBDIRS .. subdirectories where to build QT applications using qmake #OMK@qt
+# QTDIR .. where QT resides
+OMK_RULES_TYPE=linux #OMK@__type
+ #OMK@base
+# We need to ensure definition of sources directory first
+ifndef SOURCES_DIR
+# Only shell built-in pwd understands -L
+SOURCES_DIR := $(shell ( pwd -L ) )
+endif
+
+# If we are not called by OMK leaf Makefile...
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(abspath $(dir $(filter %Makefile.rules,$(MAKEFILE_LIST))))
+endif
+
+# OUTPUT_DIR is the place where _compiled, _build and possible other
+# files/directories are created. By default is the same as
+# $(MAKERULES_DIR).
+ifndef OUTPUT_DIR
+OUTPUT_DIR := $(MAKERULES_DIR)
+endif
+
+.PHONY: all default check-make-ver omkize
+
+ifdef W
+ ifeq ("$(origin W)", "command line")
+ OMK_WHOLE_TREE:=$(W)
+ endif
+endif
+ifndef OMK_WHOLE_TREE
+ OMK_WHOLE_TREE:=0
+endif
+
+ifneq ($(OMK_WHOLE_TREE),1)
+all: check-make-ver default
+ @echo "Compilation finished"
+else
+# Run make in the top-level directory
+all:
+ @$(MAKE) -C $(MAKERULES_DIR) OMK_SERIALIZE_INCLUDED=n SOURCES_DIR=$(MAKERULES_DIR) RELATIVE_DIR="" $(MAKECMDGOALS) W=0
+endif
+
+ifdef OMK_TESTSROOT
+# Usage: $(call canttest,<error message>)
+define canttest
+ ( echo "$(1)" > $(OUTPUT_DIR)/_canttest; echo "$(1)"; exit 1 )
+endef
+else
+define canttest
+ echo "$(1)"
+endef
+endif
+
+#=========================
+# Include the config file
+
+# FIXME: I think CONFIG_FILE_OK variable is useless. We have three
+# config files and it is not clearly defined to which file is this
+# variable related.
+ifneq ($(CONFIG_FILE_OK),y)
+ifndef CONFIG_FILE
+CONFIG_FILE := $(OUTPUT_DIR)/config.omk
+endif
+ifneq ($(wildcard $(CONFIG_FILE)-default),)
+-include $(CONFIG_FILE)-default
+else
+ifneq ($(MAKECMDGOALS),default-config)
+$(warning Please, run "make default-config" first)
+endif
+endif
+
+-include $(OUTPUT_DIR)/config.target
+
+ifneq ($(wildcard $(CONFIG_FILE)),)
+-include $(CONFIG_FILE)
+CONFIG_FILE_OK = y
+endif
+endif #$(CONFIG_FILE_OK)
+
+
+CONFIG_FILES ?= $(wildcard $(CONFIG_FILE)-default) $(wildcard $(OUTPUT_DIR)/config.target) $(wildcard $(CONFIG_FILE))
+
+
+export SOURCES_DIR MAKERULES_DIR RELATIVE_DIR
+export CONFIG_FILE CONFIG_FILES OMK_SERIALIZE_INCLUDED OMK_VERBOSE OMK_SILENT
+# OMK_SERIALIZE_INCLUDED has to be exported to submakes because passes
+# must to be serialized only in the toplevel make.
+
+ifndef RELATIVE_DIR
+RELATIVE_DIR := $(SOURCES_DIR:$(OUTPUT_DIR)%=%)
+endif
+#$(warning === RELATIVE_DIR = "$(RELATIVE_DIR)" ===)
+override RELATIVE_DIR := $(RELATIVE_DIR:/%=%)
+override RELATIVE_DIR := $(RELATIVE_DIR:\\%=%)
+#$(warning RELATIVE_DIR = "$(RELATIVE_DIR)")
+override BACK2TOP_DIR := $(shell echo $(RELATIVE_DIR)/ | sed -e 's_//_/_g' -e 's_/\./_/_g' -e 's_^\./__g' -e 's_\([^/][^/]*\)_.._g' -e 's_/$$__')
+#$(warning BACK2TOP_DIR = "$(BACK2TOP_DIR)")
+
+#$(warning SOURCES_DIR = "$(SOURCES_DIR)")
+#$(warning MAKERULES_DIR = "$(OUTPUT_DIR)")
+#$(warning RELATIVE_DIR = "$(RELATIVE_DIR)")
+
+# We have to use RELATIVE_PREFIX because of mingw
+override RELATIVE_PREFIX := $(RELATIVE_DIR)/
+override RELATIVE_PREFIX := $(RELATIVE_PREFIX:/%=%)
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+# Define srcdir for Automake compatibility
+srcdir = $(SOURCES_DIR)
+
+# Defines for quiet compilation
+ifdef V
+ ifeq ("$(origin V)", "command line")
+ OMK_VERBOSE = $(V)
+ endif
+endif
+ifndef OMK_VERBOSE
+ OMK_VERBOSE = 0
+endif
+ifneq ($(OMK_VERBOSE),0)
+ Q =
+else
+ Q = @
+endif
+ifneq ($(findstring s,$(MAKEFLAGS)),)
+ QUIET_CMD_ECHO = true
+ OMK_SILENT = 1
+else
+ QUIET_CMD_ECHO = echo
+endif
+
+MAKEFILE_OMK=Makefile.omk
+# All subdirectories (even linked ones) containing Makefile.omk
+# Usage in Makefile.omk: SUBDIRS = $(ALL_OMK_SUBDIRS)
+ALL_OMK_SUBDIRS = $(patsubst %/$(MAKEFILE_OMK),%,$(patsubst $(SOURCES_DIR)/%,%,$(wildcard $(SOURCES_DIR)/*/$(MAKEFILE_OMK))))
+
+# ===================================================================
+# We have set up all important variables, so we can check and include
+# real OCERA style Makefile.omk now
+ifndef OMK_INCLUDED
+include $(SOURCES_DIR)/$(MAKEFILE_OMK)
+ifeq ($(AUTOMATIC_SUBDIRS),y)
+SUBDIRS?=$(ALL_OMK_SUBDIRS)
+endif
+OMK_INCLUDED := 1
+endif
+
+check-make-ver:
+ @GOOD_MAKE_VERSION=`echo $(MAKE_VERSION) | sed -n -e 's/^[4-9]\..*\|^3\.9[0-9].*\|^3\.8[1-9].*/y/p'` ; \
+ if [ x$$GOOD_MAKE_VERSION != xy ] ; then \
+ echo "Your make program version is too old and does not support OMK system." ; \
+ echo "Please update to make program 3.81beta1 or newer." ; exit 1 ; \
+ fi
+
+distclean dist-clean:
+ @$(QUIET_CMD_ECHO) " RM $(COMPILED_DIR_NAME) $(BUILD_DIR_NAME)"
+ @rm -fr $(OUTPUT_DIR)/$(COMPILED_DIR_NAME) $(OUTPUT_DIR)/$(BUILD_DIR_NAME)
+
+# Common OMK templates
+# ====================
+
+# Syntax: $(call mkdir,<dir name>)
+define mkdir_def
+ [ -d $(1) ] || mkdir -p $(1) || exit 1
+endef
+
+ifneq ($(OMK_VERBOSE),2)
+NO_PRINT_DIRECTORY := --no-print-directory
+endif
+
+ifeq ($(USE_LEAF_MAKEFILES),n)
+export USE_LEAF_MAKEFILES
+SUBDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+SOURCESDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+else
+SUBDIR_MAKEFILE=$(SOURCES_DIR)/$(3)/Makefile
+SOURCESDIR_MAKEFILE=$(SOURCES_DIR)/Makefile
+endif
+
+pass = $(strip $(1))
+
+# Call a pass in a subdirectory
+# Usage: $(call omk_pass_subdir_template,<pass name>,<build dir>,<subdir>)
+define omk_pass_subdir_template
+.PHONY: $(pass)-$(3)-subdir
+$(pass)-submakes: $(pass)-$(3)-subdir
+$(pass)-$(3)-subdir:
+ @$(call mkdir_def,$(2)/$(3))
+ +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(3) $(NO_PRINT_DIRECTORY) \
+ RELATIVE_DIR=$(RELATIVE_PREFIX)$(3) -C $(2)/$(3) \
+ -f $(SUBDIR_MAKEFILE) $(pass)-submakes
+# In subdirectories we can call submakes directly since passes are
+# already searialized on the toplevel make.
+endef
+
+ifdef OMK_TESTSROOT
+check-target = $(1:%=%-check)
+endif
+
+# Call a pass in a subdirectory
+# Usage: $(call extra_rules_subdir_template,<subdir>)
+define extra_rules_subdir_template
+extra-rules-subdirs: extra-rules-$(1)
+extra-rules-$(1):
+ +@$(MAKE) OMK_SERIALIZE_INCLUDED=n MAKERULES_DIR=$(SOURCES_DIR)/$(1) OUTPUT_DIR=$(OUTPUT_DIR) \
+ SOURCES_DIR=$(SOURCES_DIR)/$(1) RELATIVE_DIR=$(RELATIVE_PREFIX)$(1) -C $(SOURCES_DIR)/$(1)
+endef
+
+.PHONY: extra-rules-subdirs
+extra-rules-subdirs:
+
+$(foreach subdir,$(EXTRA_RULES_SUBDIRS),$(eval $(call extra_rules_subdir_template,$(subdir))))
+
+# Usage: $(call omk_pass_template,<pass name>,<build dir>,[<local make flags>],[<local enable condition>])
+define omk_pass_template
+.PHONY: $(pass) $(pass)-local $(pass)-check $(pass)-submakes
+$(foreach subdir,$(SUBDIRS),$(eval $(call omk_pass_subdir_template,$(pass),$(2),$(subdir))))
+$(pass):
+# Submakes have to be called this way and not as dependecies for pass
+# serialization to work
+ +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR) $(NO_PRINT_DIRECTORY) \
+ RELATIVE_DIR=$(RELATIVE_DIR) \
+ -f $(SOURCESDIR_MAKEFILE) $(pass)-submakes
+$(pass)-submakes:
+ @true # Do not emit "nothing to be done" messages
+
+ifneq ($(4)$($(pass)_HOOKS),)
+$(pass)-submakes: $(pass)-this-dir
+$(pass)-this-dir: $(foreach subdir,$(SUBDIRS),$(pass)-$(subdir)-subdir)
+ +@echo "make[omk]: $(pass) in $(RELATIVE_DIR)"
+ @$(call mkdir_def,$(2))
+ +@$(MAKE) $(NO_PRINT_DIRECTORY) SOURCES_DIR=$(SOURCES_DIR) RELATIVE_DIR=$(RELATIVE_DIR) -C $(2) \
+ -f $(SOURCESDIR_MAKEFILE) $(3) $(check-target) $(1:%=%-local)
+$(pass)-local: $($(pass)_HOOKS)
+endif
+endef
+
+# =======================
+# DEFAULT CONFIG PASS
+
+default-config:
+ @echo "# Start of OMK config file" > "$(CONFIG_FILE)-default"
+ @echo "# This file should not be altered manually" >> "$(CONFIG_FILE)-default"
+ @echo "# Overrides should be stored in file $(notdir $(CONFIG_FILE))" >> "$(CONFIG_FILE)-default"
+ @echo >> "$(CONFIG_FILE)-default"
+ @$(MAKE) $(NO_PRINT_DIRECTORY) -C $(OUTPUT_DIR) \
+ RELATIVE_DIR="" SOURCES_DIR=$(OUTPUT_DIR) \
+ -f $(OUTPUT_DIR)/Makefile default-config-pass
+
+$(eval $(call omk_pass_template,default-config-pass,$$(LOCAL_BUILD_DIR),,always))
+
+default-config-pass-local:
+# @echo Default config for $(RELATIVE_DIR)
+ @echo "# Config for $(RELATIVE_DIR)" >> "$(CONFIG_FILE)-default"
+ @$(foreach x, $(default_CONFIG), echo '$(x)' | \
+ sed -e 's/^[^=]*=x$$/#\0/' >> "$(CONFIG_FILE)-default" ; )
+
+
+omkize:
+ $(Q)if ! grep -q MAKERULES_DIR Makefile; then \
+ echo "Makefile is not OMK leaf makefile!" >&2; exit 1; \
+ fi
+ $(Q)for i in `find -L . -name Makefile.omk` ; do \
+ d=`dirname $${i}`; \
+ if ! test -f "$${d}/Makefile.rules" && ( ! test -f "$${d}/Makefile" || ! cmp --silent Makefile "$${d}/Makefile" ); then \
+ rm -f "$${d}/Makefile"; \
+ cp -v Makefile "$${d}/Makefile"; \
+ fi \
+ done
+ifeq ($(OMK_VERBOSE),1) #OMK@include
+CPHEADER_FLAGS += -v
+LNHEADER_FLAGS += -v
+endif
+
+ifneq ($(LN_HEADERS),y)
+define cp_cmd
+( echo " CP $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; cp $(CPHEADER_FLAGS) $(1) $(2) )
+endef
+else
+define cp_cmd
+( echo " LN $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; [ -f $(1) ] && ln -sf $(LNHEADER_FLAGS) $(1) $(2) )
+endef
+endif
+
+# TODO: Check modification date of changed header files. If it is
+# newer that in source dir, show a warning.
+
+# Syntax: $(call include-pass-template,<include dir>,<keyword>)
+define include-pass-template
+include-pass-local: include-pass-local-$(2)
+include-pass-local-$(2): $$($(2)_GEN_HEADERS) $$(foreach f,$$(renamed_$(2)_GEN_HEADERS),$$(shell echo '$$(f)' | sed -e 's/^\(.*\)->.*$$$$/\1/'))
+ @$$(foreach f, $$($(2)_HEADERS), cmp --quiet $$(SOURCES_DIR)/$$(f) $(1)/$$(notdir $$(f)) \
+ || $$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(notdir $$(f))) || exit 1 ; )
+ @$$(foreach f, $$($(2)_GEN_HEADERS), cmp --quiet $$(f) $(1)/$$(notdir $$(f)) \
+ || $$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$(f),$(1)/$$(notdir $$(f))) || exit 1 ; ) # FIXME: Use correct build dir, then document it
+ @$$(foreach f, $$(nobase_$(2)_HEADERS), cmp --quiet $$(SOURCES_DIR)/$$(f) $(1)/$$(f) \
+ || ( mkdir -p $(1)/$$(dir $$(f)) && $$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(f)) ) || exit 1 ; )
+ @$$(foreach f, $$(renamed_$(2)_HEADERS), \
+ srcfname=`echo '$$(f)' | sed -e 's/^\(.*\)->.*$$$$/\1/'` ; destfname=`echo '$$(f)' | sed -e 's/^.*->\(.*\)$$$$/\1/'` ; \
+ cmp --quiet $$(SOURCES_DIR)/$$$${srcfname} $(1)/$$$${destfname} \
+ || ( mkdir -p `dirname $(1)/$$$${destfname}` && $$(call cp_cmd,$$(SOURCES_DIR)/$$$${srcfname},$(1)/$$$${destfname}) ) || exit 1 ; )
+ @$$(foreach f, $$(renamed_$(2)_GEN_HEADERS), \
+ srcfname=`echo '$$(f)' | sed -e 's/^\(.*\)->.*$$$$/\1/'` ; destfname=`echo '$$(f)' | sed -e 's/^.*->\(.*\)$$$$/\1/'` ; \
+ cmp --quiet $$$${srcfname} $(1)/$$$${destfname} \
+ || ( mkdir -p `dirname $(1)/$$$${destfname}` && $$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$$${srcfname},$(1)/$$$${destfname}) ) || exit 1 ; )
+endef
+
+# Local Variables:
+# mode:makefile
+# End:
+ #OMK@linux
+# Hack to check RT-Linux rules
+#LINUX_DIR := /home/cvs/ocera/ocera-build/kernel/linux
+#RTL_DIR := /home/cvs/ocera/ocera-build/kernel/rtlinux
+#CONFIG_RTLINUX = y
+#OCERA_DIR := $(shell ( cd -L $(OUTPUT_DIR)/../../.. ; pwd -L ) )
+
+-include $(OUTPUT_DIR)/OCERA_TOP_DIR
+
+BUILD_DIR_NAME = _build
+COMPILED_DIR_NAME = _compiled
+ifndef GROUP_DIR_NAME
+GROUP_DIR_NAME = nogroup
+endif
+
+ifdef OCERA_DIR
+ifeq ($(wildcard $(OCERA_DIR)/ocera.mk),)
+$(warning "ocera.mk" file does not exist. Adapt Makefile.rules for standalone compilation)
+$(warning (comment out definition of OCERA_DIR line and optionally select RTL_DIR) )
+$(error or go to the ocera/ directory and do 'make' to generate the "ocera.mk" file first, please)
+endif
+include $(OCERA_DIR)/ocera.mk
+KERN_INCLUDE_DIR := $(OCERA_KERNEL_INCLUDES_DIR)
+KERN_LIB_DIR := $(OCERA_KERNEL_LIBRARIES_DIR)
+KERN_MODULES_DIR := $(OCERA_MODULES_DIR)
+KERN_BUILD_DIR := $(BUILD_DIR)/kern/$(GROUP_DIR_NAME)
+KERN_MODPOST_DIR := $(BUILD_DIR)/kern-modpost
+USER_INCLUDE_DIR := $(OCERA_USER_INCLUDES_DIR)
+USER_LIB_DIR := $(OCERA_USER_LIBRARIES_DIR)
+USER_UTILS_DIR := $(TARGET_DIR)/usr/bin
+USER_TESTS_DIR := $(TARGET_DIR)/usr/bin
+USER_BIN_DIR := $(TARGET_DIR)/usr/bin
+USER_BUILD_DIR := $(BUILD_DIR)/user/$(GROUP_DIR_NAME)
+#LINUX_DIR := $(OCERA_DIR)/kernel/linux
+#RTL_DIR := $(OCERA_DIR)/kernel/rtlinux
+#CONFIG_FILE := $(OCERA_DIR)/emdebsys/.config
+ifneq ($(wildcard $(CONFIG_FILE)),)
+CONFIG_FILE_OK = y
+endif
+else # OCERA_DIR
+KERN_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include-kern
+KERN_LIB_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib-kern
+KERN_MODULES_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/modules
+KERN_BUILD_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern
+KERN_MODPOST_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern-modpost
+USER_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include
+USER_LIB_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib
+USER_UTILS_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-utils
+USER_TESTS_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-tests
+USER_BIN_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin
+USER_BUILD_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/user
+
+ifndef LINUX_VERSION
+LINUX_VERSION=$(shell uname -r)
+endif
+ifndef LINUX_DIR
+LINUX_DIR=/lib/modules/$(LINUX_VERSION)/build
+endif
+endif # OCERA_DIR
+
+ifeq ($(BUILD_OS),)
+ # Check for target
+ ifeq ($(OS),Windows_NT)
+ BUILD_OS := win32
+ else
+ BUILD_OS := $(shell uname | tr '[A-Z]' '[a-z]' )
+ #$(warning BUILD_OS=$(BUILD_OS))
+ endif
+endif
+
+ifeq ($(TARGET_OS),)
+ TARGET_OS := $(BUILD_OS)
+endif
+
+export TARGET_OS
+export BUILD_OS
+
+LOCAL_BUILD_DIR = $(USER_OBJS_DIR)
+
+# Assign default values to CFLAGS variable. If the variable is defined
+# earlier (i.g. in config.omk), it is not overriden here.
+CFLAGS ?= -O2 -Wall
+CXXFLAGS ?= -O2 -Wall
+
+
+CPPFLAGS += -I $(USER_INCLUDE_DIR)
+
+LOADLIBES += -L$(USER_LIB_DIR)
+
+LOADLIBES += $(lib_LOADLIBES:%=-l%)
+
+LIB_CPPFLAGS += $(CPPFLAGS)
+LIB_CFLAGS += $(CFLAGS)
+
+ifeq ($(TARGET_OS),win32)
+ SOLIB_EXT = dll
+else
+ SOLIB_EXT = so
+ SOLIB_PICFLAGS += -fpic
+endif
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+USER_OBJS_DIR = $(USER_BUILD_DIR)/$(RELATIVE_DIR)
+KERN_OBJS_DIR = $(KERN_BUILD_DIR)/$(RELATIVE_DIR)
+
+.PHONY: dep subdirs clean clean-custom cleandepend check-dir
+
+# Some support to serialize some targets for parallel make
+ifneq ($(OMK_SERIALIZE_INCLUDED),y)
+include-pass: check-dir
+library-pass: include-pass
+binary-pass: library-pass
+kernel-lib-pass: include-pass
+kernel-mod-pass: kernel-lib-pass
+kernel-modpost-pass: kernel-mod-pass
+kernel-pass: kernel-mod-pass kernel-modpost-pass
+
+override OMK_SERIALIZE_INCLUDED = y
+MAKEOVERRIDES := $(filter-out OMK_SERIALIZE_INCLUDED=n,$(MAKEOVERRIDES))
+endif
+
+# Checks for OMK tester
+ifdef OMK_TESTSROOT
+default-config-pass-check include-pass-check:
+library-pass-check binary-pass-check:
+ @[ -x "$(shell which $(CC))" ] || $(call canttest,Cannot find compiler: $(CC))
+endif
+
+#=====================================================================
+# User-space rules and templates to compile programs, libraries etc.
+
+ifdef USER_RULE_TEMPLATES
+
+USER_SOURCES2OBJS = .o/.c .o/.cc .o/.cxx .o/.S .o/.o
+
+USER_SOURCES2OBJSLO = .lo/.c .lo/.cc .lo/.cxx .lo/.S .lo/.lo
+
+#%.lo: %.c
+# $(CC) -o $@ $(LCFLAGS) -c $<
+
+c_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+cc_o_COMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+S_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(ASFLAGS) -DOMK_FOR_USER
+
+idl_COMPILE = $(IDL_COMPILER)
+
+# Check GCC version for user build
+ifndef CC_MAJOR_VERSION
+CC_MAJOR_VERSION := $(shell $(CC) -dumpversion | sed -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(CC_MAJOR_VERSION),2)
+CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+
+# Syntax: $(call COMPILE_c_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_c_o_template
+$(2): $(1) $$(GEN_HEADERS)
+ @$(QUIET_CMD_ECHO) " CC $$@"
+ $(Q) if $$(c_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+# Syntax: $(call COMPILE_cc_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_cc_o_template
+$(2): $(1) $$(GEN_HEADERS)
+ @$(QUIET_CMD_ECHO) " CXX $$@"
+ $(Q) if $$(cc_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+# Syntax: $(call COMPILE_S_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_S_o_template
+$(2): $(1) $$(GEN_HEADERS)
+ @$(QUIET_CMD_ECHO) " AS $$@"
+ $(Q) if $$(S_o_COMPILE) -D__ASSEMBLY__ $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+# Syntax: $(call CMETRIC_o_h_template,<object_file>,<target_header>)
+define CMETRIC_o_h_template
+$(2): $(1)
+ @$(QUIET_CMD_ECHO) " CMETRIC $$@"
+ $(Q)if [ -n `dirname $$@` ] ; then \
+ if [ ! -e `dirname $$@` ] ; then \
+ mkdir -p `dirname $$@` ; fi ; fi
+ $(Q)echo >$$@ '/* Automatically generated from $$< */'
+ $(Q)echo >>$$@ '/* Conditionals to control compilation */'
+ $(Q)set -o pipefail ; $(NM) $$< \
+ | sed -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2cond_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+ | sort >>$$@
+ $(Q)echo >>$$@ '/* Defines from the values defined to symbols */'
+ $(Q)set -o pipefail ; $(NM) $$< \
+ | sed -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2def_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+ | sort >>$$@
+endef
+
+
+
+define COMPILE_idl_template
+$(2).c $(2)-stubs.c $(2)-skels.c $(2)-common.c $(2).h: $(1)
+ @$(QUIET_CMD_ECHO) " IDL $$@"
+ $(Q) $$(idl_COMPILE) $$($(2)_IDLFLAGS) $(1)
+endef
+
+
+# Syntax: $(call PROGRAM_template,<dir>,<executable-name>,<executable-suffix>,<linker-sript>)
+# FIXME: ???????? asi je tu blbej komentar
+define PROGRAM_template
+
+USER_IDLS += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+USER_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+ $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+USER_OBJS += $$($(1)_OBJS)
+USER_SOURCES += $$($(1)_SOURCES)
+
+$(2)/$(1)$(3): $$($(1)_OBJS)
+ @$(QUIET_CMD_ECHO) " LINK $$@"
+ $(Q) $$(if $$(filter %.cc,$$($(1)_SOURCES:%.cxx=%.cc)),$$(CXX),$$(CC)) \
+ $$($(1)_OBJS) $$($(1)_LIBS:%=-l%) $$(LOADLIBES) $$(LDFLAGS) -Wl,-Map,$(USER_OBJS_DIR)/$(1).exe.map -o $$@
+ @echo "$(2)/$(1)$(3): \\" >$(USER_OBJS_DIR)/$(1).exe.d
+ @sed -n -e 's|^LOAD \(.*\)$$$$| \1 \&|p' $(USER_OBJS_DIR)/$(1).exe.map|tr '&' '\134' >>$(USER_OBJS_DIR)/$(1).exe.d
+ @echo >>$(USER_OBJS_DIR)/$(1).exe.d
+endef
+
+
+# Syntax: $(call LIBRARY_template,<library-name>)
+define LIBRARY_template
+
+USER_IDLS += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+USER_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+ $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+USER_OBJS += $$($(1)_OBJS)
+USER_SOURCES += $$($(1)_SOURCES)
+
+$(USER_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+ @$(QUIET_CMD_ECHO) " AR $$@"
+ $(Q) $(AR) rcs $$@ $$^
+endef
+
+
+# Syntax: $(call SOLIB_template,<library-name>)
+define SOLIB_template
+
+USER_IDLS += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+SOLIB_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJSLO),
+$(1)_OBJSLO += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+ $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJSLO := $$(sort $$($(1)_OBJSLO:%/=%))
+
+SOLIB_OBJS += $$($(1)_OBJSLO)
+SOLIB_SOURCES += $$($(1)_SOURCES)
+
+$(USER_LIB_DIR)/lib$(1).$(SOLIB_EXT): $$($(1)_OBJSLO)
+ @$(QUIET_CMD_ECHO) " LINK $$@"
+ $(Q) $(CC) --shared -Xlinker -soname=lib$(1).$(SOLIB_EXT) -o $$@ $$^ $$(LOADLIBES) $$($(1)_LIBS:%=-l%)
+endef
+
+
+
+library-pass-local: $(addprefix $(USER_INCLUDE_DIR)/,$(cmetric_include_HEADERS)) \
+ $(lib_LIBRARIES:%=$(USER_LIB_DIR)/lib%.a) $(shared_LIBRARIES:%=$(USER_LIB_DIR)/lib%.$(SOLIB_EXT))
+
+binary-pass-local: $(bin_PROGRAMS:%=$(USER_BIN_DIR)/%$(EXE_SUFFIX)) $(utils_PROGRAMS:%=$(USER_UTILS_DIR)/%$(EXE_SUFFIX)) $(test_PROGRAMS:%=$(USER_TESTS_DIR)/%$(EXE_SUFFIX))
+
+# Special rules for CMETRIC generated headers
+
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call COMPILE_c_o_template,\
+ $(SOURCES_DIR)/$($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES),\
+ $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),)))
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call CMETRIC_o_h_template,\
+ $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),\
+ $(addprefix $(USER_INCLUDE_DIR)/,$(cmetrh)))))
+
+GEN_HEADERS+=$(cmetric_include_HEADERS:%=$(USER_INCLUDE_DIR)/%)
+
+GEN_HEADERS+=$(filter %.h,$(USER_IDLS:%.idl=%.h))
+
+# Generate rules for compilation of programs and libraries
+
+$(foreach prog,$(utils_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_UTILS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(test_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_TESTS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(bin_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_BIN_DIR),$(EXE_SUFFIX))))
+
+$(foreach lib,$(lib_LIBRARIES),$(eval $(call LIBRARY_template,$(lib))))
+
+$(foreach lib,$(shared_LIBRARIES),$(eval $(call SOLIB_template,$(lib))))
+
+-include $(USER_OBJS_DIR)/*.d
+
+endif
+
+#=====================================================================
+# Kernel-space rules and templates to compile modules, libraries etc.
+
+ifdef KERN_RULE_TEMPLATES
+
+$(KERN_LIB_DIR)/kernel.mk: $(LINUX_DIR)/.config $(MAKERULES_DIR)/kernelcfg2mk
+ @$(QUIET_CMD_ECHO) " KCFG2MK $$@"
+ $(Q) $(MAKERULES_DIR)/kernelcfg2mk $(LINUX_DIR) $(KERN_LIB_DIR)
+
+ifeq ($(CONFIG_RTLINUX),y)
+include $(RTL_DIR)/rtl.mk
+
+KERN_CC = $(CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(CC) -print-search-dirs | sed -n -e 's/^install: \(.*\)$$/\1/p' )
+INCLUDES := -I $(KERN_INCLUDE_DIR) $(INCLUDE) $(rtlinux_INCLUDES) $(kernel_INCLUDES)
+#-DEXPORT_NO_SYMBOLS
+c_o_kern_COMPILE = $(KERN_CC) -idirafter $(kern_GCCLIB_DIR)/include $(INCLUDES) $(CFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(CXX) $(INCLUDES) $(CXXFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+KERN_EXE_SUFFIX := .o
+KERN_ARCH = $(ARCH)
+KERN_LD = $(LD)
+KERN_AR = $(AR)
+
+else # CONFIG_RTLINUX
+
+include $(KERN_LIB_DIR)/kernel.mk
+
+ifeq ($(LINUX_SRC),)
+LINUX_SRC = $(LINUX_DIR)
+endif
+kernel_INCLUDES += -I $(LINUX_DIR) -idirafter $(LINUX_SRC)/include/linux
+
+ifdef LINUX_CC
+KERN_CC = $(LINUX_CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(LINUX_CC) -print-search-dirs | sed -n -e 's/^install: \(.*\)$$/\1/p' )
+else
+KERN_CC = echo KERN_CC not defined - compilation skipped
+endif
+c_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+S_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_AFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+KERN_EXE_SUFFIX := $(LINUX_MODULE_EXT)
+KERN_LDFLAGS = $(LINUX_LDFLAGS)
+ifdef LINUX_ARCH
+KERN_ARCH = $(LINUX_ARCH)
+else
+KERN_ARCH = echo KERN_ARCH not defined - skipped
+endif
+ifdef LINUX_LD
+KERN_LD = $(LINUX_LD)
+else
+KERN_LD = echo KERN_LD not defined - skipped
+endif
+ifneq ($(LINUX_AR),)
+KERN_AR = $(LINUX_AR)
+else
+KERN_AR = $(AR)
+endif
+ifeq ($(LINUX_QUOTE_MODNAME),y)
+KERN_MQ=\"
+KERN_KBUILD_MODNAME=-D"KBUILD_MODNAME=((THIS_MODULE)!=NULL?(THIS_MODULE)->name:NULL)"
+endif
+endif # CONFIG_RTLINUX
+
+KERN_LOADLIBES += -L$(KERN_LIB_DIR)
+
+KERN_LOADLIBES += $(rtlinux_LOADLIBES:%=-l%)
+KERN_LOADLIBES += $(kernel_LOADLIBES:%=-l%)
+
+
+
+# Check GCC version for kernel part of build
+ifndef kern_CC_MAJOR_VERSION
+kern_CC_MAJOR_VERSION := $(shell $(KERN_CC) -dumpversion | sed -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(kern_CC_MAJOR_VERSION),2)
+kern_CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+kern_CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+ifeq ($(KERN_EXE_SUFFIX),.ko)
+ifeq ($(wildcard $(LINUX_DIR)/scripts/mod/modpost),)
+KERN_MODPOST = $(LINUX_DIR)/scripts/modpost
+else
+KERN_MODPOST = $(LINUX_DIR)/scripts/mod/modpost
+endif
+KERN_MODULES_LINK_DIR = $(KERN_MODPOST_DIR)
+KERN_LINK_SUFFIX = .o
+else
+KERN_MODULES_LINK_DIR = $(KERN_MODULES_DIR)
+KERN_LINK_SUFFIX = $(KERN_EXE_SUFFIX)
+endif
+
+ifeq ($(LINUX_CONFIG_MODVERSIONS),y)
+MODPOST_OPTS += -m
+MODPOST_OPTS += -i $(LINUX_DIR)/Module.symvers
+ifneq ($(LINUX_BUILDHOST),) # this is not correct point, it should look for 2.6.17 kernel
+MODPOST_OPTS += -I $(KERN_LIB_DIR)/Module.symvers
+endif
+MODPOST_OPTS += -o $(KERN_LIB_DIR)/Module.symvers
+endif
+
+ifeq ($(LINUX_CONFIG_DEBUG_SECTION_MISMATCH),y)
+MODPOST_OPTS += -S
+endif
+
+ifeq ($(LINUX_CONFIG_MARKERS),y)
+MODPOST_OPTS += -K $(LINUX_DIR)/Module.markers
+MODPOST_OPTS += -M $(KERN_LIB_DIR)/Module.markers
+endif
+
+ifeq ($(LINUX_KBUILD_MODPOST_WARN),y)
+MODPOST_OPTS += -w
+endif
+
+ifneq ($(LINUX_BUILDHOST),)
+ifneq ($(LINUX_BUILDHOST),$(LINUX_ARCH))
+MODPOST_OPTS += -c
+endif
+endif
+
+define COMPILE_c_o_kern_template
+
+$(2): $(1)
+ @$(QUIET_CMD_ECHO) " CC [K] $$@"
+ $(Q) if $$(c_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+ -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+ -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+
+define COMPILE_cc_o_kern_template
+
+$(2): $(1)
+ @$(QUIET_CMD_ECHO) " CXX [K] $$@"
+ $(Q) if $$(cc_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+ -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+ -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+
+define COMPILE_S_o_kern_template
+
+$(2): $(1)
+ @$(QUIET_CMD_ECHO) " AS [K] $$@"
+ $(Q) if $$(S_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+ -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+ -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+
+define MODULE_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+# this is hack to build "__this_module" structure for 2.6.x kernels
+# modpost is used for that purpose now
+
+#$(1).mod.c:
+# echo "\
+# #include <linux/version.h>@\
+# #include <linux/module.h>@\
+# #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,5))@\
+# #include <linux/vermagic.h>@\
+# #include <linux/compiler.h>@\
+# @\
+# MODULE_INFO(vermagic, VERMAGIC_STRING);@\
+# @\
+# #undef unix@\
+# struct module __this_module@\
+# __attribute__((section(\".gnu.linkonce.this_module\"))) = {@\
+# .name = __stringify(KBUILD_MODNAME),@\
+# .init = init_module,@\
+# #ifdef CONFIG_MODULE_UNLOAD@\
+# .exit = cleanup_module,@\
+# #endif@\
+# };@\
+# #endif@\
+# " | tr @ \\n >$$@
+
+
+#$(eval $(call COMPILE_c_o_kern_template,$(1).mod.c,$(1).mod.o,-DKBUILD_MODNAME=$(1)))
+
+$(2)/$(1)$(KERN_LINK_SUFFIX): $$($(1)_OBJS)
+ @$(QUIET_CMD_ECHO) " LD [K] $$@"
+ $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) -r $$($(1)_OBJS) -L$$(kern_GCCLIB_DIR) $$($(1)_LIBS:%=-l%) $$(KERN_LOADLIBES) -Map $(KERN_OBJS_DIR)/$(1).mod.map -o $$@
+ @echo "$(2)/$(1)$(KERN_LINK_SUFFIX): \\" >$(KERN_OBJS_DIR)/$(1).mod.d
+ @sed -n -e 's/^LOAD \(.*\)$$$$/ \1 \\/p' $(KERN_OBJS_DIR)/$(1).mod.map >>$(KERN_OBJS_DIR)/$(1).mod.d
+ @echo >>$(KERN_OBJS_DIR)/$(1).mod.d
+ @if [ "$(KERN_EXE_SUFFIX)" = ".ko" ] ; then \
+ echo $(1) >>$(KERN_MODPOST_DIR)/module-changes ; \
+ echo $(1) >$(KERN_MODPOST_DIR)/$(1).mod.stamp ; \
+ fi
+
+endef
+
+
+
+define LIBRARY_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+$(KERN_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+ @$(QUIET_CMD_ECHO) " AR [K] $$@"
+ $(Q) $(KERN_AR) rcs $$@ $$^
+endef
+
+
+ifdef LINUX_DIR
+
+kernel-lib-pass-local: $(kernel_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+kernel-mod-pass-local: $(kernel_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+$(foreach module,$(kernel_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(kernel_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+
+ifeq ($(CONFIG_RTLINUX),y)
+
+kernel-mod-pass-local: $(rtlinux_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+kernel-lib-pass-local: $(rtlinux_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+$(foreach module,$(rtlinux_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(rtlinux_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+ifeq ($(KERN_MODPOST_PASS),y)
+
+MODULES_LIST := $(wildcard *.mod.stamp)
+MODULES_LIST := $(MODULES_LIST:%.mod.stamp=%)
+
+define MODPOST_kern_template
+$(2) : $(1)$(KERN_LINK_SUFFIX) $(1).mod.c
+ @$(QUIET_CMD_ECHO) " LD [M] $$@"
+ $(Q) $$(cc_o_kern_COMPILE) -D"KBUILD_BASENAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+ -D"KBUILD_MODNAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+ -o $(1).mod.o -c $(1).mod.c
+ $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) $(1)$(KERN_LINK_SUFFIX) $(1).mod.o -r -o $$@
+endef
+
+kernel-modpost-versions: $(wildcard $(LINUX_DIR)/Module.symvers)
+ @$(QUIET_CMD_ECHO) " MODPOST $(KERN_MODPOST_DIR)"
+ @echo >$(KERN_MODPOST_DIR)/modpost-running
+ @rm -f $(KERN_MODPOST_DIR)/module-changes
+ $(Q) $(KERN_MODPOST) $(MODPOST_OPTS) $(MODULES_LIST:%=%$(KERN_LINK_SUFFIX))
+
+$(MODULES_LIST:%=%.mod.c) : kernel-modpost-versions
+
+kernel-modpost-pass-local: $(MODULES_LIST:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX))
+ @rm -f $(KERN_MODPOST_DIR)/modpost-running
+
+$(foreach module,$(MODULES_LIST),$(eval $(call MODPOST_kern_template,$(module),$(module:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX)))))
+
+endif
+
+-include $(KERN_OBJS_DIR)/*.d
+
+endif
+
+#=====================================================================
+
+# Kernel requires its own set of configuration header-files
+ifneq ($(kernel_LIBRARIES)$(rtlinux_LIBRARIES)$(kernel_MODULES)$(rtlinux_MODULES)$(kernel_HEADERS)$(rtlinux_HEADERS)$(kernel_HEADERS)$(rtlinux_HEADERS)$(nobase_kernel_HEADERS)$(nobase_rtlinux_HEADERS)$(renamed_kernel_HEADERS)$(renamed_rtlinux_HEADERS),)
+KERN_CONFIG_HEADERS_REQUIRED = y
+endif
+
+$(eval $(call omk_pass_template, kernel-lib-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_LIBRARIES)$(rtlinux_LIBRARIES)))
+$(eval $(call omk_pass_template, kernel-mod-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_MODULES)$(rtlinux_MODULES)))
+
+kernel-modpost-pass:
+ +@if [ -e "$(KERN_MODPOST_DIR)/module-changes" -o -e "$(KERN_MODPOST_DIR)/modpost-running" ] ; \
+ then \
+ $(MAKE) --no-print-directory -C $(KERN_MODPOST_DIR) \
+ -f $(SOURCES_DIR)/Makefile KERN_RULE_TEMPLATES=y KERN_MODPOST_PASS=y $(@:%=%-local) ; \
+ fi
+
+$(eval $(call omk_pass_template, library-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(lib_LIBRARIES)$(shared_LIBRARIES)))
+$(eval $(call omk_pass_template, binary-pass, $(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(bin_PROGRAMS)$(utils_PROGRAMS)$(test_PROGRAMS)))
+
+$(eval $(call omk_pass_template,clean,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,install,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,include-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,always))
+
+check-dir:
+ @$(call mkdir_def,$(USER_BUILD_DIR))
+ @$(call mkdir_def,$(KERN_BUILD_DIR))
+ @$(call mkdir_def,$(USER_INCLUDE_DIR))
+ @$(call mkdir_def,$(KERN_INCLUDE_DIR))
+ @$(call mkdir_def,$(USER_LIB_DIR))
+ @$(call mkdir_def,$(KERN_LIB_DIR))
+ @$(call mkdir_def,$(USER_BIN_DIR))
+ @$(call mkdir_def,$(USER_UTILS_DIR))
+ @$(call mkdir_def,$(USER_TESTS_DIR))
+ @$(call mkdir_def,$(KERN_MODULES_DIR))
+ @$(call mkdir_def,$(KERN_MODPOST_DIR))
+
+install-local: # TODO
+
+$(eval $(call include-pass-template,$(USER_INCLUDE_DIR),include))
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),kernel))
+ifeq ($(CONFIG_RTLINUX),y)
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),rtlinux))
+endif
+
+
+ifdef USER_RULE_TEMPLATES
+
+# User-space static libraries and applications object files
+
+USER_SOURCES := $(sort $(USER_SOURCES))
+
+USER_GEN_SOURCES := $(sort $(USER_GEN_SOURCES))
+
+#$(warning USER_SOURCES = $(USER_SOURCES))
+
+$(foreach src,$(filter %.c,$(USER_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(USER_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(USER_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+
+$(foreach src,$(filter %.c,$(USER_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.o),)))
+
+# User-space shared libraries object files
+
+SOLIB_SOURCES := $(sort $(SOLIB_SOURCES))
+
+SOLIB_GEN_SOURCES := $(sort $(SOLIB_GEN_SOURCES))
+
+#$(warning SOLIB_SOURCES = $(SOLIB_SOURCES))
+#$(warning SOLIB_GEN_SOURCES = $(SOLIB_GEN_SOURCES))
+
+$(foreach src,$(filter %.c,$(SOLIB_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.cc,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.cxx,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.S,$(SOLIB_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.c,$(SOLIB_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+# IDL compilation
+
+USER_IDLS := $(sort $(USER_IDLS))
+
+$(foreach src,$(filter %.idl,$(USER_IDLS)),$(eval $(call COMPILE_idl_template,$(SOURCES_DIR)/$(src),$(src:%.idl=%))))
+
+endif
+
+ifdef KERN_RULE_TEMPLATES
+
+KERN_SOURCES := $(sort $(KERN_SOURCES))
+
+#$(warning KERN_SOURCES = $(KERN_SOURCES))
+
+$(foreach src,$(filter %.c,$(KERN_SOURCES)),$(eval $(call COMPILE_c_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+endif
+
+clean-local: clean-custom
+ @echo Cleaning in $(KERN_OBJS_DIR) and $(USER_OBJS_DIR)
+ @rm -f $(KERN_OBJS_DIR)/*.o $(USER_OBJS_DIR)/*.[och] $(USER_OBJS_DIR)/*.lo\
+ $(KERN_OBJS_DIR)/*.d $(USER_OBJS_DIR)/*.d \
+ $(KERN_OBJS_DIR)/*.map $(USER_OBJS_DIR)/*.map \
+ $(KERN_OBJS_DIR)/*.mod.c \
+ $(kernel_MODULES:%=$(KERN_MODPOST_DIR)/%.*) \
+ $(LOCAL_CONFIG_H:%=$(KERN_OBJS_DIR)/%) \
+ $(LOCAL_CONFIG_H:%=$(USER_OBJS_DIR)/%)
+ @if [ -e $(KERN_LIB_DIR)/kernel.mk ] ; then \
+ touch -t 200001010101 $(KERN_LIB_DIR)/kernel.mk ; \
+ fi
+
+include-pass-submakes: extra-rules-subdirs
+
+# We must go to EXTRA_RULES_SUBDIRS beofre going to any other
+# directory, since the executables compiled in EXTRA_RULES_SUBDIRS
+# might be needed there.
+include-pass-this-dir $(foreach subdir,$(SUBDIRS),include-pass-$(subdir)-subdir): extra-rules-subdirs
+
+default: include-pass library-pass binary-pass
+ifndef OMIT_KERNEL_PASSES
+# Also make kernel passes if not disabled
+default: kernel-lib-pass kernel-pass
+endif
+
+# Local Variables:
+# mode:makefile
+# End:
+ #OMK@config_h
+# Syntax: $(call BUILD_CONFIG_H_template,<stamp_dir>,<header_file_path>,<list_of_options_to_export>,<header_barrier>)
+define BUILD_CONFIG_H_template
+
+$(addprefix $(1)/,$(notdir $(addsuffix .stamp,$(2)))) : $(CONFIG_FILES)
+ @$(QUIET_CMD_ECHO) " CONFGEN $$(@:%.stamp=%)"
+ @if [ ! -d `dirname $(2).tmp` ] ; then \
+ mkdir -p `dirname $(2).tmp` ; fi
+ @echo "/* Automatically generated from */" > "$(2).tmp"
+ @echo "/* config files: $$(^:$(OUTPUT_DIR)/%=%) */" >> "$(2).tmp"
+ $(if $(DOXYGEN),@echo "/** @file */" >> "$(2).tmp")
+ @echo "#ifndef $(4)" >> "$(2).tmp"
+ @echo "#define $(4)" >> "$(2).tmp"
+ @( $(foreach x, $(shell echo '$($(3))' | tr 'x\t ' 'x\n\n' | sed -e 's/^\([^ =]*\)\(=[^ ]\+\|\)$$/\1/' ), \
+ echo '$(x).$($(x))' ; ) echo ; ) | \
+ sed -e '/^[^.]*\.n$$$$/d' -e '/^[^.]*\.$$$$/d' -e 's/^\([^.]*\)\.[ym]$$$$/\1.1/' | \
+ sed -n -e 's/^\([^.]*\)\.\(.*\)$$$$/#define \1 \2/p' \
+ >> "$(2).tmp"
+ @echo "#endif /*$(4)*/" >> "$(2).tmp"
+ @touch "$$@"
+ @if cmp --quiet "$(2).tmp" "$(2)" ; then rm "$(2).tmp"; \
+ else mv "$(2).tmp" "$(2)" ; \
+ echo "Updated configuration $(2)" ; fi
+
+endef
+
+ifdef LOCAL_CONFIG_H
+
+# This must be declared after the default cflags are assigned!
+# Override is used to override command line assignemnt.
+override CFLAGS += -I $(USER_OBJS_DIR)
+override kernel_INCLUDES += -I $(KERN_OBJS_DIR)
+$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(USER_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+
+endif
+
+# Special rules for configuration exported headers
+
+#FIXME: The directory for headers should not be specified here.
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(addprefix $(USER_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+config_h_stamp_files = $(addprefix $(USER_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(config_h_stamp_files)
+
+ifneq ($(KERN_CONFIG_HEADERS_REQUIRED),)
+
+ifdef LOCAL_CONFIG_H
+$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(KERN_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+endif
+
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(addprefix $(KERN_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+kern_config_h_stamp_files = $(addprefix $(KERN_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(kern_config_h_stamp_files)
+
+endif
+
+clean-local: clean-local-config-h
+
+clean-local-config-h:
+ @$(foreach confh,$(config_h_stamp_files) $(kern_config_h_stamp_files),\
+ if [ -e $(confh) ] ; then rm $(confh) ; fi ; \
+ )
+
+
+# Local Variables:
+# mode:makefile
+# End:
+ #OMK@qt
+ifneq ($(QT_SUBDIRS),)
+
+.PHONY: qt-subpass clean-qt distclean-qt
+
+# Usage: $(call qt_makefile_template,<qt-subdir>)
+define qt_makefile_template
+$(SOURCES_DIR)/$(1)/Makefile: $(wildcard $(SOURCES_DIR)/$(1)/*.pro)
+ cd $(SOURCES_DIR)/$(1); $(QTDIR:%=%/bin/)qmake TOP_DIR=$(OUTPUT_DIR) \
+ RELATIVE_DIR=$(RELATIVE_PREFIX)$(1) $(QTDIR:%=QTDIR=%) CC=$(CC) \
+ CXX=$(CXX) LIBS+="-L$(USER_LIB_DIR)" INCLUDEPATH+="$(USER_INCLUDE_DIR)"
+endef
+$(foreach dir,$(QT_SUBDIRS), $(eval $(call qt_makefile_template,$(dir))))
+
+qt-subpass: $(foreach dir,$(QT_SUBDIRS), $(SOURCES_DIR)/$(dir)/Makefile)
+ $(foreach dir,$(QT_SUBDIRS),\
+ $(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir) \
+ RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir) -C $(SOURCES_DIR)/$(dir) \
+ -f $(SOURCES_DIR)/$(dir)/Makefile || exit 1 ;)
+
+# Hook to binary pass
+binary-pass-submakes: qt-subpass
+
+# Hook to clean pass
+clean-local: clean-qt
+clean-qt:
+ +@$(foreach dir, $(QT_SUBDIRS), \
+ $(if $(wildcard $(SOURCES_DIR)/$(dir)/Makefile), \
+ @$(QUIET_CMD_ECHO) " CLEAN $(dir)"; \
+ $(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir) \
+ RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir) -C $(SOURCES_DIR)/$(dir) \
+ -f $(SOURCES_DIR)/$(dir)/Makefile clean|| exit 1 ;))
+
+
+# Hook to distclean
+distclean: distclean-qt
+
+# TODO: Add distclean-qt-pass to handle QT_SUBDIRS in the whole
+# tree. This way we only distclean toplevel subdirs.
+distclean-qt:
+ +@$(foreach dir, $(QT_SUBDIRS), \
+ $(if $(wildcard $(SOURCES_DIR)/$(dir)/Makefile), \
+ @$(QUIET_CMD_ECHO) " DISTCLEAN $(dir)"; \
+ $(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir) \
+ RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir) -C $(SOURCES_DIR)/$(dir) \
+ -f $(SOURCES_DIR)/$(dir)/Makefile distclean|| exit 1 ;))
+endif
+
+# Local Variables:
+# mode:makefile
+# End:
+ #OMK@sources-list
+# Rules that creates the list of files which are used during
+# compilation. The list reflects conditional compilation depending on
+# config.omk and other variables.
+
+SOURCES_LIST_FN=sources.txt
+ifndef SOURCES_LIST
+SOURCES_LIST_DIR:=$(RELATIVE_DIR)
+SOURCES_LIST:=$(OUTPUT_DIR)/$(SOURCES_LIST_DIR)/$(SOURCES_LIST_FN)
+SOURCES_LIST_D := $(LOCAL_BUILD_DIR)/$(SOURCES_LIST_FN).d
+export SOURCES_LIST SOURCES_LIST_DIR SOURCES_LIST_D
+endif
+
+ifeq ($(MAKECMDGOALS),sources-list)
+NEED_SOURCES_LIST=y
+endif
+ifeq ($(MAKECMDGOALS),TAGS)
+NEED_SOURCES_LIST=y
+endif
+ifeq ($(MAKECMDGOALS),tags)
+NEED_SOURCES_LIST=y
+endif
+
+ifeq ($(NEED_SOURCES_LIST),y) # avoid execution of find command bellow if it is not useful
+.PHONY: sources-list
+sources-list: $(SOURCES_LIST)
+
+$(SOURCES_LIST): $(CONFIG_FILES) $(shell find -name $(MAKEFILE_OMK))
+ @$(call mkdir_def,$(dir $(SOURCES_LIST_D)))
+ @echo -n "" > "$(SOURCES_LIST).tmp"
+ @echo -n "" > "$(SOURCES_LIST_D).tmp"
+ @$(MAKE) --no-print-directory sources-list-pass
+ @echo "# Automatically generated list of files in '$(RELATIVE_DIR)' that are used during OMK compilation" > "$(SOURCES_LIST).tmp2"
+ @cat "$(SOURCES_LIST).tmp"|sort|uniq >> "$(SOURCES_LIST).tmp2"
+ @rm "$(SOURCES_LIST).tmp"
+ @mv "$(SOURCES_LIST).tmp2" "$(SOURCES_LIST)"
+ @echo "$(SOURCES_LIST): \\" > "$(SOURCES_LIST_D).tmp2"
+ @cat "$(SOURCES_LIST_D).tmp"|grep -v "$(SOURCES_LIST_D).tmp"|sort|uniq|\
+ sed -e 's/$$/\\/' >> "$(SOURCES_LIST_D).tmp2"
+ @rm "$(SOURCES_LIST_D).tmp"
+ @mv "$(SOURCES_LIST_D).tmp2" "$(SOURCES_LIST_D)"
+endif
+
+$(eval $(call omk_pass_template,sources-list-pass,$$(LOCAL_BUILD_DIR),,always))
+
+sources-list-pass-local:
+ @$(foreach m,$(MAKEFILE_LIST),echo ' $(m)' >> "$(SOURCES_LIST_D).tmp";)
+ @$(foreach h,$(include_HEADERS) $(nobase_include_HEADERS) $(kernel_HEADERS),\
+ echo "$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))$(h)" >> "$(SOURCES_LIST).tmp";)
+ @$(foreach ch,$(config_include_HEADERS), \
+ echo "$(USER_INCLUDE_DIR:$(OUTPUT_DIR)/$(addsuffix /,$(SOURCES_LIST_DIR))%=%)/$(ch)" >> "$(SOURCES_LIST).tmp";)
+ @$(foreach h,$(renamed_include_HEADERS),echo '$(h)'|sed -e 's|\(.*\)->.*|$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))\1|' >> "$(SOURCES_LIST).tmp";)
+ @$(foreach bin,$(lib_LIBRARIES) $(shared_LIBRARIES) $(bin_PROGRAMS) $(test_PROGRAMS) $(utils_PROGRAMS) \
+ $(kernel_LIBRARIES) $(rtlinux_LIBRARIES) $(kernel_MODULES),\
+ $(foreach src,$(filter-out %.o,$($(bin)_SOURCES)),echo "$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))$(src)" >> "$(SOURCES_LIST).tmp";))
+
+############ TAGS ###########
+
+ifeq ($(MAKECMDGOALS),TAGS)
+ETAGS=etags
+TAGS_CMD = $(ETAGS)
+TAGS: $(SOURCES_LIST)
+ @$(MAKE) --no-print-directory do-tags
+endif
+ifeq ($(MAKECMDGOALS),tags)
+CTAGS=ctags -N
+TAGS_CMD = $(CTAGS)
+tags: $(SOURCES_LIST)
+ @$(MAKE) --no-print-directory do-tags
+endif
+export TAGS_CMD
+
+ifeq ($(MAKECMDGOALS),do-tags)
+.PHONY: do-tags
+do-tags: $(shell sed -e '/^\#/d' $(SOURCES_LIST))
+ @$(QUIET_CMD_ECHO) " TAGS $(SOURCES_LIST_FN)"
+ $(Q)$(TAGS_CMD) $^
+endif
+
+############ CSCOPE ###########
+
+cscope: $(SOURCES_LIST)
+ @$(QUIET_CMD_ECHO) " CSCOPE < $(SOURCES_LIST_FN)"
+ $(Q)sed -e '/^#/d' $(SOURCES_LIST)|cscope -b -i-
+#FIXME: see doc to -i in cscope(1)
+
+# Local Variables:
+# mode:makefile
+# End:
--- /dev/null
+# -*- makefile -*-
+# Config file for compilation by OMK for Marte OS target
+
+# You can override this variable in config.omk
+MARTE_PATH=$(firstword $(wildcard $(HOME)/frescor/marte/ $(HOME)/marte/ /usr/src/marte))
+
+export PLATFORM=MARTE_OS
+
+# Create symbolic links to headers instead of copying them. Useful
+# during development.
+LN_HEADERS=y
+
+# We do not want to overwrite original FRESCOR Makefiles
+USE_LEAF_MAKEFILES=n
+
+########################################
+# Setting of compiler
+########################################
+
+# This doesn't work with MARTE OS 1.7 since mgcc script eats multiple
+# -M options. Current version of mgcc works correctly.
+CC=$(MARTE_PATH)/utils/mgcc
+CFLAGS=-Wall -g -O1 -Wuninitialized -D$(PLATFORM)
+
+ifneq ($(V),2)
+export MGCC_QUIET=y
+endif
+
+# # Instead, with MARTE OS 1.7, we call normal gcc with parameters which mgcc adds
+
+# # List of variables to import from Marte's global.pl
+# MARTE_VARS = MPATH GNAT_PATH ARCH_LD_OPTS CRTI_0 CRTN_O INCLUDES LIBS \
+# LIBS_PATH ARCH_GCC_OPTS WRAPPER_MAIN_C_O \
+# WRAPPER_MAIN_CPP_O _EXIT_O
+
+# # Acquire Marte configuration and store it in marte.mk
+# $(MAKERULES_DIR)/marte.mk: $(MARTE_PATH)/utils/globals.pl
+# @$(QUIET_CMD_ECHO) " CREATE marte.mk"
+# $(Q)perl -e 'require "$(MARTE_PATH)/utils/globals.pl"; foreach (qw/$(MARTE_VARS)/) {print "$$_=$${$$_}\n";}' > $@.tmp
+# $(Q)mv $@.tmp $@
+
+# # Import Marte configuration as make variables
+# -include $(MAKERULES_DIR)/marte.mk
+
+# # Use the compiler configured for Marte
+# CC=$(GNAT_PATH)/../../../../bin/gcc
+
+# distclean: distclean-marte.mk
+# distclean-marte.mk:
+# @$(QUIET_CMD_ECHO) " RM marte.mk"
+# $(Q)rm -f $(MAKERULES_DIR)/marte.mk
+
+# CFLAGS=$(ARCH_GCC_OPTS) -Wall -Wuninitialized -g -gstabs+ -O1 -D$(PLATFORM)
+# LDFLAGS=$(ARCH_LD_OPTS) $(CRTI_0) $(WRAPPER_MAIN_C_O) $(_EXIT_O) $(LIBS_PATH) $(LIBS) $(CRTN_O)
--- /dev/null
+#!/bin/sh
+
+# Usage: ./create-links [path/to/frescor/root]
+#
+# path/to/frescor/root defaults to ../..
+
+LINKS="
+dtm
+fna
+fosa
+frsh
+fsa
+utils
+"
+
+FRESCOR_SRC=${1:-../..}
+
+for link in $LINKS; do
+ ln -s $FRESCOR_SRC/$link .
+done
+
--- /dev/null
+FRSH/FORB 0.1.1
+===============
+
+This is mostly a bug-fix release. The main differences from version
+0.1 are:
+
+- Added frsh_get_local_cpu_id() which returns either compiled in local
+ CPU ID or, if set, the value of FRSH_CPU_ID environment variable.
+ This function is used by CPU resource managers/allocators and should
+ also be used by applications.
+- A few bugs fixed in BFQ, Cgroup and FWP resource managers.
+- Up-to-date Makefile.rules
--- /dev/null
+FRSH/FORB 0.1
+=============
+
+This is the first official release of FRSH/FORB resource reservation
+framework for real-time and distributed applications.
+
+The main differences from the version available at the end of FRESCOR
+project are the following:
+
+- FRSH WLAN Protocol (FWP) was reworked quite a lot.
+ * It contains new version of VRES budgeting which handles correctly
+ all corner cases.
+ * FWP overhead was decreased significantly by allowing sending of
+ packets directly from application threads instead of VRES threads,
+ which are now used only if the budget is exhausted.
+ * Synchronous send operation was implemented.
+ * New application fwp-timing was developed to measure communication
+ delays and packet looses. It showed that the previously mentioned
+ changes improved FWP parameters.
+- FRSH API was slightly changed to remove problematic things.
+ See commit b5508fb2d706b33491fbde62a675432300b43542.
+- Improved logging. Every log message is now prefixed by the name of
+ the process.
+- Several bugs were fixed:
+ * Race condition in registration of allocators.
+ * Incorrect block id in disk BFQ resource
--- /dev/null
+#!/bin/sh
+
+cd ./$(git rev-parse --show-cdup)
+
+if ! git submodule foreach --quiet 'git diff-files --quiet && git diff-index --quiet HEAD'
+then
+ echo >&2 "Submodules are not clean"
+ exit 1
+fi
+
+if ! git diff-files --quiet || ! git diff-index --quiet HEAD
+then
+ echo >&2 "The work tree is not clean"
+ exit 1
+fi
+
+NAME=${NAME:-frsh-forb}
+VERSION=`git describe|sed -e s/^v//`
+
+( git submodule foreach --quiet 'git ls-files|sed -e "s|^|$path/|"'; \
+ git ls-files -s|grep -v ^16|awk '{print $4;}' ) \
+ | grep -v '\(.gitignore\|.gitmodules\)' | \
+tar -czf ${NAME}-${VERSION}.tar.gz --files-from - --transform "s|^\([^\.].*\)|${NAME}-${VERSION}/\1|"
--- /dev/null
+NOTE: The text below develops the terms of the GNU General Public
+ License in detail which serves as the basis for distribution of
+ this software. Please check the source code files themselves
+ for the final exceptions on the GPL license.
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+2008-05-03 10:11 sangorrin
+
+ * Changelog: added Changelog file
+
+2008-05-03 10:10 sangorrin
+
+ * INSTALL, TODO, doc/TODO, src_frescan/TODO, src_frescan/frescan.c,
+ src_frescan/frescan_data.c, src_frescan/frescan_data.h,
+ tests/tests_frescan/test_frescan_send_basic.c,
+ tests/tests_frescan/test_frescan_servers_send_basic.c: added the
+ SRC param for the fragmentation layer and a INSTALL file
+
+2008-04-23 16:09 sangorrin
+
+ * src_frescan/frescan.c, src_frescan/frescan_bwres_messages.c,
+ src_frescan/frescan_config.h: found the bug.. actually it was a
+ very serious bug that affected fragmentation of messages.. i
+ forgot to change in a function that frag_id==0 is not for fp
+ messages anymore.. now frag_id==MX_IDS is for fp messages, so we
+ can use the rest 0..MX_IDS-1 for the servers
+
+2008-04-23 09:23 sangorrin
+
+ * src_frescan/frescan_bwres.c, src_frescan/frescan_bwres.h,
+ src_frescan/frescan_bwres_analysis.c,
+ src_frescan/frescan_bwres_analysis.h,
+ src_frescan/frescan_bwres_messages.c,
+ src_frescan/frescan_bwres_threads.c,
+ tests/tests_frescan/test_frescan_bwres_cancel_in_master.c,
+ tests/tests_frescan/test_frescan_bwres_cancel_in_slave.c,
+ tests/tests_frescan/test_frescan_bwres_renegotiate_in_master.c,
+ tests/tests_frescan/test_frescan_bwres_renegotiate_in_slave.c:
+ added the functions to renegotiate and cancel a contract. TODO:
+ there is a bug when cancelling contracts, reneg async,
+ reserve-commit, spare capacity, measurements
+
+2008-04-22 11:10 sangorrin
+
+ * src_frescan/frescan_bwres_analysis.c,
+ src_frescan/frescan_config.h: make a simplified utilization
+ analysis for the moment
+
+2008-04-22 09:27 sangorrin
+
+ * src_frescan/frescan_bwres.c, src_frescan/frescan_bwres.h,
+ src_frescan/frescan_bwres_analysis.c,
+ src_frescan/frescan_bwres_analysis.h,
+ src_frescan/frescan_bwres_fna.c,
+ src_frescan/frescan_bwres_messages.c,
+ src_frescan/frescan_bwres_requests.h,
+ src_frescan/frescan_bwres_threads.c,
+ src_frescan/frescan_config.h, src_frescan/frescan_data.h,
+ src_frescan/frescan_debug.h,
+ tests/tests_frescan/test_frescan_bwres_init.c,
+ tests/tests_frescan/test_frescan_bwres_negotiate_in_master.c,
+ tests/tests_frescan/test_frescan_bwres_negotiate_in_slave.c: add
+ the infraestructure for storing the negotiated contracts and
+ performing the analysis through the analysis module. TODO:
+ perform a test with those contracts to admit them. In the end the
+ module implementation could be replaced by the cpu
+ implementation.
+ Spare capacity is not done yet. Now we have to implement
+ negotiation and cancel of contracts.
+
+2008-04-21 17:35 sangorrin
+
+ * src_frescan/frescan.c, src_frescan/frescan_data.h,
+ src_frescan/frescan_debug.h, src_frescan/frescan_queues.c,
+ src_frescan/frescan_servers.c,
+ src_frescan/frescan_servers.c_posix,
+ src_frescan/frescan_servers.h,
+ src_frescan/frescan_servers_replenishments.c,
+ src_frescan/frescan_servers_replenishments.c_posix,
+ src_frescan/frescan_servers_replenishments.h: michael found an
+ error in the definition of the posix sporadic servers so i
+ replaced them with new rules designed by michael... I still keep
+ them because they are still analyzable (they dont behave like
+ periodic tasks though) to compare them
+
+2008-04-18 10:50 sangorrin
+
+ * src_frescan/frescan.c, src_frescan/frescan_packets.h,
+ src_frescan/frescan_queues.c,
+ src_frescan/frescan_servers_replenishments.c,
+ src_frescan/frescan_servers_replenishments.h: corrected an error
+ in the sporadic servers... the activation time is the timestamp
+ when the packet is enqueued, not when the frame is sent!!!
+
+2008-04-18 08:50 sangorrin
+
+ * src_frescan/frescan_bwres.c,
+ src_frescan/frescan_bwres_messages.c,
+ src_frescan/frescan_bwres_requests.c,
+ src_frescan/frescan_bwres_threads.c: tested negotiation in slave
+ and in master.. it seems to work good with the new structures
+ too. And its much simpler and clear! wohooo!! TODO: do the
+ scheduling analysis with the API that is already done but for the
+ moment use a utilization analysis, then allow renegotiations and
+ cancelling of contracts... finally implement modifications to the
+ posix sporadic server... do testing, measures and the
+ deliverable... (the spare capacity will have to wait i guess..)
+
+2008-04-17 18:54 sangorrin
+
+ * src_frescan/frescan_bwres.c,
+ src_frescan/frescan_bwres_messages.c,
+ src_frescan/frescan_bwres_messages.h,
+ src_frescan/frescan_bwres_requests.h,
+ src_frescan/frescan_bwres_robjs.c,
+ src_frescan/frescan_bwres_threads.c, src_frescan/frescan_debug.h,
+ src_frescan/frescan_servers_replenishments.c: some
+ reorganization... now the acceptor is simpler.. everything goes
+ through requests and these are sent and received directly through
+ the messages module... TODO: sched analysis, test negotiations,
+ then add renegotiations and cancel..
+
+2008-04-17 15:52 sangorrin
+
+ * src/fna_configuration.c: rename the file
+
+2008-04-17 15:51 sangorrin
+
+ * tests/tests_frescan/Makefile,
+ tests/tests_frescan/test_frescan_bwres_init.c,
+ tests/tests_frescan/test_frescan_bwres_negotiate_in_master.c,
+ tests/tests_frescan/test_frescan_bwres_negotiate_in_slave.c,
+ tests/tests_frescan/test_frescan_bwres_robjs_timedwait.c,
+ tests/tests_frescan/test_frescan_bwres_robjs_wait.c,
+ tests/tests_frescan/test_frescan_replyobj_timedwait.c,
+ tests/tests_frescan/test_frescan_replyobj_wait_signal.c,
+ tests/tests_frescan/test_frescan_servers_send_basic.c: tests
+ adapted to new names.. now the compile.. in makefile i add a
+ target 'tests' to build them all in one shot
+
+2008-04-17 15:31 sangorrin
+
+ * src_frescan/frescan_bwres.c,
+ src_frescan/frescan_bwres_requests.h,
+ src_frescan/frescan_bwres_threads.c, src_frescan/frescan_data.h,
+ src_frescan/frescan_debug.h: updated everything to the new
+ structure... it compiles ok... next step, make sure that the
+ tests compile, then check that the corresponding messages are
+ sent and find possible bugs (very probable to have forgotten some
+ info in the requests..) and then adapt it to do sched analysis
+
+2008-04-17 10:49 sangorrin
+
+ * src_frescan/frescan.c, src_frescan/frescan_bwres.c,
+ src_frescan/frescan_bwres_messages.c,
+ src_frescan/frescan_bwres_messages.h,
+ src_frescan/frescan_bwres_requests.c,
+ src_frescan/frescan_bwres_requests.h,
+ src_frescan/frescan_bwres_robjs.c,
+ src_frescan/frescan_bwres_robjs.h,
+ src_frescan/frescan_bwres_threads.c,
+ src_frescan/frescan_bwres_threads.h, src_frescan/frescan_data.h,
+ src_frescan/frescan_reply_objs.c,
+ src_frescan/frescan_reply_objs.h, src_frescan/frescan_requests.c,
+ src_frescan/frescan_requests.h: renamings... redo the request and
+ messages part... also now there will be two threads in each node
+ like in the dtm... still not compile.. i have to finish it in the
+ afternoon
+
+2008-04-16 15:55 sangorrin
+
+ * src_frescan/frescan.c,
+ src_frescan/frescan_bandwidth_reservation.c,
+ src_frescan/frescan_bandwidth_reservation.h,
+ src_frescan/frescan_bwres.c, src_frescan/frescan_bwres.h,
+ src_frescan/frescan_bwres_analysis.c,
+ src_frescan/frescan_bwres_analysis.h,
+ src_frescan/frescan_bwres_fna.c, src_frescan/frescan_bwres_fna.h,
+ src_frescan/frescan_bwres_frsh_fna.c,
+ src_frescan/frescan_bwres_messages.c,
+ src_frescan/frescan_bwres_messages.h,
+ src_frescan/frescan_bwres_threads.c,
+ src_frescan/frescan_bwres_threads.h, src_frescan/frescan_fna.c,
+ src_frescan/frescan_fna.h, src_frescan/frescan_frsh_fna.c,
+ src_frescan/frescan_negotiation_messages.c,
+ src_frescan/frescan_negotiation_messages.h,
+ src_frescan/frescan_negotiation_threads.c,
+ src_frescan/frescan_negotiation_threads.h,
+ src_frescan/frescan_reply_objects.c,
+ src_frescan/frescan_reply_objects.h,
+ src_frescan/frescan_reply_objs.c,
+ src_frescan/frescan_reply_objs.h, src_frescan/frescan_requests.c,
+ src_frescan/frescan_requests.h,
+ src_frescan/frescan_requests_queue.c,
+ src_frescan/frescan_requests_queue.h,
+ src_frescan/frescan_sched_analysis.c,
+ src_frescan/frescan_sched_analysis.h: renaming
+
+2008-04-16 15:27 sangorrin
+
+ * src_frescan/frescan_bandwidth_reservation.c,
+ src_frescan/frescan_data.h,
+ src_frescan/frescan_negotiation_messages.c,
+ src_frescan/frescan_negotiation_messages.h,
+ src_frescan/frescan_queues.c,
+ src_frescan/frescan_requests_queue.c,
+ src_frescan/frescan_requests_queue.h: i break the svn for one day
+ to change the name of files, redo the negotiation messages system
+ and implement renegotiations and canceling of contracts
+
+2008-04-15 11:47 sangorrin
+
+ * tests/tests_frescan/test_frescan_servers_send_basic.c: update
+ values
+
+2008-04-15 11:42 sangorrin
+
+ * src_frescan/frescan_queues.c: add a lock for the queue structures
+ when dequeued, for th moment is hardwired to network 0
+
+2008-04-15 11:42 sangorrin
+
+ * src_frescan/frescan.c: this lock was wrong.. it worked because of
+ an error in marte os: if u block after enter in the critical
+ section, the idle task enters unblocking the irqs again. An error
+ should be returned i think
+
+2008-04-15 08:51 sangorrin
+
+ * src_frescan/frescan_negotiation_messages.c: lock for the (future)
+ negotiation
+
+2008-04-15 08:51 sangorrin
+
+ * src_frescan/frescan_negotiation_threads.c: net
+
+2008-04-15 08:50 sangorrin
+
+ * src_frescan/frescan_servers.c: locks for server functions
+
+2008-04-15 08:20 sangorrin
+
+ * src_frescan/TODO, src_frescan/frescan_sched_analysis.c,
+ src_frescan/frescan_sched_analysis.h: add the modules for the
+ frescan sched analysis with an initial API that we are discussing
+ at the moment so it might change soon... it is not applied yet..
+ TODO: we will need new messages for the spare capacity
+ distribution and structures to apply them at the right moment..
+ this is also ongoing work and research must be done on when is
+ the right moment.
+
+2008-04-15 07:47 sangorrin
+
+ * src_frescan/frescan_bandwidth_reservation.c,
+ src_frescan/frescan_data.h: update the names and add acceptor
+ thread id to the general data
+
+2008-04-15 07:44 sangorrin
+
+ * src_frescan/frescan_acceptor_threads.c,
+ src_frescan/frescan_acceptor_threads.h,
+ src_frescan/frescan_negotiation_threads.c,
+ src_frescan/frescan_negotiation_threads.h,
+ src_frescan/frescan_negotiator_thread.c,
+ src_frescan/frescan_negotiator_thread.h: renaming to neg threads
+
+2008-04-15 07:43 sangorrin
+
+ * src_frescan/frescan_acceptor_threads.c,
+ src_frescan/frescan_acceptor_threads.h: joining threads module
+
+2008-04-14 16:58 sangorrin
+
+ * src_frescan/TODO, src_frescan/frescan.c,
+ src_frescan/frescan_debug.h, src_frescan/frescan_hw_buffer.c:
+ abort when higher prio frame
+
+2008-04-09 11:19 sangorrin
+
+ * tests/tests_frescan/test_frescan_servers_send_receive_measures.c:
+ add a test to obtain measures of a round trip
+
+2008-04-09 11:19 sangorrin
+
+ * rules.mk: apps need to link to libfosa too
+
+2008-04-08 15:37 sangorrin
+
+ * config.mk_example: network enabling is now in fna_configuration.h
+
+2008-04-08 15:37 sangorrin
+
+ * src_frescan/frescan_servers_replenishments.c: initialize pointer
+ to null to avoid warning.. this is because the compiler does not
+ know that im checking that a list is not empty before using it
+ etc..
+
+2008-04-08 15:36 sangorrin
+
+ * src_frescan/frescan_requests_queue.c: initialize pointer to null
+ to avoid warning.. this is because the compiler does not know
+ that im checking that a list is not empty before using it etc..
+
+2008-04-08 15:36 sangorrin
+
+ * src_frescan/frescan_queues.c: initialize pointer to null to avoid
+ warning.. this is because the compiler does not know that im
+ checking that a list is not empty before using it etc..
+
+2008-04-08 15:35 sangorrin
+
+ * src_frescan/frescan_negotiator_thread.c: create a server in the
+ negotiator thread... this thread should be renamed to MASTER
+ local negotiator thread or sth like that cause the rest of
+ negotiations are performed by the acceptor thread.. which also
+ should be renamed to SLAVE negotiations or sth like that
+
+2008-04-08 15:34 sangorrin
+
+ * src_frescan/frescan_fna.c: implement send and receive in fna and
+ bytes<->budget conversion functions... the test is in
+ frsh/tests_distributed/test send receive basic
+
+2008-04-08 15:33 sangorrin
+
+ * src_frescan/frescan_config.h: put neg channel to 0 by default so
+ i dont forget it
+
+2008-04-08 15:32 sangorrin
+
+ * include/frsh_fna.h: tab
+
+2008-04-08 15:32 sangorrin
+
+ * include/fna_configuration.h: networks are enabled in
+ fna_configuration.h now, not in CFLAGS... i keep the enables in
+ config.mk for the moment but just rules.mk to know which
+ directories should be compiled... with the future omk system i
+ guess this is easier
+
+2008-04-08 08:45 sangorrin
+
+ * tests/tests_frescan/Makefile: now libfrescan.o instead of .a
+
+2008-04-08 08:45 sangorrin
+
+ * src_frescan/Makefile: now libfrescan is a relocatable object file
+ instead of a library .a
+
+2008-04-08 08:44 sangorrin
+
+ * src_frescan/frescan_fna.c, src_frescan/frescan_fna.h,
+ src_frescan/frescan_frsh_fna.c: added fna files, starting its
+ implementation, the rest return an error and write not
+ implemented so far
+
+2008-04-08 08:44 sangorrin
+
+ * src_frescan/frescan_debug.h: add flag for debugging frescan fna
+ layer
+
+2008-04-08 08:44 sangorrin
+
+ * src/fna_configuration.c: add frescan operations
+
+2008-04-08 08:43 sangorrin
+
+ * include/frsh_fna.h: add prototypes for frescan
+
+2008-04-08 08:43 sangorrin
+
+ * config.mk_example: now im working on frescan.. ill update rtep if
+ i broke the compilation later
+
+2008-04-08 08:42 sangorrin
+
+ * rules.mk: now all will be included in libfna.a, the rest will be
+ relocatable linked objects
+
+2008-04-07 15:58 sangorrin
+
+ * tests/tests_rtep_fna/Makefile,
+ tests/tests_rtep_fna/test_c_rtep_fna.c,
+ tests/tests_rtep_fna/test_c_rtep_fna_measurement.c,
+ tests/tests_rtep_fna/test_c_rtep_fna_with_frsh.c,
+ tests/tests_rtep_fna/test_c_rtep_frsh_fna.c: use frsh.h only,
+ headers mess otherwise
+
+2008-04-07 15:49 sangorrin
+
+ * include/fna.h, include/frsh_fna.h: include frsh.h to include
+ everything because there were headers problems and miguel has
+ thought it to include only this file
+
+2008-04-07 15:48 sangorrin
+
+ * src_rtep/Makefile, src_rtep/rtep_fna_c.c: frsh_freelist is now
+ part of utils as fadt_freelist
+
+2008-04-07 15:47 sangorrin
+
+ * config.mk_example, rules.mk: utils
+
+2008-04-07 08:22 sangorrin
+
+ * tests/tests_frescan/test_frescan_bwres_negotiate_in_slave.c: neg
+ in slave, receive results
+
+2008-04-07 08:21 sangorrin
+
+ * src_frescan/frescan_bandwidth_reservation.c,
+ src_frescan/frescan_data.h,
+ src_frescan/frescan_negotiation_messages.c,
+ src_frescan/frescan_negotiation_messages.h,
+ src_frescan/frescan_servers.c,
+ src_frescan/frescan_servers_replenishments.c: negotiation reply
+ (TODO: integrate the scheduling test component)
+
+2008-04-03 16:04 sangorrin
+
+ * src_frescan/frescan.c, src_frescan/frescan_acceptor_threads.c,
+ src_frescan/frescan_acceptor_threads.h,
+ src_frescan/frescan_bandwidth_reservation.c,
+ src_frescan/frescan_config.h, src_frescan/frescan_data.h,
+ src_frescan/frescan_debug.h,
+ src_frescan/frescan_negotiation_messages.c,
+ src_frescan/frescan_negotiation_messages.h,
+ src_frescan/frescan_negotiator_thread.c,
+ src_frescan/frescan_requests_queue.c,
+ src_frescan/frescan_requests_queue.h,
+ tests/tests_frescan/test_frescan_bwres_negotiate_in_master.c,
+ tests/tests_frescan/test_frescan_bwres_negotiate_in_slave.c,
+ tests/tests_frescan/test_frescan_send_basic.c: negotiation
+ messages, so far a slave call negotiate which sends a negotiate
+ msg which arrives to the master and sends a reply
+
+2008-04-01 16:09 sangorrin
+
+ * tests/tests_frescan/test_frescan_bwres_init.c,
+ tests/tests_frescan/test_frescan_bwres_negotiate_in_master.c,
+ tests/tests_frescan/test_frescan_init.c,
+ tests/tests_frescan/test_frescan_send_basic.c,
+ tests/tests_frescan/test_frescan_servers_send_basic.c: tests for
+ bwres basic
+
+2008-04-01 16:09 sangorrin
+
+ * src_frescan/frescan.c,
+ src_frescan/frescan_bandwidth_reservation.c,
+ src_frescan/frescan_bandwidth_reservation.h,
+ src_frescan/frescan_config.h, src_frescan/frescan_data.h,
+ src_frescan/frescan_debug.h,
+ src_frescan/frescan_negotiator_thread.c,
+ src_frescan/frescan_negotiator_thread.h,
+ src_frescan/frescan_requests_queue.c,
+ src_frescan/frescan_requests_queue.h,
+ src_frescan/frescan_servers_replenishments.c: negotiator thread
+ and bwres layer
+
+2008-04-01 09:55 sangorrin
+
+ * tests/tests_frescan/Makefile: makefile for the tests
+
+2008-04-01 09:55 sangorrin
+
+ * tests/tests_frescan/test_frescan_replyobj_timedwait.c,
+ tests/tests_frescan/test_frescan_replyobj_wait_signal.c: some
+ tests
+
+2008-04-01 09:55 sangorrin
+
+ * src_frescan/frescan.c, src_frescan/frescan.h,
+ src_frescan/frescan_config.h, src_frescan/frescan_data.h,
+ src_frescan/frescan_hw_buffer.h, src_frescan/frescan_packets.h,
+ src_frescan/frescan_queues.h,
+ src_frescan/frescan_reply_objects.c,
+ src_frescan/frescan_reply_objects.h,
+ src_frescan/frescan_requests_queue.c,
+ src_frescan/frescan_requests_queue.h,
+ src_frescan/frescan_servers.h,
+ src_frescan/frescan_servers_replenishments.h: starting to build
+ the negotiations infrastructure
+
+2008-03-31 11:21 sangorrin
+
+ * config.mk_example, src_frescan/Makefile: frescan compiles
+
+2008-03-31 11:16 sangorrin
+
+ * doc/TODO, rules.mk, src/fna_configuration.c,
+ src_frescan/Makefile, src_frescan/frescan_config.h,
+ src_frescan/frescan_data.h,
+ src_frescan/frescan_servers_replenishments.c,
+ src_frescan/test_frescan_init.c,
+ src_frescan/test_frescan_queues.c,
+ src_frescan/test_frescan_send_basic.c,
+ src_frescan/test_frescan_servers_send_basic.c,
+ tests/tests_frescan, tests/tests_frescan/test_frescan_init.c,
+ tests/tests_frescan/test_frescan_queues.c,
+ tests/tests_frescan/test_frescan_send_basic.c,
+ tests/tests_frescan/test_frescan_servers_send_basic.c: starting
+ adaptation to fosa of frescan.. some reordering..
+
+2008-03-31 10:24 sangorrin
+
+ * src_frescan, src_frescan/Makefile, src_frescan/README,
+ src_frescan/frescan.c, src_frescan/frescan_config.h,
+ src_frescan/frescan_data.c, src_frescan/frescan_data.h,
+ src_frescan/frescan_debug.h, src_frescan/frescan_hw_buffer.c,
+ src_frescan/frescan_hw_buffer.h, src_frescan/frescan_id.c,
+ src_frescan/frescan_id.h, src_frescan/frescan_packets.c,
+ src_frescan/frescan_packets.h, src_frescan/frescan_queues.c,
+ src_frescan/frescan_queues.h, src_frescan/frescan_servers.c,
+ src_frescan/frescan_servers.h,
+ src_frescan/frescan_servers_replenishments.c,
+ src_frescan/frescan_servers_replenishments.h,
+ src_frescan/test_frescan_init.c,
+ src_frescan/test_frescan_queues.c,
+ src_frescan/test_frescan_send_basic.c,
+ src_frescan/test_frescan_servers_send_basic.c: added frescan
+ sources
+
+2008-01-03 11:00 sangorrin
+
+ * tests/tests_rtep_fna/test_c_rtep_fna_measurement.c: changed to N
+ measures
+
+2008-01-03 10:59 sangorrin
+
+ * src_rtep/rtep_fna_c.c: added send sync operation
+
+2007-12-13 11:58 sangorrin
+
+ * Makefile, src_rtep/rtep_fna_c.c: some debugging flags and the
+ target of the makefile
+
+2007-12-11 11:06 sangorrin
+
+ * tests/tests_rtep_fna/test_c_rtep_fna_measurement.c: new test for
+ measuring the neg time in rtep fna
+
+2007-12-11 11:05 sangorrin
+
+ * rules.mk, tests/tests_rtep_fna/Makefile: makefile changes
+
+2007-11-27 17:53 sangorrin
+
+ * src_rtep/rtep_fna_c.c: debug flags
+
+2007-11-26 12:06 sangorrin
+
+ * tests/qemu: no qemu image in svn
+
+2007-11-26 12:04 sangorrin
+
+ * config.mk_example, src/fna_configuration.c,
+ tests/tests_rtep_fna/test_c_rtep_fna_with_frsh.c: backup
+
+2007-10-31 12:28 sangorrin
+
+ * src_unix/unix_fna.c, src_unix/unix_fna.h,
+ tests/tests_unix_fna/Makefile,
+ tests/tests_unix_fna/test_unix_address.c,
+ tests/tests_unix_fna/test_unix_fna_send_receive.c,
+ tests/tests_unix_fna/test_unix_fna_send_receive_script: change to
+ unix fna, now we encode streams... but i found a problem in dtm
+ so it wont be useful because multithreaded apps in linux_lib_arch
+ cannot sleep
+
+2007-10-29 18:17 sangorrin
+
+ * src_unix/unix_fna.c: debug function
+
+2007-10-29 10:38 sangorrin
+
+ * include/fna.h, src_rtep/rtep_fna_c.c, src_unix/unix_fna.c,
+ src_unix/unix_fna.h,
+ tests/tests_unix_fna/test_unix_fna_send_receive.c,
+ tests/tests_unix_fna/test_unix_send_receive.c: unix fna, it seems
+ to work
+
+2007-10-26 17:46 sangorrin
+
+ * config.mk_example, include/frsh_fna.h, rules.mk,
+ src/fna_configuration.c, src_unix/unix_fna.c,
+ src_unix/unix_fna.h, tests/tests_rtep_fna/test_c_rtep_fna.c,
+ tests/tests_unix_fna, tests/tests_unix_fna/Makefile,
+ tests/tests_unix_fna/test_unix_fna_send_receive.c,
+ tests/tests_unix_fna/test_unix_send_receive.c: preparing to do
+ unix fna
+
+2007-10-26 10:23 sangorrin
+
+ * config.mk_example, rules.mk, src/fna_configuration.c, src_unix,
+ src_unix/Makefile, src_unix/unix_fna.c, src_unix/unix_fna.h,
+ tests, tests/qemu, tests/qemu/Makefile, tests/qemu/base_disk.img,
+ tests/qemu/mkvirtualdisk, tests/qemu/mnt, tests/tests_rtep_fna,
+ tests/tests_rtep_fna/Makefile,
+ tests/tests_rtep_fna/test_c_rtep_fna.c,
+ tests/tests_rtep_fna/test_c_rtep_fna_with_frsh.c,
+ tests/tests_rtep_fna/test_c_rtep_frsh_fna.c: start to do the unix
+ fna
+
+2007-10-26 09:31 sangorrin
+
+ * src_rtep/tests:
+
+2007-10-19 11:44 sangorrin
+
+ * config.mk_example: config
+
+2007-10-19 11:43 sangorrin
+
+ * include/fna_configuration.h: rtep is defined in config.mk
+
+2007-10-19 11:43 sangorrin
+
+ * rules.mk: ifdef rtep
+
+2007-10-19 10:22 sangorrin
+
+ * src/fna_configuration.c: define rtep
+
+2007-10-19 10:22 sangorrin
+
+ * include/fna_configuration.h: define rtep
+
+2007-10-19 09:22 sangorrin
+
+ * src_rtep/tests/Makefile: new makefile
+
+2007-10-19 09:22 sangorrin
+
+ * src_rtep/Makefile: clean images in tests
+
+2007-10-19 09:20 sangorrin
+
+ * src_rtep/Makefile: makefile update
+
+2007-10-19 09:20 sangorrin
+
+ * src_rtep/rtep_fna_c.c: the table is now in fna_configuration.c
+
+2007-10-19 09:20 sangorrin
+
+ * Makefile, config.mk_example, rules.mk: new makefile system
+
+2007-10-19 09:19 sangorrin
+
+ * src, src/Makefile, src/fna_configuration.c: to store the fna
+ table
+
+2007-10-19 09:18 sangorrin
+
+ * include/frsh_fna.h: no elif
+
+2007-10-19 09:18 sangorrin
+
+ * include/fna_configuration.h: define rtep
+
+2007-10-19 09:15 sangorrin
+
+ * doc/license_fna.txt: que no
+
+2007-09-28 11:44 telleriam
+
+ * doc/license_fna.txt, include/fna.h, include/fna_configuration.h,
+ include/frsh_fna.h, src_rtep/rtep_fna.h, src_rtep/rtep_fna_c.c,
+ src_rtep/rtep_frsh_fna_c.c, src_rtep/tests/test_c_rtep_fna.c,
+ src_rtep/tests/test_c_rtep_fna_with_frsh.c,
+ src_rtep/tests/test_c_rtep_frsh_fna.c: Global update in FNA to
+ update license text
+
+2007-09-06 15:15 sangorrin
+
+ * src_rtep/rtep_fna_c.c: no messages
+
+2007-09-03 17:38 sangorrin
+
+ * src_rtep/tests/Makefile, src_rtep/tests/test_c_frsh.c,
+ src_rtep/tests/test_c_rtep_fna.c.old: makefile with frsh
+
+2007-09-03 17:38 sangorrin
+
+ * src_rtep/tests/test_c_rtep_fna.c: send receive
+
+2007-09-03 17:37 sangorrin
+
+ * src_rtep/tests/test_c_rtep_fna_with_frsh.c: check fna with frsh
+ running
+
+2007-09-03 17:37 sangorrin
+
+ * src_rtep/tests/test_c_rtep_frsh_fna.c: comment until implemented
+
+2007-09-03 17:36 sangorrin
+
+ * src_rtep/rtep_fna_c.c: chan
+
+2007-08-10 17:05 sangorrin
+
+ * src_rtep/rtep_fna_c.c: renegotiate_sync
+
+2007-08-09 11:47 sangorrin
+
+ * src_rtep/Makefile, src_rtep/rtep_fna.h, src_rtep/rtep_fna_c.c,
+ src_rtep/rtep_frsh_fna_c.c, src_rtep/tests/Makefile,
+ src_rtep/tests/test_c_rtep_fna.c,
+ src_rtep/tests/test_c_rtep_frsh_fna.c: big commint with a lot of
+ changes, see files
+
+2007-08-09 11:46 sangorrin
+
+ * lib: lib for rtepfna
+
+2007-08-09 11:40 sangorrin
+
+ * include/fna.h, include/fna_configuration.h: hooks for fna
+
+2007-08-02 10:23 sangorrin
+
+ * src_rtep/tests/test_c_rtep_fna.c,
+ src_rtep/tests/test_c_rtep_frsh_fna.c: assert
+
+2007-06-25 15:34 sangorrin
+
+ * src_rtep/Makefile, src_rtep/rtep_fna_c.c,
+ src_rtep/rtep_frsh_fna_c.c, src_rtep/tests,
+ src_rtep/tests/Makefile, src_rtep/tests/base_disk.img,
+ src_rtep/tests/mkvirtualdisk, src_rtep/tests/mnt,
+ src_rtep/tests/test_c_frsh.c, src_rtep/tests/test_c_rtep_fna.c,
+ src_rtep/tests/test_c_rtep_fna.c.old,
+ src_rtep/tests/test_c_rtep_frsh_fna.c: fna tests
+
+2007-06-25 15:32 sangorrin
+
+ * include/fna.h, include/frsh_fna.h, src, src_rtep:
+
+2007-06-19 07:46 sangorrin
+
+ * include/fna.h: i add FROM when receiving
+
+2007-05-15 17:40 sangorrin
+
+ * doc/api_fna_html.tar.gz, doc/fna-refman.pdf: update doc
+
+2007-03-22 10:33 sangorrin
+
+ * include/fna.h: create_callback
+
+2007-03-20 17:27 sangorrin
+
+ * include/fna.h: maxsize
+
+2007-03-20 10:27 sangorrin
+
+ * doc/api_fna_html.tar.gz, doc/fna-refman.pdf: doc update
+
+2007-03-20 10:26 sangorrin
+
+ * include/fna.h: correct network functions
+
+2007-03-19 16:16 sangorrin
+
+ * include/fna.h: functions to map bytes to budgets changed and a
+ new function for effective budget
+
+2007-03-14 18:03 sangorrin
+
+ * doc/api_fna_html.tar.gz, doc/fna-refman.pdf, include/fna.h:
+ Changes in names of spare capacity functions. Change in
+ message_get_tx_time (tx_time is the physical time without
+ overheads)
+
+2007-03-13 18:16 sangorrin
+
+ * doc/api_fna_html.tar.gz, doc/fna-refman.pdf: update doc
+
+2007-03-13 11:20 sangorrin
+
+ * include/fna.h: changes in get_status functions and add receive
+ create endpoint
+
+2007-03-09 09:11 sangorrin
+
+ * COPYING, README, doc/TODO: copying, readme, todo..
+
+2007-03-09 09:04 sangorrin
+
+ * ftt-se_fna, rtep_fna, src: src is source common for all
+ protocols. each protocol has its source in its own dir
+
+2007-03-09 08:53 sangorrin
+
+ * ftt-se_fna, rtep_fna, src_ftt-se, src_rtep: change source names
+ because they don't contain the whole code of the protocols
+
+2007-03-07 09:30 sangorrin
+
+ * doc, doc/api_fna_html.tar.gz, doc/fna-refman.pdf, include,
+ include/fna.h, include/frsh_fna.h, src_ftt-se, src_rtep: first
+ upload of fna
+
+2007-03-07 09:19 sangorrin
+
+ * .: creating trunk
+
--- /dev/null
+INSTALL
+=======
+
+1.- Enable / Disable the FNA modules (RT-EP, FRESCAN, etc..) in the config.mk and in
+ the fna_configuration.h files
+
+2.- Compile the FNA library with 'make'
+
+3.- Build and example from the 'tests/' directory (i.e.: make test_frescan_send_basic.exe)
+
+4.- Tests using the modules from FRSH distributed interface are located at 'tests/tests_distributed'
+ in the FRSH module, not in FNA.
+
--- /dev/null
+all: libfna
+include config.mk
+include rules.mk
+
+
--- /dev/null
+SUBDIRS=include
+
+default_CONFIG = CONFIG_FNA_RTEP=n CONFIG_FNA_UNIX=n CONFIG_FNA_FRESCAN=n
+
+lib_LIBRARIES = fna
+fna_SOURCES = src/fna_configuration.c
+
+ifeq ($(CONFIG_FNA_RTEP),y)
+SUBDIRS+=src_rtep
+CFLAGS+=-DRTEP_FNA_ENABLED
+endif
+
+ifeq ($(CONFIG_FNA_UNIX),y)
+SUBDIRS+=src_unix
+CFLAGS+=-DUNIX_FNA_ENABLED
+endif
+
+ifeq ($(CONFIG_FNA_FRESCAN),y)
+SUBDIRS+=src_frescan
+CFLAGS+=-DFRESCAN_FNA_ENABLED
+endif
+
+ifeq ($(CONFIG_FWP),y)
+CFLAGS+=-DFWP_FNA_ENABLED
+endif
--- /dev/null
+FNA
+=====================
+Name:
+FNA
+
+Version:
+May 2008
+
+Status:
+Alpha
+
+Authors:
+Daniel Sangorrin [daniel.sangorrin@unican.es] (UC),
+Michael Gonzalez Harbour [mgh@unican.es] (UC)
+Martin Molnar (CTU)
+Michal Sojka (CTU)
+
+Licence:
+FRESCOR Lincece (see COPYING)
+
+Brief description:
+This is FNA (Frescor Network Adaptation layer) module, the layer that allows
+to plug-in different network protocols to FRESCOR by means of a clear interface.
+
+URL:
+svn co http://www.frescor.org/private/svn/frescor/fna/trunk/
+
+Bugs:
+See TODO
+
+Description:
+
+This is FNA (Frescor Network Adaptation layer) module, the layer that allows
+to plug-in different network protocols to FRESCOR by means of a clear interface.
+
+- README: This file
+
+- COPYING: FRESCOR license
+
+- INSTALL: Installation instructions
+
+- include/: FNA API C header files.
+
+- src/ : source code of FNA that is common to all protocols
+
+- src_xxx/ : source code of 'xxx' protocols
+
+- doc/: documentation directory
--- /dev/null
+* rtep spare capacity
+* make the unix platform working with a linux external thread
+* finish frescan
+
--- /dev/null
+# Platform: MARTE_OS, DUMMY_OS, RT_LINUX, OSE, AQuoSA
+PLATFORM = MARTE_OS
+PLATFORM_PATH = $(HOME)/marte
+EXPORT_PATH = $(HOME)/export
+
+# utilization or response time
+SA_VERSION = utilization
+
+# the gcc to use
+CC = mgcc
+
+FRESCOR_ROOT = $(HOME)/frescor
+FRSH_PATH = $(FRESCOR_ROOT)/frsh
+FOSA_PATH = $(FRESCOR_ROOT)/fosa
+FNA_PATH = $(FRESCOR_ROOT)/fna
+UTILS_PATH = $(FRESCOR_ROOT)/utils
+FSA_PATH = $(FRESCOR_ROOT)/fsa
+
+# the compilation flags
+CFLAGS = -Wall -g -O1 -Wuninitialized \
+ -D$(PLATFORM) \
+ -I$(FNA_PATH)/include \
+ -I$(FRSH_PATH)/include \
+ -I$(FOSA_PATH)/include \
+ -I$(UTILS_PATH)/include \
+ -I$(FSA_PATH)/include
+
+
+# fna networks configuration
+CONFIG_FNA_RTEP=n
+CONFIG_FNA_UNIX=n
+CONFIG_FNA_FRESCAN=n
+CONFIG_FWP=n
+
+ifeq ($(CONFIG_FNA_RTEP),y)
+CFLAGS += -DRTEP_FNA_ENABLED -I$(FNA_PATH)/src_rtep/ -I$(PLATFORM_PATH)/arch/drivers/rt-ep/
+endif
+
+ifeq ($(CONFIG_FNA_UNIX),y)
+CFLAGS += -DUNIX_FNA_ENABLED
+endif
+
+ifeq ($(CONFIG_FNA_FRESCAN),y)
+CFLAGS += -DFRESCAN_FNA_ENABLED -I$(FNA_PATH)/src_frescan/
+endif
+
+ifeq ($(CONFIG_FWP),y)
+CFLAGS += -DFWP_FNA_ENABLED
+endif
+
+# fna network connected
+CONFIG_FNA_RTEP_CONNECTED=n
+CONFIG_FNA_UNIX_CONNECTED=n
+CONFIG_FNA_FRESCAN_CONNECTED=n
+CONFIG_FWP_CONNECTED=n
+
+ifeq ($(CONFIG_FNA_RTEP_CONNECTED),y)
+CFLAGS += -DCONFIG_FNA_RTEP_CONNECTED
+endif
+
+ifeq ($(CONFIG_FNA_UNIX_CONNECTED),y)
+CFLAGS += -DCONFIG_FNA_UNIX_CONNECTED
+endif
+
+ifeq ($(CONFIG_FNA_FRESCAN_CONNECTED),y)
+CFLAGS += -DCONFIG_FNA_FRESCAN_CONNECTED
+endif
+
+ifeq ($(CONFIG_FWP_CONNECTED),y)
+CFLAGS += -DCONFIG_FWP_CONNECTED
+endif
+
+# the library flags
+LDFLAGS = -L$(FRSH_PATH)/lib -L$(FSA_PATH)/lib -L$(FOSA_PATH)/lib \
+ -L$(UTILS_PATH)/lib -L$(FNA_PATH)/lib
+
+LDFLAGS += -Wl,--start-group -lfrsh -lfsa_$(SA_VERSION) -lfosa_$(PLATFORM) -lutils -lfna -lm
+LDFLAGS += -Wl,--end-group
--- /dev/null
+include_HEADERS = $(notdir $(wildcard $(SOURCES_DIR)/*.h))
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+// ******** **** ** **
+// **///// /**/** /** ****
+// ** /**//** /** **//**
+// ******* /** //** /** ** //**
+// **//// /** //**/** **********
+// ** /** //****/**//////**
+// ** /** //***/** /**
+// / // /// // //
+//
+// FNA(Frescor Network Adaptation layer), pronounced "efe ene a"
+//==============================================================
+
+#ifndef _FNA_H_
+#define _FNA_H_
+
+/* for frsh_resource_id_t, frsh_contract_t, for frsh_network_address_t,
+ frsh_stream_id_t, ... */
+#include "frsh.h"
+/* for timespec */
+#include <time.h>
+/* for ERROR constants */
+// #include "fna_error.h"
+/* for uint32_t, UINT32_MAX */
+#include <stdint.h>
+
+/**
+ * @defgroup fna FNA Private Interface
+ *
+ * FNA is a Network adaption layer that allows to plugin new
+ * network protocols to the distributed module.
+ *
+ * It is divided in two parts:
+ * - FRSH_FNA: public types and functions for the FRSH API
+ * - FNA: private functions only used within FRSH.
+ *
+ **/
+
+
+//////////////////////////////////////////////////////////////////////
+// INITIALIZATION
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup fnainit FNA Initialization
+ * @ingroup fna
+ *
+ * These functions need to be called before using any network
+ *
+ * @{
+ **/
+
+/**
+ * fna_init()
+ *
+ * This function will be hooked to the frsh_init function and it is
+ * intented to initialize the protocol and its structures.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_ALREADY_INITIALIZED:
+ * if the function has already been called before (with success) \n
+ *
+ **/
+typedef int fna_init_t(const frsh_resource_id_t resource_id);
+
+/*@}*/
+
+///////////////////////////////////////////////////////////////////
+// VIRTUAL RESOURCES
+///////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup fnavres FNA Virtual Resources
+ * @ingroup fna
+ *
+ * The following functions are used to negotiate, renegotiate and cancel
+ * virtual network resources.
+ *
+ * @{
+ **/
+
+#ifndef FRSH_FORB
+/**
+ * fna_vres_id_t
+ *
+ * Internal virtual resource id. In the current implementation it is a 16 bits
+ * value (up to 65536 vres) so it can be integrated easily with the
+ * frsh_vres_id_t type (see frsh_internal_data.h)
+ *
+ **/
+typedef uint16_t fna_vres_id_t;
+#else
+/**
+ * In FRSH_FORB implementation, we do not distinguish between vreses
+ * of different resources.
+ */
+typedef frsh_vres_id_t fna_vres_id_t;
+#endif
+
+typedef struct {
+ int size;
+ fna_vres_id_t vres[FRSH_MAX_GROUP_OPS];
+} fna_vres_group_t;
+
+/**
+ * frsh_group_change_mode_sync()
+ *
+ * This function performs a set of negotiation operations which can
+ * include: adding new contracts (neg), modifying existing vres (reneg)
+ * or cancelling existing vres (cancel).
+ *
+ * If one of the group operations has a NULL value, unless it causes an
+ * inconsistency the system will suppose that no operation of that
+ * type (neg, reneg or cancel) should be done.
+ *
+ * The virtual resources resulting from negotiations of new contracts are
+ * returned in the parameter 'new_vres' which must be provided by the user.
+ *
+ * If the on-line admission test is enabled, FRSH analizes the
+ * schedulability of the context that would result in the new
+ * contract situation with removed, changed and added contracts.
+ *
+ * A successful return code will mean that all contracts have been
+ * accepted and all required operations (creation, cancellation or
+ * update of vres) have been carried out to reach the new running
+ * context.
+ *
+ * If any of the contracts is not accepted a corresponding error shall be
+ * returned and no changes will be made to the previously running context.
+ *
+ * This call is a synchronous, potentially blocking operation. It
+ * returns when the system has rejected the contracts or accepted
+ * and made them effective.
+ *
+ * @param[in] contracts_to_neg List of new contracts to negotiate
+ * @param[in] contracts_to_reneg List of contracts to renegotiate
+ * @param[in] vres_to_reneg List of vres to renegotiate
+ * @param[in] vres_to_cancel List of vres to cancel
+ * @param[out] new_vres List of vres of new contracts.
+ *
+ * @return 0 if no error \n
+ * 0 if there are no errors (in this case it also means contract accepted) \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_TOO_MANY_VRES: if there is no space for more vres \n
+ * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
+ * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+typedef int fna_group_change_mode_sync_t
+ (const frsh_resource_id_t resource_id,
+ const frsh_contracts_group_t *contracts_to_neg,
+ const frsh_contracts_group_t *contracts_to_reneg,
+ const fna_vres_group_t *vres_to_reneg,
+ const fna_vres_group_t *vres_to_cancel,
+ fna_vres_group_t *new_vres);
+
+/**
+ * fna_contract_negotiate()
+ *
+ * The operation negotiates a contract and if accepted it will return
+ * a fna_vres_id_t. It will also check that the given contract_id is unique
+ * within the network.
+ *
+ * If the on-line admission test is enabled, it determines whether the
+ * contract can be admitted or not based on the current contracts
+ * established in the network. Then it creates the vres and
+ * recalculates all necessary parameters for the contracts already
+ * present in the system.
+ *
+ * This is a potentially blocking operation, it returns when the
+ * system has either rejected the contract, or admitted it and made it
+ * effective.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] contract The contract parameters to negotiate
+ * @param[out] vres The internal virtual resource id
+ *
+ * @return
+ * 0 if there are no errors (in this case it also means contract accepted) \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_TOO_MANY_VRES: if there is no space for more vres \n
+ * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
+ * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+typedef int fna_contract_negotiate_t
+ (const frsh_resource_id_t resource_id,
+ const frsh_contract_t *contract,
+ fna_vres_id_t *vres);
+
+/**
+ * fna_contract_renegotiate_sync()
+ *
+ * The operation renegotiates a contract for an existing vres. If
+ * the on-line admission test is enabled it determines whether the
+ * contract can be admitted or not based on the current contracts
+ * established in the system. If it cannot be admitted, the old
+ * contract remains in effect and an error is returned. If it can be
+ * admitted, it recalculates all necessary parameters for the
+ * contracts already present in the system and returns zero. This is a
+ * potentially blocking operation; it returns when the system has
+ * either rejected the new contract, or admitted it and made it
+ * effective.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id to renegotiate
+ * @param[in] new_contract The new contract
+ *
+ * @return
+ * 0 if there are no errors (in this case it also means contract accepted) \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
+ * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+typedef int fna_contract_renegotiate_sync_t
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ const frsh_contract_t *new_contract);
+
+/**
+ * fna_contract_renegotiate_async()
+ *
+ * The operation enqueues a renegotiate operation for an existing
+ * vres, and returns immediately. The renegotiate operation is
+ * performed asynchronously, as soon as it is practical; meanwhile the
+ * system operation will continue normally. When the renegotiation is
+ * made, if the on-line admission test is enabled it determines
+ * whether the contract can be admitted or not based on the current
+ * contracts established in the system. If it cannot be admitted, the
+ * old contract remains in effect. If it can be admitted, it
+ * recalculates all necessary parameters for the contracts already
+ * present in the system.
+ *
+ * When the operation is completed, notification is made to the
+ * caller, if requested, via a signal. The status of the operation (in
+ * progress, admitted, rejected) can be checked with the
+ * frsh_vres_get_renegotiation_status() operation. The argument
+ * sig_notify can be FRSH_NULL_SIGNAL (no notification), or any FRSH
+ * signal value and in this case signal_info is to be sent with the signal.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id to renegotiate
+ * @param[in] new_contract The new contract
+ * @param[in] signal_to_notify Signal number to use to notify vres of
+ * the negotiation result. If FRSH_NULL_SIGNAL, no signal will be raised.
+ * @param[in] signal_info: Associated info that will come with the signal.
+ * This parameter will be ignored if signal_to_notify == FRSH_NULL_SIGNAL.
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL, or sig_notify is neither
+ * NULL nor a valid POSIX signal \n
+ *
+ **/
+typedef int fna_contract_renegotiate_async_t
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ const frsh_contract_t *new_contract,
+ frsh_signal_t signal_to_notify,
+ frsh_signal_info_t signal_info);
+
+/**
+ * fna_vres_get_renegotiation_status()
+ *
+ * The operation reports on the status of the last renegotiation
+ * operation enqueued for the specified vres. It is callable even
+ * after notification of the completion of such operation, if
+ * requested.
+ *
+ * If the vres is not and has not been involved in any of the
+ * frsh_contract_renegotiate_async() or frsh_group_change_mode_async()
+ * operations, the status returned is FNA_NOT_REQUESTED
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id we want the status from
+ * @param[in] renegotiation_status The status of the last renegotiation on
+ * vres (FRSH_RS_IN_PROGRESS, FRSH_RS_REJECTED, FRSH_RS_ADMITTED,
+ * FRSH_RS_NOT_REQUESTED)
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+typedef int fna_vres_get_renegotiation_status_t
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ frsh_renegotiation_status_t *renegotiation_status);
+
+/**
+ * fna_vres_destroy()
+ *
+ * The operation eliminates the specified vres
+ * and recalculates all necessary parameters for the contracts
+ * remaining in the system. This is a potentially blocking operation;
+ * it returns when the system has made the changes effective.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id to destroy
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+typedef int fna_vres_destroy_t
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres);
+
+/**
+ * fna_vres_get_contract()
+ *
+ * This operation stores the contract parameters currently associated
+ * with the specified vres in the variable pointed to by
+ * contract. It returns an error if the vres_id is not recognised.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id
+ * @param[out] contract The contract parameters that we want
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+typedef int fna_vres_get_contract_t
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ frsh_contract_t *contract);
+
+/**
+ * fna_vres_get_usage()
+ *
+ * This function gets the execution time spent by all messages that have been
+ * sent through the specified vres.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id
+ * @param[out] usage Execution time spent by this vres
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+typedef int fna_vres_get_usage_t
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ struct timespec *usage);
+
+/**
+ * fna_vres_get_remaining_budget()
+ *
+ * This function stores in the variable pointed to by budget the
+ * remaining execution-time budget associated with the specified
+ * vres in the present period.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id
+ * @param[out] remaining_budget The remaining budget for this period
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+typedef int fna_vres_get_remaining_budget_t
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ struct timespec *remaining_budget);
+
+/**
+ * fna_vres_get_budget_and_period()
+ *
+ * This function gets the budget and period associated with the specified vres
+ * for each period. If one of these pointers is NULL, the corresponding
+ * information is not stored.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id
+ * @param[out] budget The budget associated to vres
+ * @param[out] period The period associated to vres
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if both pointers are NULL \n
+ *
+ **/
+typedef int fna_vres_get_budget_and_period_t
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ struct timespec *budget,
+ struct timespec *period);
+
+/*@}*/
+
+///////////////////////////////////////////////////////////////////
+// SPARE CAPACITY FUNCIONS
+///////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup fnaspare FNA Spare Capacity
+ * @ingroup fna
+ *
+ * The following functions are used to get spare capacity data
+ *
+ * @{
+ **/
+
+/**
+ * fna_resource_get_capacity()
+ *
+ * This operation gets the spare capacity currently assigned to a importance
+ * level. If we divide this value by UINT32_MAX we will get the network
+ * utilization associated to the spare capacity of a importance level.
+ *
+ * The following is typically in stdint.h: \n
+ * - typedef unsigned int uint32_t; \n
+ * - # define UINT32_MAX (4294967295U) \n
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] importance The importance we want the capacity of
+ * @param[out] capacity The spare capacity for that importance level
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+typedef int fna_resource_get_capacity_t
+ (const frsh_resource_id_t resource_id,
+ const int importance,
+ uint32_t *capacity);
+
+/**
+ * fna_resource_get_total_weight()
+ *
+ * This function gets the sum of the weight parameters for all vres in a
+ * network of an importance level.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] importance The importance we want the total weight of
+ * @param[out] total_weight The total weight for that importance level
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+typedef int fna_resource_get_total_weight_t
+ (const frsh_resource_id_t resource_id,
+ const int importance,
+ int *total_weight);
+
+/**
+ * fna_vres_decrease_capacity()
+ *
+ * This function allows to ask for less budget and period than what we
+ * received. The request must be compatible with the rest of contract
+ * parameters of the vres. If we want to recover the released capacity
+ * we will need to renegotiate.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id
+ * @param[in] new_budget The new_budget
+ * @param[in] new_period The new Period
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ * FNA_ERR_CONTRACT_REJECTED: if it is incompatible with the current
+ * contract \n
+ *
+ **/
+typedef int fna_vres_decrease_capacity_t
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ const struct timespec new_budget,
+ const struct timespec new_period);
+
+/*@}*/
+
+///////////////////////////////////////////////////////////////////
+// SEND RECEIVE OPERATIONS
+///////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup fnasendrecv FNA Send and Receive
+ * @ingroup fna
+ *
+ * The following functions are used to send and receive
+ *
+ * @{
+ **/
+
+typedef enum {
+ FRSH_SEND_ENDPOINT_TYPE,
+ FRSH_RECEIVE_ENDPOINT_TYPE
+} frsh_endpoint_type_t;
+
+typedef struct fna_endpoint_data {
+ frsh_endpoint_type_t endpoint_type; // send_endpoint or receive_endpoint
+ fna_vres_id_t vres; // only for send_endpoints
+ bool is_bound; // only for send_endpoints
+ frsh_network_address_t destination; // only for send_endpoints
+ frsh_resource_id_t resource_id;
+ frsh_stream_id_t stream_id;
+ frsh_protocol_info_t protocol_info;
+ frsh_endpoint_queueing_info_t queue_info;
+ union {
+ frsh_send_endpoint_protocol_info_t send;
+ frsh_receive_endpoint_protocol_info_t receive;
+ } endpoint_protocol_info;
+} fna_endpoint_data_t;
+
+/**
+ * fna_send_sync()
+ *
+ * Similar to previous function but now the sending thread gets blocked
+ * until the message is already sent to the network.
+ *
+ * @param[in] endpoint The send endpoint we are sending through. It must
+ * be bound to a virtual resource (resource_id is in the endpoint).
+ * @param[in] msg The message we want to send
+ * @param[in] size The size in bytes of the message
+ *
+ * @returns
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
+ * FNA_ERR_BUFFER_FULL: if the message has been discarded because
+ * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
+ *
+ **/
+typedef int fna_send_sync_t
+ (const fna_endpoint_data_t *endpoint,
+ const void *msg,
+ const size_t size);
+
+/**
+ * fna_send_async()
+ *
+ * This operation sends a message stored in msg and of length size
+ * through the given send endpoint. The operation is non-blocking and
+ * returns immediately.
+ *
+ * @param[in] endpoint The send endpoint we are sending through. It must
+ * be bound to a virtual resource (resource_id is in the endpoint).
+ * @param[in] msg The message we want to send
+ * @param[in] size The size in bytes of the message
+ *
+ * @returns
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
+ * FNA_ERR_BUFFER_FULL: if the message has been discarded because
+ * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
+ *
+ **/
+typedef int fna_send_async_t
+ (const fna_endpoint_data_t *endpoint,
+ const void *msg,
+ const size_t size);
+
+/**
+ * fna_receive_sync()
+ *
+ * This operation is used to receive messages from the network with a
+ * blocking behavior (if there are no messages this operation blocks
+ * the calling thread).
+ *
+ * When a message is available, it is copied to buffer (up to its size).
+ * The number of bytes copied is returned in received_bytes. The rest
+ * of the bytes of that message will be lost or not depending on the
+ * protocol (FNA_ERR_NO_SPACE will be returned if it is).
+ *
+ * The function fails with FNA_ERR_NO_SPACE if the buffersize is
+ * too small for the message received. In this case the message is
+ * lost.
+ *
+ * Messages arriving at a receiver buffer that is full will be handled
+ * according to the queueing policy of the endpoint (overwrite oldest,
+ * discard it,etc).
+ *
+ * @param[in] endpoint The receive endpoint we are receiving from.
+ * (resource_id is in the endpoint).
+ * @param[out] buffer Buffer for storing the received message
+ * @param[in] buffer_size The size in bytes of this buffer
+ * @param[out] received_bytes The actual number of received bytes
+ * @param[out] from Address of the sender node
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ * FNA_ERR_NO_SPACE: if the message size is bigger than the
+ * provided buffer. \n
+ *
+ **/
+typedef int fna_receive_sync_t
+ (const fna_endpoint_data_t *endpoint,
+ void *buffer,
+ const size_t buffer_size,
+ size_t *received_bytes,
+ frsh_network_address_t *from);
+
+/**
+ * fna_receive_async()
+ *
+ * This operation is similar to the previous one but it works in a non
+ * blocking (asynchronous) fashion. If no message is available it
+ * returns with error FNA_NO_MESSAGE.
+ *
+ * @param[in] endpoint The receive endpoint we are receiving from.
+ * (resource_id is in the endpoint).
+ * @param[out] buffer Buffer for storing the received message
+ * @param[in] buffer_size The size in bytes of this buffer
+ * @param[out] received_bytes The actual number of received bytes
+ * @param[out] from Address of the sender node
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ * FNA_ERR_NO_SPACE: if the message size is bigger than the
+ * provided buffer. \n
+ * FNA_NO_MESSAGE: if no messages are available in the queue. \n
+ *
+ **/
+typedef int fna_receive_async_t
+ (const fna_endpoint_data_t *endpoint,
+ void *buffer,
+ const size_t buffer_size,
+ size_t *received_bytes,
+ frsh_network_address_t *from);
+
+/**
+ * fna_send_endpoint_get_status()
+ *
+ * This function tells the number of messages still pending in the
+ * endpoint queue, whether the network is up or down with some
+ * optional information which is protocol_dependent.
+ *
+ * @param[in] endpoint The send endpoint (resource_id is in the endpoint).
+ * @param[out] number_of_pending_messages The number of pending messages
+ * @param[out] network_status How is the network (up, down..)
+ * @param[out] protocol_status Protocol dependent status info
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+typedef int fna_send_endpoint_get_status_t
+ (const fna_endpoint_data_t *endpoint,
+ int *number_of_pending_messages,
+ frsh_endpoint_network_status_t *network_status,
+ frsh_protocol_status_t *protocol_status);
+
+/**
+ * fna_send_endpoint_bind_t()
+ *
+ * This operation is a called from frsh_send_endpoint_bind and binds send
+ * edpoint to vres.
+ *
+ * @param[in] endpoint the endpoint object.
+ * @param[in] vres The internal virtual resource id
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ **/
+typedef
+int fna_send_endpoint_bind_t(fna_endpoint_data_t *endpoint, fna_vres_id_t vres);
+
+/**
+ * fna_send_endpoint_unbind_t()
+ *
+ * This operation is a called from frsh_send_endpoint_bind.
+ *
+ * @param[in] endpoint the endpoint object.
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ **/
+typedef
+int fna_send_endpoint_unbind_t(fna_endpoint_data_t *endpoint);
+
+/**
+ * fna_send_endpoint_create_callback()
+ *
+ * This operation is a called from frsh_send_endpoint_create with a
+ * send_endpoint structure already filled.
+ *
+ * @param[in] endpoint the endpoint object.
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ **/
+typedef int fna_send_endpoint_create_callback_t
+ (fna_endpoint_data_t *endpoint);
+
+/**
+ * fna_receive_endpoint_create_callback()
+ *
+ * This operation is a called from frsh_receive_endpoint_create with a
+ * receive_endpoint structure already filled.
+ *
+ * Receiving endpoints are not bound to any network vres, this is
+ * because don't originate any traffic.
+ *
+ * @param[in] endpoint the endpoint object.
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ **/
+typedef int fna_receive_endpoint_create_callback_t
+ (fna_endpoint_data_t *endpoint);
+
+/**
+ * fna_endpoint_destroy()
+ *
+ * This operation is a called from frsh_send(receive)_endpoint_destroy.
+ *
+ * @param[in] endpoint the endpoint object.
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ **/
+typedef int fna_endpoint_destroy_t
+ (fna_endpoint_data_t *endpoint);
+
+/**
+ * fna_receive_endpoint_get_pending_messages
+ *
+ * This function tells the number of messages still pending in the
+ * endpoint queue, whether the network is up or down and some optional
+ * information which is protocol dependent.
+ *
+ * @param[in] endpoint The receive endpoint (resource_id is in the endpoint).
+ * @param[out] number_of_pending_messages The number of pending messages
+ * @param[out] network_status How is the network (up, down..)
+ * @param[out] protocol_status Protocol dependent status info
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+typedef int fna_receive_endpoint_get_status_t
+ (const fna_endpoint_data_t *endpoint,
+ int *number_of_pending_messages,
+ frsh_endpoint_network_status_t *network_status,
+ frsh_protocol_status_t *protocol_status);
+
+/*@}*/
+
+//////////////////////////////////////////////////////////////////////
+// NETWORK CONFIGURATION FUNCTIONS
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup frshfnaconfig FNA Network Configuration
+ * @ingroup fna
+ *
+ * These functions are needed to set/get some network dependent values
+ *
+ * @{
+ **/
+
+/**
+ * fna_network_get_max_message_size()
+ *
+ * This operation gives the maximum number of bytes that can be sent
+ * at a time through the send function when using the network designated by
+ * 'resource_id' and sending it to 'destination'.
+ *
+ * If the application needs to send bigger messages it will have to
+ * split them.
+ *
+ * Some protocols, like IP, are capable of sending large messages
+ * (and use fragmentation internally) but other protocols don't.
+ *
+ * @param[in] resource_id The network we want the tx time from.
+ * @param[in] destination The destination address
+ * @param[out] max_size The maximum number of bytes for each message
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
+ * invalid \n
+ *
+ **/
+typedef int fna_network_get_max_message_size_t
+ (const frsh_resource_id_t resource_id,
+ const frsh_network_address_t destination,
+ size_t *max_size);
+
+/**
+ * fna_network_bytes_to_budget()
+ *
+ * This operation converts a number of bytes into a temporal budget for
+ * a specific network. Network overheads are not included here but are
+ * considered internally when negotiating a specific contract.
+ *
+ * @param[in] resource_id The network
+ * @param[in] nbytes Number of bytes
+ * @param[out] budget The network budget for nbytes
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or nbytes is less
+ * than zero \n
+ *
+ **/
+typedef int fna_network_bytes_to_budget_t
+ (const frsh_resource_id_t resource_id,
+ const size_t nbytes,
+ frsh_rel_time_t *budget);
+
+/**
+ * fna_network_budget_to_bytes()
+ *
+ * This operation converts a temporal budget into a number of bytes for
+ * a specific network. Network overheads are not included.
+ *
+ * @param[in] resource_id The network
+ * @param[in] budget The network budget for nbytes
+ * @param[out] nbytes Number of bytes
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
+ * an invalid time value \n
+ *
+ **/
+typedef int fna_network_budget_to_bytes_t
+ (const frsh_resource_id_t resource_id,
+ const frsh_rel_time_t *budget,
+ size_t *nbytes);
+
+/**
+ * fna_network_get_min_effective_budget()
+ *
+ * This operation gets the minimum effective budget for a network. Each message
+ * consumes a contracted budget in "chunks" (i.e: packets) that we call
+ * minimum effective budget.
+ *
+ * A negotiated contract, for N bytes in a period T, means that there is a
+ * virtual resource that reserves for the user:
+ *
+ * Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
+ *
+ * Note that if the user decides not to send these N bytes at once but, say,
+ * one byte at a time, it will consume one "CHUNK" at a time and the reserved
+ * budget will become exhausted before sending all the bytes.
+ *
+ * @param[in] resource_id The network
+ * @param[out] budget The network budget
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+typedef int fna_network_get_min_effective_budget_t
+ (const frsh_resource_id_t resource_id,
+ frsh_rel_time_t *budget);
+
+/*@}*/
+
+typedef struct {
+ fna_init_t *fna_init;
+ fna_group_change_mode_sync_t *fna_group_change_mode_sync;
+ fna_contract_negotiate_t *fna_contract_negotiate;
+ fna_contract_renegotiate_sync_t *fna_contract_renegotiate_sync;
+ fna_contract_renegotiate_async_t *fna_contract_renegotiate_async;
+ fna_vres_get_renegotiation_status_t *fna_vres_get_renegotiation_status;
+ fna_vres_destroy_t *fna_vres_destroy;
+ fna_vres_get_contract_t *fna_vres_get_contract;
+ fna_vres_get_usage_t *fna_vres_get_usage;
+ fna_vres_get_remaining_budget_t *fna_vres_get_remaining_budget;
+ fna_vres_get_budget_and_period_t *fna_vres_get_budget_and_period;
+ fna_resource_get_capacity_t *fna_resource_get_capacity;
+ fna_resource_get_total_weight_t *fna_resource_get_total_weight;
+ fna_vres_decrease_capacity_t *fna_vres_decrease_capacity;
+ fna_send_sync_t *fna_send_sync;
+ fna_send_async_t *fna_send_async;
+ fna_receive_sync_t *fna_receive_sync;
+ fna_receive_async_t *fna_receive_async;
+ fna_send_endpoint_get_status_t *fna_send_endpoint_get_status;
+ fna_send_endpoint_bind_t *fna_send_endpoint_bind;
+ fna_send_endpoint_unbind_t *fna_send_endpoint_unbind;
+ fna_endpoint_destroy_t *fna_endpoint_destroy;
+ fna_send_endpoint_create_callback_t *fna_send_endpoint_created;
+ fna_receive_endpoint_create_callback_t *fna_receive_endpoint_created;
+ fna_receive_endpoint_get_status_t *fna_receive_endpoint_get_status;
+ fna_network_get_max_message_size_t *fna_network_get_max_message_size;
+ fna_network_bytes_to_budget_t *fna_network_bytes_to_budget;
+ fna_network_budget_to_bytes_t *fna_network_budget_to_bytes;
+ fna_network_get_min_effective_budget_t *fna_network_get_min_eff_budget;
+} fna_operations_t;
+
+#endif // _FNA_H_
+
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+// ******** **** ** **
+// **///// /**/** /** ****
+// ** /**//** /** **//**
+// ******* /** //** /** ** //**
+// **//// /** //**/** **********
+// ** /** //****/**//////**
+// ** /** //***/** /**
+// / // /// // //
+//
+// FNA(Frescor Network Adaptation layer), pronounced "efe ene a"
+//==============================================================
+
+#ifndef _FNA_CONFIGURATION_H_
+#define _FNA_CONFIGURATION_H_
+
+#include "fna.h"
+
+/** Maximum number of networks in the system (each network will have a
+ * different resource_id)
+ **/
+#define FNA_MAX_NETWORKS 4
+
+extern fna_operations_t *fna_operations[FNA_MAX_NETWORKS];
+
+#endif // _FNA_CONFIGURATION_H_
+
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+// ******** **** ** **
+// **///// /**/** /** ****
+// ** /**//** /** **//**
+// ******* /** //** /** ** //**
+// **//// /** //**/** **********
+// ** /** //****/**//////**
+// ** /** //***/** /**
+// / // /// // //
+//
+// FNA(Frescor Network Adaptation layer), pronounced "efe ene a"
+//==============================================================
+
+#ifndef _FRSH_FNA_H_
+#define _FRSH_FNA_H_
+
+#include "frsh.h" /* for frsh_resource_id_t, network_address_t, stream_id_t*/
+#include <time.h> /* for timespec */
+#include <stdbool.h> /* for bool */
+#include "fna_configuration.h"
+
+#ifdef RTEP_FNA_ENABLED
+ #include "rtep.h"
+#endif
+
+#ifdef FRESCAN_FNA_ENABLED
+ #include "../src_frescan/frescan.h"
+#endif
+
+/**
+ * @defgroup frshfna FNA Public Interface
+ *
+ * FNA is a Network adaption layer that allows to plugin new
+ * network protocols to the distributed module.
+ *
+ * It is divided in two parts:
+ * - FRSH_FNA: public types and functions for the FRSH API
+ * - FNA: private functions only used within FRSH.
+ *
+ **/
+
+////////////////////////////////////////////////////////////////////
+// MAPPING FUNCTIONS
+////////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup frshfnamap FNA Mapping Functions
+ * @ingroup frshfna
+ *
+ * These functions are needed to map network specific types to FRSH types.
+ * Instead of providing this mapping functions a static hardwired configuration
+ * could be used.
+ *
+ * @{
+ **/
+
+/**
+ * frsh_XXXX_map_network_address()
+ *
+ * To map a XXXX protocol network address into a FRSH address.
+ * The protocol must keep this mapping consistent. Instead of using a function
+ * a hardwired mapping could be used.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] in_address The network address we want to map to a frsh address
+ * @param[out] out_address The FRSH abstract network address
+ *
+ * @return
+ * FNA_NO_ERROR: in this case it also means contract accepted \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+#ifdef RTEP_FNA_ENABLED
+int frsh_rtep_map_network_address(const frsh_resource_id_t resource_id,
+ const rtep_station_id_t in_address,
+ frsh_network_address_t *out_address);
+#endif
+
+#ifdef FRESCAN_FNA_ENABLED
+int frsh_frescan_map_network_address(const frsh_resource_id_t resource_id,
+ const frescan_node_t in_address,
+ frsh_network_address_t *out_address);
+#endif
+
+/**
+ * frsh_XXXX_map_stream_id()
+ *
+ * To map a XXXX protocol network stream, port, channel... into a FRSH stream.
+ * The protocol must keep this mapping consistent. Instead of using a function
+ * a hardwired mapping could be used.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] in_stream The network stream we want to map to a FRSH stream
+ * @param[out] out_stream The FRSH abstract network stream
+ *
+ * @return
+ * FNA_NO_ERROR: in this case it also means contract accepted \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+#ifdef RTEP_FNA_ENABLED
+int frsh_rtep_map_stream_id(const frsh_resource_id_t resource_id,
+ const rtep_channel_t in_stream,
+ frsh_stream_id_t *out_stream);
+#endif
+
+#ifdef FRESCAN_FNA_ENABLED
+int frsh_frescan_map_stream_id(const frsh_resource_id_t resource_id,
+ const frescan_channel_t in_stream,
+ frsh_stream_id_t *out_stream);
+#endif
+
+/*@}*/
+
+///////////////////////////////////////////////////////////////////
+// NEGOTIATION SERVICE PARAMETERS
+///////////////////////////////////////////////////////////////////
+/**
+ * @defgroup frshfnaserv FNA Negotiation Service Parameters
+ * @ingroup frshfna
+ *
+ * These functions are needed to set/get the negotiation service parameters.
+ *
+ * @{
+ **/
+
+/**
+ * frsh_XXXX_negotiation_messages__vres_renegotiate()
+ *
+ * This function allows the application to change the minimum period
+ * of the negotiation messages sent through the network. It is similar
+ * to the service thread but for the network messages. We do not provide
+ * budget here because the size of the negotiation messages is fixed.
+ *
+ * This change is similar to a renegotiation so a schedulability test
+ * must be done to see if the change can be accepted or not.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] period The new period for negotiation messages
+ * @param[out] accepted If the change has been accepted or not
+ *
+ * @return
+ * FNA_NO_ERROR: in this case it also means contract accepted \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ * FNA_ERR_REJECTED_CONTRACT : if the renegotiation fails \n
+ *
+ **/
+#ifdef RTEP_FNA_ENABLED
+int frsh_rtep_negotiation_messages_vres_renegotiate
+ (const frsh_resource_id_t resource_id,
+ const struct timespec *period);
+#endif
+
+#ifdef FRESCAN_FNA_ENABLED
+int frsh_frescan_negotiation_messages_vres_renegotiate
+ (const frsh_resource_id_t resource_id,
+ const struct timespec *period);
+#endif
+
+/**
+ * frsh_XXXX_negotiation_messages_vres_get_period()
+ *
+ * This function gets the minimum period of the negotiation messages
+ * sent through the network.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[out] period The period for negotiation messages
+ *
+ * @return
+ * FNA_NO_ERROR: in this case it also means contract accepted \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+#ifdef RTEP_FNA_ENABLED
+int frsh_rtep_negotiation_messages_vres_get_period
+ (const frsh_resource_id_t resource_id,
+ struct timespec *period);
+#endif
+
+#ifdef FRESCAN_FNA_ENABLED
+int frsh_frescan_negotiation_messages_vres_get_period
+ (const frsh_resource_id_t resource_id,
+ struct timespec *period);
+#endif
+
+/**
+ * frsh_XXXX_service_thread_vres_renegotiate()
+ *
+ * This function allows the application to change the period and
+ * budget of the service thread that makes the negotiations and
+ * schedulability tests in a network.
+ *
+ * The service thread starts with a default budget and period that
+ * should be configurable
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] budget The new budget for the service thread
+ * @param[in] period The new period for the service thread
+ * @param[out] accepted If the negotiation has been accepted or not
+ *
+ * @return
+ * FNA_NO_ERROR: in this case it also means contract accepted \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+#ifdef RTEP_FNA_ENABLED
+int frsh_rtep_service_thread_vres_renegotiate
+ (const frsh_resource_id_t resource_id,
+ const struct timespec *budget,
+ const struct timespec *period,
+ bool *accepted);
+#endif
+
+#ifdef FRESCAN_FNA_ENABLED
+int frsh_frescan_service_thread_vres_renegotiate
+ (const frsh_resource_id_t resource_id,
+ const struct timespec *budget,
+ const struct timespec *period,
+ bool *accepted);
+#endif
+
+/**
+ * frsh_XXXX_service_thread_vres_get_budget_and_period()
+ *
+ * This function gets the budget and period of a service thread.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[out] budget The budget of the service thread
+ * @param[out] period The period of the service thread
+ *
+ * @return
+ * FNA_NO_ERROR: in this case it also means contract accepted \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+#ifdef RTEP_FNA_ENABLED
+int frsh_rtep_service_thread_vres_get_budget_and_period
+ (const frsh_resource_id_t resource_id,
+ struct timespec *budget,
+ struct timespec *period);
+#endif
+
+#ifdef FRESCAN_FNA_ENABLED
+int frsh_frescan_service_thread_vres_get_budget_and_period
+ (const frsh_resource_id_t resource_id,
+ struct timespec *budget,
+ struct timespec *period);
+#endif
+
+/*@}*/
+
+#endif /* _FRSH_FNA_H_ */
--- /dev/null
+.PHONY: none clean libfna libfrsh libfosa libfsa libutils
+
+none:
+ @exec echo -e "\nPlease introduce a target, i.e: 'make test_dtm_xxx.exe'";
+
+%.exe: %.c libfna libfosa libfrsh libfosa libfsa libutils dependencies
+ @exec echo -e "\n>> Building $@: ";
+ @if [ -f $< ]; \
+ then \
+ $(CC) $(CFLAGS) $< $(LDFLAGS) -o $@; \
+ fi;
+ @exec echo ">> End Building $@";
+
+libfna:
+ @exec echo -e "\n>> Compiling FNA library (lib/libfna.a):";
+ @rm -f $(FNA_PATH)/lib/*.o
+ @make -C $(FNA_PATH)/src all
+ @mv $(FNA_PATH)/src/*.o $(FNA_PATH)/lib/
+
+ifeq ($(CONFIG_FNA_RTEP),y)
+ @make -C $(FNA_PATH)/src_rtep librtepfna.a
+endif
+
+ifeq ($(CONFIG_FNA_UNIX),y)
+ @make -C $(FNA_PATH)/src_unix libunixfna.a
+endif
+
+ifeq ($(CONFIG_FNA_FRESCAN),y)
+ @make -C $(FNA_PATH)/src_frescan libfrescan
+endif
+
+ifeq ($(CONFIG_FWP),y)
+ @make -C $(FNA_PATH)/src_fwp libfwp
+endif
+
+ @ar -rc libfna.a $(FNA_PATH)/lib/*.o
+ @mv libfna.a $(FNA_PATH)/lib/
+ @rm -f $(FNA_PATH)/lib/*.o
+ @exec echo ">> End Compiling FNA library (lib/libfna.a)"
+
+libfrsh:
+ make -C $(FRSH_PATH) libfrsh
+
+libfosa:
+ make -C $(FOSA_PATH) libfosa
+
+libutils:
+ make -C $(UTILS_PATH) libutils
+
+libfsa:
+ make -C $(FSA_PATH) libfsa
+
+dependencies:
+
+clean:
+ @exec echo -e "\n>> Cleaning... ";
+ @find \( -name '*.[oa]' -or -name '*~*' -or -name 'lib*.a' \
+ -or -name '*.exe' -or -name 'mprogram' -or -name 'a.out' \) -print -delete
+ @exec echo ">> End Cleaning"
--- /dev/null
+all: objs
+include ../config.mk
+include ../rules.mk
+
+SRCS := $(wildcard *.c)
+OBJS := $(patsubst %.c,%.o,$(wildcard *.c))
+HDRS := $(wildcard $(FNA_PATH)/include/*.h)
+
+objs: $(OBJS)
+
+%.o: %.c $(SRCS) $(HDRS)
+ $(CC) $(CFLAGS) -c $<
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+// ******** **** ** **
+// **///// /**/** /** ****
+// ** /**//** /** **//**
+// ******* /** //** /** ** //**
+// **//// /** //**/** **********
+// ** /** //****/**//////**
+// ** /** //***/** /**
+// / // /// // //
+//
+// FNA(Frescor Network Adaptation layer), pronounced "efe ene a"
+//==============================================================
+
+#include "fna_configuration.h"
+
+#ifdef RTEP_FNA_ENABLED
+ #include "../src_rtep/rtep_fna.h" // for rtep_fna_operations
+#endif
+
+#ifdef UNIX_FNA_ENABLED
+ #include "../src_unix/unix_fna.h" // for unix_fna_operations
+#endif
+
+#ifdef FRESCAN_FNA_ENABLED
+ #include "../src_frescan/frescan_bwres_fna.h" // for frescan_fna_operations
+#endif
+
+#ifdef FWP_FNA_ENABLED
+ #include <fwp_fna.h> // for fwp_fna_operations
+#endif
+
+fna_operations_t *fna_operations[FNA_MAX_NETWORKS] = {
+#ifdef FRESCAN_FNA_ENABLED
+ &frescan_fna_operations,
+#else
+ NULL,
+#endif
+#ifdef RTEP_FNA_ENABLED
+ &rtep_fna_operations,
+#else
+ NULL,
+#endif
+#ifdef UNIX_FNA_ENABLED
+ &unix_fna_operations,
+#else
+ NULL,
+#endif
+#ifdef FWP_FNA_ENABLED
+ &fwp_fna_operations
+#else
+ NULL
+#endif
+};
--- /dev/null
+.PHONY: none libfrescan clean cleanall
+
+include ../config.mk
+include ../rules.mk
+
+SRCS := $(wildcard *.c)
+OBJS := $(patsubst %.c,%.o,$(wildcard *.c))
+HDRS := $(wildcard *.h)
+
+libfrescan: $(OBJS)
+ @exec echo -e "\n>> Building FRESCAN:";
+ ld -r -o libfrescan.o *.o
+ @mv libfrescan.o $(FNA_PATH)/lib
+ @exec echo ">> [OK]"
+
+%.o: %.c $(SRCS) $(HDRS)
+ @$(CC) $(CFLAGS) -c $< # 1> /dev/null
+
--- /dev/null
+FRESCAN protocol
+=====================
+Name:
+FRESCAN
+
+Version:
+May 2008
+
+Status:
+Alpha
+
+Authors:
+Daniel Sangorrin [daniel.sangorrin@unican.es] (UC),
+Michael Gonzalez Harbour [mgh@unican.es] (UC)
+
+Licence:
+FRESCOR Licence (see COPYING)
+
+Brief description:
+Implementation of the FREScor on CAN (FRESCAN) protocol
+
+URL:
+svn co http://www.frescor.org/private/svn/frescor/fna/trunk/src_frescan/
+
+Bugs:
+See TODO
+
+Description:
+
+This folder contains the implementation of the FRESCAN protocol. The design,
+arquitecture and description of the FRESCAN protocol is explained in the
+FRESCOR D-ND1 deliverable about Fieldbus systems. The protocol is based on
+the CAN bus, and it includes support for prioritized task-oriented message
+communication either with fixed priorities or sporadic servers.
+
--- /dev/null
+- reserve commit functions
+- use an internal thread as a bottom half for irq hooks
+- corrections in fna
+ * CTU corrections
+ * fna_vres_id_t will be frsh_vres_index_T
+- oh, i forgot CAN priorities are assigned inversely!! map them!
+- when linking, hide symbols that are not needed externally (objcopy -G..)
\ No newline at end of file
--- /dev/null
+/*!
+ * @file frescan.c
+ *
+ * @brief the FRESCAN protocol
+ *
+ * @version 0.01
+ *
+ * @date 20-Feb-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This file contains the implementation of the FRESCAN protocol
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#include <sys/marte_configuration_parameters.h> // PATH_MX
+#include <fcntl.h> // open
+#include <unistd.h> // ioctl
+#include <stdlib.h> // malloc
+#include <string.h> // memcpy
+#include <assert.h>
+
+#include <drivers/can.h> // can_chip_t, can_frame_t
+#include "frescan.h" // frescan_init_params_t, frescan_send_params_t
+#include "frescan_queues.h" // init, enqueue, requeue
+#include "frescan_data.h" // init, frescan_data
+#include "frescan_servers.h" // init, frame_sent
+#include "frescan_debug.h" // DEBUG
+#include "frescan_id.h" // frescan_id_set_field, frescan_id_get_field
+#include "frescan_hw_buffer.h" // frescan_hw_buffer_update
+#include "frescan_packets.h"
+
+static int frescan_hook_frame_recv (const struct can_chip_t *chip,
+ struct can_frame_t *frame);
+
+static int frescan_hook_frame_sent(const struct can_chip_t *chip);
+
+static int frescan_hook_frame_aborted(const struct can_chip_t *chip);
+
+/**
+ * frescan_init - initializes the network and the internal structures
+ *
+ * @params: the initialization parameters
+ *
+ * This function initializes the frescan network protocol.
+ *
+ * First it opens and configures the corresponding CAN chip device. For the
+ * CAN chip acceptance filter we use a dual filter configuration. The first
+ * filter is to set my local address address and the second one is to allow
+ * broadcast messages.
+ *
+ * Once the CAN chip is configured we call the initialization functions of
+ * the rest of modules of frescan.
+ *
+ */
+
+int frescan_init(frescan_init_params_t *params)
+{
+ int fd, ret;
+ char can_path[PATH_MX];
+ struct ioctl_filters_t ioctl_filters;
+ struct can_filter_t filters[2];
+
+ snprintf(can_path, PATH_MX, "/dev/can%u", params->net);
+
+ DEBUG(FRESCAN_INIT_ENABLE_DEBUG, "open %s\n", can_path);
+
+ fd = open (can_path, O_RDWR);
+ if (fd == -1) {
+ FRESCAN_ERROR ("could not open /dev/can%u\n", params->net);
+ FRESCAN_ERROR ("hint: check driver or card installation\n");
+ return -1;
+ }
+
+ DEBUG(FRESCAN_INIT_ENABLE_DEBUG, "set acceptance filters\n");
+
+ filters[0].mask = 0xFFFFFFFF;
+ frescan_id_set_field(&filters[0].mask, FRESCAN_FIELD_DEST,0x00);
+ filters[0].code = 0;
+ frescan_id_set_field(&filters[0].code, FRESCAN_FIELD_DEST,params->node);
+
+ filters[1].mask = filters[0].mask;
+ filters[1].code = 0;
+ frescan_id_set_field(&filters[1].code,
+ FRESCAN_FIELD_DEST,
+ FRESCAN_BROADCAST_ADDR);
+
+ ioctl_filters.filters = filters;
+ ioctl_filters.len = 2;
+
+ ret = ioctl(fd, CAN_IOCTL_SET_FILTERS, &ioctl_filters);
+ if (ret == -1) {
+ FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_FILTERS failed /dev/can%u\n",
+ params->net);
+ return -1;
+ }
+
+ DEBUG(FRESCAN_INIT_ENABLE_DEBUG, "set tx, rx, abort hooks\n");
+
+ ret = ioctl(fd, CAN_IOCTL_SET_TX_HOOK, frescan_hook_frame_sent);
+ if (ret == -1) {
+ FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_TX_HOOK failed /dev/can%u\n",
+ params->net);
+ return -1;
+ }
+
+ ret = ioctl(fd, CAN_IOCTL_SET_RX_HOOK, frescan_hook_frame_recv);
+ if (ret == -1) {
+ FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_RX_HOOK failed /dev/can%u\n",
+ params->net);
+ return -1;
+ }
+
+ ret = ioctl(fd, CAN_IOCTL_SET_AB_HOOK, frescan_hook_frame_aborted);
+ if (ret == -1) {
+ FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_AB_HOOK failed /dev/can%u\n",
+ params->net);
+ return -1;
+ }
+
+ DEBUG(FRESCAN_INIT_ENABLE_DEBUG, "init the rest of modules\n");
+
+ ret = frescan_data_init(fd, params);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not initialize the global data\n");
+ return -1;
+ }
+
+ ret = frescan_packets_init();
+ if (ret != 0) {
+ FRESCAN_ERROR("could not initialize the packets pool\n");
+ return -1;
+ }
+
+ ret = frescan_queues_init(&frescan_data[params->net].queues, params);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not initialize the queues\n");
+ return -1;
+ }
+
+ ret = frescan_servers_init(params->net);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not initialize the servers\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * frescan_send - send a message
+ *
+ * @params: the parameters needed by the protocol to send the message
+ * @msg: the message buffer
+ * @size: the size of the message
+ *
+ * This is one of the main functions of the protocol and it provides the
+ * means to send a message through the protocol stack.
+ */
+
+int frescan_send(const frescan_send_params_t *params,
+ const uint8_t *msg,
+ const size_t size)
+{
+ int ret;
+ frescan_packet_t *packet;
+ frescan_prio_queue_t *pqueue;
+
+ DEBUG(FRESCAN_SEND_ENABLE_DEBUG || FRESCAN_FRAG_ENABLE_DEBUG,
+ "checking arguments (msg size=%d)\n", size);
+
+ if ((params == NULL) || (msg == NULL) || (size == 0)) {
+ FRESCAN_ERROR("arguments are not ok\n");
+ return -1;
+ }
+
+ DEBUG(FRESCAN_SEND_ENABLE_DEBUG, "allocating a packet\n");
+
+ FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
+ packet = frescan_packets_alloc();
+ FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
+
+ if (packet == NULL) {
+ FRESCAN_ERROR("could not allocate packet\n");
+ return -1;
+ }
+ packet->flags = params->flags; // set the flags (to remember them)
+
+ DEBUG(FRESCAN_SEND_ENABLE_DEBUG, "allocating a frame\n");
+
+ FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
+ packet->frame = can_framespool_alloc();
+ FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
+
+ if (packet->frame == NULL) {
+ FRESCAN_ERROR("could not allocate frame\n");
+ return -1;
+ }
+
+ DEBUG(FRESCAN_SEND_ENABLE_DEBUG, "set values for the frame header\n");
+ packet->frame->is_extended_format = true;
+ packet->frame->is_rtr = false;
+
+ if (params->flags & FRESCAN_FP) {
+ // NOTE: frag id for fp is: FRESCAN_MX_IDS, so the servers can
+ // have IDs in the range (0 .. FRESCAN_MX_IDS-1)
+ frescan_id_set_field(&packet->frame->id,
+ FRESCAN_FIELD_FRAG_ID,
+ (uint32_t)FRESCAN_MX_IDS);
+
+ frescan_id_set_field(&packet->frame->id,
+ FRESCAN_FIELD_PRIO,
+ (uint32_t)params->prio);
+ } else {
+ // NOTE: the priority is put when the packet is dequeued
+ // and it is the priority of th server
+ frescan_id_set_field(&packet->frame->id,
+ FRESCAN_FIELD_FRAG_ID,
+ (uint32_t)params->ss);
+ }
+
+ frescan_id_set_field(&packet->frame->id,
+ FRESCAN_FIELD_DEST,
+ (uint32_t)params->to);
+
+ frescan_id_set_field(&packet->frame->id,
+ FRESCAN_FIELD_SRC,
+ (uint32_t)frescan_data[params->net].local_node);
+
+ frescan_id_set_field(&packet->frame->id,
+ FRESCAN_FIELD_CHAN,
+ (uint32_t)params->channel);
+
+ DEBUG(FRESCAN_SEND_ENABLE_DEBUG, "set the packet data bytes\n");
+ if (params->flags & FRESCAN_ASYNC) {
+ // allocate a buffer and copy the data
+ // NOTE: instead of this we could use a chain of frames but
+ // i think it would be inefficient since each one can only
+ // hold 8 user bytes and we need to write its headers.
+ FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
+ packet->buffer_head = (uint8_t *)malloc(size*sizeof(uint8_t)); // TODO: FREE IT!!!
+ FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
+ memcpy(packet->buffer_head, msg, size);
+ } else {
+ packet->buffer_head = (uint8_t *)msg;
+ }
+
+ packet->buffer_read_pointer = packet->buffer_head;
+ packet->buffer_pending_bytes = size;
+ pqueue = frescan_data[params->net].queues.tx_fp_queue;
+
+ DEBUG(FRESCAN_SEND_ENABLE_DEBUG, "enqueue the packet\n");
+ if (packet->flags & FRESCAN_FP) {
+ FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
+ ret = frescan_pqueue_enqueue(pqueue, packet, params->prio);
+ FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
+
+ if (ret != 0) {
+ FRESCAN_ERROR("could not enqueue the packet\n");
+ return -1;
+ }
+ } else {
+ FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
+ ret = frescan_servers_enqueue(params->net, params->ss, packet);
+ FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
+
+ if (ret != 0) {
+ FRESCAN_ERROR("could not enqueue the packet\n");
+ return -1;
+ }
+ }
+
+ FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
+ ret = frescan_hw_buffer_update(params->net);
+ FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
+
+ if (ret != 0) {
+ FRESCAN_ERROR("could not update hw buffer\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * frescan_recv - receive a message
+ *
+ * @params: the parameters needed by the protocol to receive the message
+ * @msg: the message buffer
+ * @size: the size of the message buffer
+ * @recv_bytes: the number of bytes received
+ * @from: the node that sent the message
+ * @prio: the priority of the message
+ *
+ * This is one of the main functions of the protocol and it provides the
+ * means to receive a message through the protocol stack.
+ */
+
+int frescan_recv(const frescan_recv_params_t *params,
+ uint8_t *msg,
+ const size_t size,
+ size_t *recv_bytes,
+ frescan_node_t *from,
+ frescan_prio_t *prio)
+{
+ int ret;
+ frescan_prio_queue_t *pqueue;
+ bool blocking;
+ frescan_packet_t *head, *packet;
+
+ if (params->flags & FRESCAN_SYNC) {
+ DEBUG(FRESCAN_RECV_ENABLE_DEBUG,
+ "receive a packet in blocking mode\n");
+ blocking = true;
+ } else {
+ DEBUG(FRESCAN_RECV_ENABLE_DEBUG,
+ "receive a packet in non-blocking mode\n");
+ blocking = false;
+ }
+
+ pqueue = frescan_data[params->net].queues.rx_channel_queues
+ [params->channel];
+
+ ret = frescan_pqueue_dequeue(pqueue, &head, prio, blocking);
+ if (ret != 0) {
+ FRESCAN_ERROR ("could not dequeue packet\n");
+ return -1;
+ }
+
+ if (head == NULL) {
+ if (blocking == false) {
+ DEBUG(FRESCAN_RECV_ENABLE_DEBUG,
+ "blocking false, no packets\n");
+ *recv_bytes = 0;
+ return 0;
+ } else {
+ FRESCAN_ERROR ("blocking true, and packet = null\n");
+ return -1;
+ }
+ }
+
+ DEBUG(FRESCAN_RECV_ENABLE_DEBUG,
+ "traverse the list of packets for this message\n");
+
+ *recv_bytes = 0;
+
+ FRESCAN_ACQUIRE_LOCK(&frescan_data[params->net].lock);
+
+ list_for_each_entry(packet, &head->msg_list, msg_list) {
+ // TODO: memory checks, delete the packets
+ memcpy(msg + *recv_bytes,
+ packet->frame->data,
+ packet->frame->dlc);
+ *recv_bytes += packet->frame->dlc;
+
+ *from = (frescan_node_t)frescan_id_get_field(packet->frame->id,
+ FRESCAN_FIELD_SRC);
+ DEBUG(FRESCAN_RECV_ENABLE_DEBUG,
+ "ID Packet, dlc: %u, frame pool pos: %u, from:%u\n",
+ packet->frame->dlc, packet->frame->pool_pos, *from);
+
+ ret = can_framespool_free(packet->frame);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not free frame\n");
+ return -1;
+ }
+
+ ret = frescan_packets_free(packet);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not free packet\n");
+ return -1;
+ }
+ }
+
+ ret = frescan_packets_free(head);
+
+ FRESCAN_RELEASE_LOCK(&frescan_data[params->net].lock);
+
+ if (ret != 0) {
+ FRESCAN_ERROR("could not free head packet\n");
+ return -1;
+ }
+
+ DEBUG(FRESCAN_RECV_ENABLE_DEBUG,
+ "received bytes: %u\n", *recv_bytes);
+
+ return 0;
+}
+
+
+/**
+ * frescan_hook_frame_recv - frame received hook
+ *
+ * This function will be called by the CAN driver's IRQ handler when a frame
+ * is received so we can store it in an appropiate queue.
+ *
+ * NOTE: in the future it could consist simply of signaling a semaphore to
+ * let a bottom half thread do the hard work.
+ */
+
+
+static int frescan_hook_frame_recv (const struct can_chip_t *chip,
+ struct can_frame_t *frame)
+{
+ int i, ret;
+ uint32_t prio, dest, src, channel, frag_id, frag_flag;
+ frescan_packet_t *packet, *head;
+ frescan_prio_queue_t *pqueue;
+ int net;
+
+ net = chip->minor;
+
+ DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG, "received a frame, net=%d\n", net);
+ DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG || FRESCAN_FRAG_ENABLE_DEBUG,
+ "%s %s, id=0x%X, dlc=%u, pool:%u\n",
+ (frame->is_extended_format) ? "Ext" : "Stnd",
+ (frame->is_rtr) ? "RTR Frame" : "DATA Frame",
+ frame->id,
+ frame->dlc,
+ frame->pool_pos);
+
+ for (i=0; i<frame->dlc; i++) {
+ DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG,
+ "data[%d] = 0x%X;\n", i, frame->data[i]);
+ }
+
+ prio = frescan_id_get_field(frame->id, FRESCAN_FIELD_PRIO);
+ dest = frescan_id_get_field(frame->id, FRESCAN_FIELD_DEST);
+ src = frescan_id_get_field(frame->id, FRESCAN_FIELD_SRC);
+ channel = frescan_id_get_field(frame->id, FRESCAN_FIELD_CHAN);
+ frag_id = frescan_id_get_field(frame->id, FRESCAN_FIELD_FRAG_ID);
+ frag_flag = frescan_id_get_field(frame->id, FRESCAN_FIELD_FRAG_FLAG);
+
+ DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG || FRESCAN_FRAG_ENABLE_DEBUG,
+ "prio:%u dest:%u src:%u chan:%u id:%u flag:%u\n",
+ prio, dest, src, channel, frag_id, frag_flag);
+ DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG,
+ "enqueue the packet in ID queue\n");
+
+ packet = frescan_packets_alloc();
+ if (packet == NULL) {
+ FRESCAN_ERROR("could not allocate packet\n");
+ return -1;
+ }
+
+ packet->frame = frame;
+
+ if (frag_id == FRESCAN_MX_IDS) {
+ head = frescan_data[net].id_fp_queues[src][prio];
+ } else {
+ head = frescan_data[net].id_queues[src][frag_id];
+ }
+
+ if (head == NULL) {
+ DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG ||
+ FRESCAN_FRAG_ENABLE_DEBUG,
+ "allocate head for id=%u\n", frag_id);
+ head = frescan_packets_alloc();
+ if (head == NULL) {
+ FRESCAN_ERROR("could not allocate packet\n");
+ return -1;
+ }
+
+ INIT_LIST_HEAD(&head->msg_list);
+
+ if (frag_id == FRESCAN_MX_IDS) {
+ frescan_data[net].id_fp_queues[src][prio] = head;
+ } else {
+ frescan_data[net].id_queues[src][frag_id] = head;
+ }
+ }
+
+ list_add_tail(&packet->msg_list, &head->msg_list);
+
+ if (frag_flag == false) {
+ DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG ||
+ FRESCAN_FRAG_ENABLE_DEBUG,
+ "message complete, move msg to channel\n");
+ // TODO: select the highest priority??
+ pqueue = frescan_data[net].queues.rx_channel_queues[channel];
+ ret = frescan_pqueue_enqueue(pqueue, head, prio);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not enqueue message in channel queue\n");
+ return -1;
+ }
+
+ if (frag_id == FRESCAN_MX_IDS) {
+ frescan_data[net].id_fp_queues[src][prio] = NULL;
+ } else {
+ frescan_data[net].id_queues[src][frag_id] = NULL;
+ }
+
+ } else {
+ DEBUG(FRESCAN_RX_HOOK_ENABLE_DEBUG ||
+ FRESCAN_FRAG_ENABLE_DEBUG,
+ "message not complete, wait for more fragments\n");
+ }
+
+ // NOTE: don't forget to free the frame and the packet when it is
+ // read by the user application
+
+ return 0;
+};
+
+/**
+ * frescan_hook_frame_sent - frame sent hook
+ *
+ * This function will be called by the CAN driver's IRQ handler when a frame
+ * is sent through the CAN bus so we can enqueue another one, signal a
+ * semaphore, consume sporadic server capacity...
+ */
+
+static int frescan_hook_frame_sent(const struct can_chip_t *chip)
+{
+ int ret;
+ frescan_packet_t *packet;
+ frescan_prio_queue_t *pqueue;
+ frescan_prio_t prio;
+ frescan_ss_t id;
+
+ packet = frescan_data[chip->minor].last_packet;
+ assert(packet != NULL);
+
+ id = frescan_id_get_field(packet->frame->id,
+ FRESCAN_FIELD_FRAG_ID);
+
+ DEBUG(FRESCAN_SENT_HOOK_ENABLE_DEBUG,
+ "frame sent, minor:%u flags:0x%X frag_id:0x%X\n",
+ chip->minor, packet->flags, id);
+
+ if (packet->flags & FRESCAN_SS) {
+ DEBUG(FRESCAN_SENT_HOOK_ENABLE_DEBUG,
+ "calling frame_sent + program repl for id:%u\n", id);
+
+ ret = frescan_servers_frame_sent(chip->minor, id, packet);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not let the server a frame was sent\n");
+ return -1;
+ }
+ }
+
+ DEBUG(FRESCAN_SENT_HOOK_ENABLE_DEBUG || FRESCAN_FRAG_ENABLE_DEBUG,
+ "last packet buffer_pending_bytes=%u\n",
+ packet->buffer_pending_bytes);
+
+ if (packet->buffer_pending_bytes > 0) {
+ if (packet->flags & FRESCAN_FP) {
+ prio = frescan_id_get_field(packet->frame->id,
+ FRESCAN_FIELD_PRIO);
+
+ DEBUG(FRESCAN_FRAG_ENABLE_DEBUG,
+ "requeue fp packet, prio:%u\n", prio);
+
+ pqueue = frescan_data[chip->minor].queues.tx_fp_queue;
+ ret = frescan_pqueue_requeue(pqueue, packet, prio);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not requeue the packet packet:%p flags:0x%X\n", packet, packet->flags);
+ return -1;
+ }
+ } else if (packet->flags & FRESCAN_SS) {
+ DEBUG(FRESCAN_FRAG_ENABLE_DEBUG,
+ "requeue server %u packet\n", id);
+ ret = frescan_servers_requeue(chip->minor, id, packet);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not requeue the packet\n");
+ return -1;
+ }
+ } else {
+ FRESCAN_ERROR("flags are not correct\n");
+ return -1;
+ }
+ } else {
+ DEBUG(FRESCAN_FRAG_ENABLE_DEBUG,
+ "all packet fragmets sent, freeing the packet\n");
+
+ ret = can_framespool_free(packet->frame);
+ if (ret != 0) {
+ FRESCAN_ERROR ("could not free the frame\n");
+ return ret;
+ }
+
+ ret = frescan_packets_free(packet);
+ if (ret != 0) {
+ FRESCAN_ERROR ("could not free the packet\n");
+ return ret;
+ }
+
+ // TODO: signal semaphore for send_sync
+ }
+
+ frescan_data[chip->minor].last_packet = NULL;
+
+ ret = frescan_hw_buffer_update(chip->minor);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not update hw buffer\n");
+ return -1;
+ }
+
+ return 0;
+};
+
+/**
+ * frescan_hook_frame_aborted - frame frame aborted hook
+ *
+ * This function will be called by the CAN driver's IRQ handler when a frame
+ * is aborted (because another frame with higher priority is waiting). We
+ * have to requeue the frame and update the buffer.
+ */
+
+static int frescan_hook_frame_aborted(const struct can_chip_t *chip)
+{
+ int ret;
+ frescan_packet_t *packet;
+ frescan_prio_queue_t *pqueue;
+ frescan_prio_t prio;
+ frescan_ss_t id;
+
+ packet = frescan_data[chip->minor].last_packet;
+
+ id = frescan_id_get_field(packet->frame->id,
+ FRESCAN_FIELD_FRAG_ID);
+
+ DEBUG(FRESCAN_SENT_HOOK_ENABLE_DEBUG,
+ "frame aborted, minor:%u flags:0x%X frag_id:0x%X\n",
+ chip->minor, packet->flags, id);
+
+ if (packet->flags & FRESCAN_FP) {
+ prio = frescan_id_get_field(packet->frame->id,
+ FRESCAN_FIELD_PRIO);
+
+ DEBUG(FRESCAN_FRAG_ENABLE_DEBUG,
+ "requeue fp packet, prio:%u\n", prio);
+
+ pqueue = frescan_data[chip->minor].queues.tx_fp_queue;
+ ret = frescan_pqueue_requeue(pqueue, packet, prio);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not requeue the packet\n");
+ return -1;
+ }
+ } else if (packet->flags & FRESCAN_SS) {
+ DEBUG(FRESCAN_FRAG_ENABLE_DEBUG,
+ "requeue server %u packet\n", id);
+
+ ret = frescan_servers_requeue(chip->minor, id, packet);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not requeue the packet\n");
+ return -1;
+ }
+ } else {
+ FRESCAN_ERROR("flags are not correct\n");
+ return -1;
+ }
+
+ frescan_data[chip->minor].last_packet = NULL;
+
+ ret = frescan_hw_buffer_update(chip->minor);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not update hw buffer\n");
+ return -1;
+ }
+
+ return 0;
+}
--- /dev/null
+/*!
+ * @file frescan.h
+ *
+ * @brief interface of the FRESCAN protocol
+ *
+ * @version 0.01
+ *
+ * @date 20-Feb-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This file contains the interface to the FRESCAN protocol
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _FRESCAN_H_
+#define _FRESCAN_H_
+
+#include "frescan_types.h"
+
+/**
+ * frescan_init - initializes the network and the internal structures
+ *
+ * @params: the initialization parameters
+ */
+
+int frescan_init(frescan_init_params_t *params);
+
+/**
+ * frescan_send - send a message
+ *
+ * @params: the parameters needed by the protocol to send the message
+ * @msg: the message buffer
+ * @size: the size of the message
+ *
+ * This is one of the main functions of the protocol and it provides the
+ * means to send a message through the protocol stack.
+ */
+
+int frescan_send(const frescan_send_params_t *params,
+ const uint8_t *msg,
+ const size_t size);
+
+/**
+ * frescan_recv - receive a message
+ *
+ * @params: the parameters needed by the protocol to receive the message
+ * @msg: the message buffer
+ * @size: the size of the message buffer
+ * @recv_bytes: the number of bytes received
+ * @from: the node that sent the message
+ * @prio: the priority of the message
+ *
+ * This is one of the main functions of the protocol and it provides the
+ * means to receive a message through the protocol stack.
+ */
+
+int frescan_recv(const frescan_recv_params_t *params,
+ uint8_t *msg,
+ const size_t size,
+ size_t *recv_bytes,
+ frescan_node_t *from,
+ frescan_prio_t *prio);
+
+#endif // _FRESCAN_H_
--- /dev/null
+/*!
+ * @file frescan_bwres.c
+ *
+ * @brief FRESCAN bandwidth reservation layer
+ *
+ * This module contains function to negotiate contracts and get the
+ * corresponding frescan sporadic servers.
+ *
+ * @version 0.01
+ *
+ * @date 1-Apr-2008
+ *
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#include "frsh.h"
+#include "frescan_bwres.h"
+#include "frescan_bwres_requests.h"
+#include "frescan_bwres_robjs.h"
+#include "frescan_bwres_messages.h"
+#include "frescan_bwres_threads.h"
+#include "frescan_bwres_analysis.h"
+#include "frescan_data.h"
+#include "frescan_debug.h"
+#include "frescan_config.h"
+#include "frescan_servers.h"
+
+/**
+ * frescan_bwres_init()
+ *
+ * Init the frescan bandwidth reservation layer
+ */
+
+int frescan_bwres_init(frescan_network_t net)
+{
+ int ret;
+ frescan_node_t node;
+ frescan_ss_t neg_msg_ss_id;
+ frescan_server_params_t server_params;
+ frescan_bwres_sa_init_params_t init_params;
+ frsh_contract_t neg_msgs_contract;
+ frsh_rel_time_t neg_msgs_budget;
+ frsh_rel_time_t neg_msgs_period;
+
+ init_params.min_prio = FRESCAN_BWRES_SS_MIN_PRIO;
+ init_params.max_prio = FRESCAN_BWRES_SS_MAX_PRIO;
+
+ if (frescan_data[net].local_node == FRESCAN_BWRES_MASTER_NODE) {
+ ret = frescan_bwres_sa_init(&frescan_data[net].scenario,
+ &init_params);
+ if (ret != 0) return ret;
+
+ // Add contracts for the negotiation messages
+ ret = frsh_contract_init(&neg_msgs_contract);
+ if (ret != 0) return ret;
+
+ neg_msgs_budget = frsh_usec_to_rel_time(
+ (long)FRESCAN_FRAME_TX_TIME_US *
+ FRESCAN_BWRES_NEG_MSG_BUDGET);
+
+ neg_msgs_period = frsh_usec_to_rel_time(
+ (long)FRESCAN_BWRES_NEG_MSG_PERIOD);
+
+ ret = frsh_contract_set_basic_params(&neg_msgs_contract,
+ &neg_msgs_budget,
+ &neg_msgs_period,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ if (ret != 0) return ret;
+
+ ret = frsh_contract_set_preemption_level
+ (&neg_msgs_contract, FRESCAN_BWRES_NEG_MSG_PRIO);
+ if (ret != 0) return ret;
+
+ for(node=0; node<FRESCAN_MX_NODES; node++) {
+ ret = freelist_init(&frescan_data[net].scenario.
+ ss_id_freelist[node],
+ FRESCAN_MX_IDS);
+ if (ret != 0) return ret;
+
+ ret = freelist_alloc(&frescan_data[net].scenario.
+ ss_id_freelist[node]);
+ if (ret < 0) return -1;
+
+ neg_msg_ss_id = (frescan_ss_t)ret;
+
+ DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
+ "manager node:%u b:(%d,%d) t:(%d,%d) p:%u ss:%u\n",
+ node,
+ neg_msgs_budget.tv_sec, neg_msgs_budget.tv_nsec,
+ neg_msgs_period.tv_sec, neg_msgs_period.tv_nsec,
+ FRESCAN_BWRES_NEG_MSG_PRIO,
+ neg_msg_ss_id);
+
+ ret = frescan_bwres_sa_add_contract
+ (&frescan_data[net].scenario,
+ neg_msg_ss_id,
+ node,
+ &neg_msgs_contract);
+ if (ret != 0) return ret;
+ }
+ }
+
+ server_params.budget = FRESCAN_BWRES_NEG_MSG_BUDGET;
+ server_params.period = frsh_rel_time_to_timespec(
+ frsh_usec_to_rel_time(
+ (long)FRESCAN_BWRES_NEG_MSG_PERIOD));
+ server_params.prio = FRESCAN_BWRES_NEG_MSG_PRIO;
+
+ ret = frescan_servers_create(net, &server_params,
+ &frescan_data[net].neg_messages_ss_id);
+ if (ret != 0) return ret;
+
+ DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "neg_msg_ss_id: %u\n",
+ frescan_data[net].neg_messages_ss_id);
+
+ ret = frescan_bwres_robjs_init(FRESCAN_BWRES_ROBJS_MX_CEILING);
+ if (ret != 0) return ret;
+
+ ret = frescan_bwres_requests_init(FRESCAN_BWRES_REQ_MX_CEILING);
+ if (ret != 0) return ret;
+
+ ret = frescan_messages_init(net);
+ if (ret != 0) return ret;
+
+ ret = frescan_manager_thread_create(net);
+ if (ret != 0) return ret;
+
+ ret = frescan_acceptor_thread_create(net);
+ if (ret != 0) return ret;
+
+ return 0;
+}
+
+/**
+ * frescan_bwres_group_change_mode_sync()
+ *
+ * 1.- allocate and prepare the GN request
+ * 2.- enqueue the request
+ * 3.- wait in the reply object for a reply
+ * (unless there are only cancellations)
+ * 4.- free the request
+ */
+
+int frescan_bwres_group_change_mode_sync
+ (frescan_network_t net,
+ const frsh_contracts_group_t *contracts_to_neg,
+ const frsh_contracts_group_t *contracts_to_reneg,
+ const frescan_ss_group_t *ss_to_reneg,
+ const frescan_ss_group_t *ss_to_cancel,
+ frescan_ss_group_t *ss_new,
+ bool *accepted)
+{
+ int ret;
+ frescan_bwres_request_id_t req;
+ frescan_bwres_request_data_t *req_data;
+
+ DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "preparing a GN request\n");
+
+ ret = frescan_bwres_requests_alloc(&req);
+ if (ret != 0) return ret;
+
+ ret = frescan_bwres_requests_get_data(req, &req_data);
+ if (ret != 0) return ret;
+
+ req_data->net = net;
+ req_data->type = FRESCAN_BWRES_REQ_GN;
+ req_data->req = req;
+ req_data->request_node = frescan_data[net].local_node;
+
+ if (contracts_to_neg == NULL) {
+ req_data->contracts_to_neg = &req_data->contracts_to_neg_data;
+ req_data->contracts_to_neg->size = 0;
+ } else {
+ req_data->contracts_to_neg =
+ (frsh_contracts_group_t *)contracts_to_neg;
+ }
+
+ if (contracts_to_reneg == NULL) {
+ req_data->contracts_to_reneg = &req_data->
+ contracts_to_reneg_data;
+ req_data->contracts_to_reneg->size = 0;
+ } else {
+ req_data->contracts_to_reneg = (frsh_contracts_group_t *)
+ contracts_to_reneg;
+ }
+
+ if (ss_to_reneg == NULL) {
+ req_data->ss_to_reneg = &req_data->ss_to_reneg_data;
+ req_data->ss_to_reneg->size = 0;
+ } else {
+ req_data->ss_to_reneg = (frescan_ss_group_t *)ss_to_reneg;
+ }
+
+ if (ss_to_cancel == NULL) {
+ req_data->ss_to_cancel = &req_data->ss_to_cancel_data;
+ req_data->ss_to_cancel->size = 0;
+ } else {
+ req_data->ss_to_cancel = (frescan_ss_group_t *)ss_to_cancel;
+
+ }
+
+ if (ss_new == NULL) {
+ req_data->ss_new = &req_data->ss_new_data;
+ req_data->ss_new->size = 0;
+ } else {
+ req_data->ss_new = ss_new;
+ }
+
+ ret = frescan_bwres_robjs_alloc(&req_data->robj, FRESCAN_BWRES_MX_PRIO);
+ if (ret != 0) return ret;
+
+ DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "enqueue the negotiation request\n");
+
+ ret = frescan_bwres_requests_enqueue(req);
+ if (ret != 0) return ret;
+
+ DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "wait for a reply\n");
+
+ ret = frescan_bwres_robjs_wait(req_data->robj);
+ if (ret != 0) return ret;
+
+ ret = frescan_bwres_robjs_free(req_data->robj);
+ if (ret != 0) return ret;
+
+ switch (req_data->return_value) {
+ case FRESCAN_BWRES_REQ_ACCEPTED:
+ DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation OK\n");
+ *accepted = true;
+ break;
+
+ case FRESCAN_BWRES_REQ_NOT_ACCEPTED:
+ DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation FAIL\n");
+ *accepted = false;
+ break;
+
+ default:
+ FRESCAN_ERROR("return_value unknown\n");
+ return -1;
+ }
+
+ ret = frescan_bwres_requests_free(req);
+ if (ret != 0) return ret;
+
+ return 0;
+}
+
+/**
+ * frescan_bwres_negotiate()
+ */
+
+int frescan_bwres_negotiate(frescan_network_t net,
+ const frsh_contract_t *contract,
+ frescan_ss_t *ss,
+ bool *accepted)
+{
+ int ret;
+ frsh_contracts_group_t contracts_to_neg;
+ frescan_ss_group_t ss_new;
+
+ contracts_to_neg.size = 1;
+ contracts_to_neg.contracts[0] = *contract;
+
+ ret = frescan_bwres_group_change_mode_sync
+ (net, &contracts_to_neg, NULL, NULL,
+ NULL, &ss_new, accepted);
+ if (ret != 0) return ret;
+
+ if (*accepted) {
+ *ss = ss_new.ss[0];
+ }
+
+ return 0;
+}
+
+/**
+ * frescan_bwres_renegotiate()
+ */
+
+int frescan_bwres_renegotiate(frescan_network_t net,
+ const frsh_contract_t *contract,
+ frescan_ss_t ss,
+ bool *accepted)
+{
+ frsh_contracts_group_t contracts_to_reneg;
+ frescan_ss_group_t ss_to_reneg;
+
+ contracts_to_reneg.size = 1;
+ contracts_to_reneg.contracts[0] = *contract;
+
+ ss_to_reneg.size = 1;
+ ss_to_reneg.ss[0] = ss;
+
+ return frescan_bwres_group_change_mode_sync
+ (net, NULL, &contracts_to_reneg, &ss_to_reneg,
+ NULL, NULL, accepted);
+}
+
+/**
+ * frescan_bwres_cancel()
+ */
+
+int frescan_bwres_cancel(frescan_network_t net,
+ frescan_ss_t ss)
+{
+ frescan_ss_group_t ss_to_cancel;
+
+ ss_to_cancel.size = 1;
+ ss_to_cancel.ss[0] = ss;
+
+ return frescan_bwres_group_change_mode_sync
+ (net, NULL, NULL, NULL, &ss_to_cancel, NULL, NULL);
+}
--- /dev/null
+/*!
+ * @file frescan_bwres.h
+ *
+ * @brief FRESCAN bandwidth reservation layer
+ *
+ * This module contains function to negotiate contracts and get the
+ * corresponding frescan sporadic servers.
+ *
+ * @version 0.01
+ *
+ * @date 1-Apr-2008
+ *
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _FRESCAN_BWRES_H_
+#define _FRESCAN_BWRES_H_
+
+#include "frescan_types.h"
+
+extern int frescan_bwres_init(frescan_network_t net);
+
+extern int frescan_bwres_group_change_mode_sync
+ (frescan_network_t net,
+ const frsh_contracts_group_t *contracts_to_neg,
+ const frsh_contracts_group_t *contracts_to_reneg,
+ const frescan_ss_group_t *ss_to_reneg,
+ const frescan_ss_group_t *ss_to_cancel,
+ frescan_ss_group_t *ss_new,
+ bool *accepted);
+
+extern int frescan_bwres_negotiate(frescan_network_t net,
+ const frsh_contract_t *contract,
+ frescan_ss_t *ss,
+ bool *accepted);
+
+extern int frescan_bwres_renegotiate(frescan_network_t net,
+ const frsh_contract_t *contract,
+ frescan_ss_t ss,
+ bool *accepted);
+
+extern int frescan_bwres_cancel(frescan_network_t net,
+ frescan_ss_t ss);
+
+// TODO: add functions for reservation requests
+
+#endif // _FRESCAN_BWRES_H_
--- /dev/null
+/*!
+ * @file frescan_bwres_analysis.c
+ *
+ * @brief FRESCAN bandwith reservation layer: sched analysis
+ *
+ * @version 0.02
+ *
+ * @date 3-Jul-2008
+ *
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @comments
+ *
+ * This module contains the scheduling analysis functions for the
+ * admission tests and spare capacity distribution of the bandwith
+ * reservation (bwres) layer.
+ *
+ * The module "frescan_bwres_mode_change" must be used to apply finally this
+ * new parameters to the sporadic servers following an appropriate mode
+ * change protocol.
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#include <math.h>
+#include <misc/timespec_operations.h>
+#include <misc/linux_list.h>
+#include <misc/freelist.h>
+#include "frescan_bwres_analysis.h"
+#include "frescan_debug.h"
+
+/**
+ * frescan_bwres_sa_init() - init the scenario
+ *
+ * Initialize the vres list and copy the initialization parameters
+ */
+
+int frescan_bwres_sa_init(frescan_bwres_sa_scenario_t *scenario,
+ const frescan_bwres_sa_init_params_t *params)
+{
+ int ret;
+ frsh_sa_scenario_init_data_t fsa_scenario_init_data;
+
+ INIT_LIST_HEAD(&scenario->vres_head.list);
+ scenario->init_params = *params;
+
+ ret = freelist_init(&scenario->fsa_vres_global_id_freelist,
+ FRESCAN_MX_NODES*FRESCAN_MX_IDS);
+ if (ret != 0) return ret;
+
+ fsa_scenario_init_data.min_priority = params->min_prio;
+ fsa_scenario_init_data.max_priority = params->max_prio;
+ fsa_scenario_init_data.ovhd_data.np =
+ frsh_rel_time_to_sa_time(frsh_usec_to_rel_time(0));
+
+ DEBUG(FRESCAN_BWRES_SA_ENABLE_DEBUG,
+ "init the scenario min_prio:%d max_prio:%d\n",
+ params->min_prio, params->max_prio);
+
+ ret = frsh_sa_scenario_init(&scenario->fsa_scenario,
+ &fsa_scenario_init_data);
+ if (ret != 0) return -1;
+
+ return 0;
+}
+
+/**
+ * frescan_bwres_sa_add_contract() - add a contract to the scenario
+ *
+ * create the corresponding vres structure and set its values, and add the
+ * vres to the vres list
+ */
+
+int frescan_bwres_sa_add_contract(frescan_bwres_sa_scenario_t *scenario,
+ frescan_ss_t ss,
+ frescan_node_t node,
+ const frsh_contract_t *contract)
+{
+ int ret;
+ frescan_bwres_vres_t *sa_vres = &scenario->vres_pool[node][ss];
+
+ sa_vres->contract = *contract;
+ sa_vres->node = node;
+ sa_vres->ss = ss;
+ sa_vres->old_c = 0;
+ sa_vres->old_t = 0;
+ sa_vres->old_p = 0;
+
+ ret = freelist_alloc(&scenario->fsa_vres_global_id_freelist);
+ if (ret < 0) return -1;
+
+ sa_vres->fsa_vres_global_id = (frsh_sa_vres_id_t)ret;
+
+ list_add_tail(&sa_vres->list,
+ &scenario->vres_head.list);
+
+ DEBUG(FRESCAN_BWRES_SA_ENABLE_DEBUG,
+ "add contract, node:%d ss:%d globalid:%d\n",
+ node, ss, sa_vres->fsa_vres_global_id);
+
+ DEBUG(FRESCAN_BWRES_SA_ENABLE_DEBUG,
+ "contract bmin=(%u,%u) tmax=(%u,%u) bmax=(%u,%u) tmin=(%u,%u) prio=%u\n",
+ contract->budget_min.tv_sec,
+ contract->budget_min.tv_nsec,
+ contract->period_max.tv_sec,
+ contract->period_max.tv_nsec,
+ contract->budget_max.tv_sec,
+ contract->budget_max.tv_nsec,
+ contract->period_min.tv_sec,
+ contract->period_min.tv_nsec,
+ contract->preemption_level);
+
+ ret = frsh_sa_scenario_add_vres(&scenario->fsa_scenario,
+ &sa_vres->contract,
+ sa_vres->fsa_vres_global_id);
+ if (ret != 0) return -1;
+
+ return 0;
+}
+
+/**
+ * frescan_bwres_sa_update_contract() - update a contract in the scenario
+ */
+
+int frescan_bwres_sa_update_contract(frescan_bwres_sa_scenario_t *scenario,
+ frescan_ss_t ss,
+ frescan_node_t node,
+ const frsh_contract_t *contract,
+ frsh_contract_t *old_contract)
+{
+ int ret;
+ frescan_bwres_vres_t *sa_vres = &scenario->vres_pool[node][ss];
+
+ if (old_contract != NULL) {
+ *old_contract = sa_vres->contract;
+ }
+
+ sa_vres->contract = *contract;
+
+ DEBUG(FRESCAN_BWRES_SA_ENABLE_DEBUG,
+ "update contract node:%d ss:%d globalid:%d\n",
+ node, ss, sa_vres->fsa_vres_global_id);
+
+ ret = frsh_sa_scenario_modify_vres(&scenario->fsa_scenario,
+ sa_vres->fsa_vres_global_id,
+ &sa_vres->contract);
+ if (ret != 0) return -1;
+
+ return 0;
+}
+
+/**
+ * frescan_bwres_sa_remove_contract() - remove a contract from the scenario
+ */
+
+int frescan_bwres_sa_remove_contract(frescan_bwres_sa_scenario_t *scenario,
+ frescan_ss_t ss,
+ frescan_node_t node,
+ frsh_contract_t *contract)
+{
+ int ret;
+ frescan_bwres_vres_t *sa_vres = &scenario->vres_pool[node][ss];
+
+ if (contract != NULL) {
+ *contract = sa_vres->contract;
+ }
+
+ DEBUG(FRESCAN_BWRES_SA_ENABLE_DEBUG,
+ "remove contract, node:%d ss:%d globalid:%d\n",
+ node, ss, sa_vres->fsa_vres_global_id);
+
+ ret = frsh_sa_scenario_del_vres(&scenario->fsa_scenario,
+ sa_vres->fsa_vres_global_id);
+ if (ret != 0) return -1;
+
+ ret = freelist_free(&scenario->fsa_vres_global_id_freelist,
+ sa_vres->fsa_vres_global_id);
+ if (ret < 0) return -1;
+
+ list_del(&sa_vres->list);
+
+ return 0;
+}
+
+/**
+ * frescan_bwres_sa_sched_test() - perform a scheduling test on the scenario
+ *
+ */
+
+int frescan_bwres_sa_sched_test(frescan_bwres_sa_scenario_t *scenario,
+ bool *is_schedulable)
+{
+ int ret;
+
+ DEBUG(FRESCAN_BWRES_SA_ENABLE_DEBUG, "init the fsa scenario\n");
+
+ ret = frsh_sa_init_analysis(&scenario->fsa_scenario);
+ if (ret != 0) return -1;
+
+ ret = frsh_sa_assign_priorities(&scenario->fsa_scenario);
+ if (ret != 0) return -1;
+
+ DEBUG(FRESCAN_BWRES_SA_ENABLE_DEBUG, "do scheduling test\n");
+
+ ret = frsh_sa_sched_test(&scenario->fsa_scenario, is_schedulable);
+ if (ret != 0) return -1;
+
+ DEBUG(FRESCAN_BWRES_SA_ENABLE_DEBUG, "%s\n",
+ (*is_schedulable) ? "OK" : "FAILED");
+
+ return 0;
+}
+
+/**
+ * frescan_bwres_sa_spare_capacity() - distribute the spare capacity
+ */
+
+int frescan_bwres_sa_spare_capacity(frescan_bwres_sa_scenario_t *scenario)
+{
+ int ret;
+
+ DEBUG(FRESCAN_BWRES_SA_ENABLE_DEBUG, "distribute sc\n");
+
+ ret = frsh_sa_distribute_spare(&scenario->fsa_scenario);
+ if (ret != 0) return -1;
+
+ return 0;
+}
--- /dev/null
+/*!
+ * @file frescan_bwres_analysis.h
+ *
+ * @brief FRESCAN bandwith reservation layer: sched analysis
+ *
+ * @version 0.02
+ *
+ * @date 3-Jul-2008
+ *
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @comments
+ *
+ * This module contains the scheduling analysis functions for the
+ * admission tests and spare capacity distribution of the bandwith
+ * reservation (bwres) layer.
+ *
+ * The module "frescan_bwres_mode_change" must be used to apply finally this
+ * new parameters to the sporadic servers following an appropriate mode
+ * change protocol.
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _FRESCAN_BWRES_ANALYSIS_H_
+#define _FRESCAN_BWRES_ANALYSIS_H_
+
+#include "frescan_types.h"
+
+/**
+ * frescan_bwres_sa_init() - init the scenario
+ *
+ * @scenario: the scenario (in out)
+ * @params: init params (in)
+ */
+
+extern int frescan_bwres_sa_init
+ (frescan_bwres_sa_scenario_t *scenario,
+ const frescan_bwres_sa_init_params_t *params);
+
+/**
+ * frescan_bwres_sa_add_contract() - add a contract to the scenario
+ *
+ * @scenario: the scenario (in out)
+ * @ss: the preallocated ss identificator (in)
+ * @node: the node this contract belongs to (in)
+ * @contract: the new contract (in)
+ */
+
+extern int frescan_bwres_sa_add_contract
+ (frescan_bwres_sa_scenario_t *scenario,
+ frescan_ss_t ss,
+ frescan_node_t node,
+ const frsh_contract_t *contract);
+
+/**
+ * frescan_bwres_sa_update_contract() - update a contract in the scenario
+ *
+ * @scenario: the scenario (in out)
+ * @ss: the ss identificator (in)
+ * @node: the node this contract belongs to (in)
+ * @contract: the values to update the contract (in)
+ * @old_contract: the values of the previous contract. if NULL
+ * no contract is returned (out)
+ */
+
+extern int frescan_bwres_sa_update_contract
+ (frescan_bwres_sa_scenario_t *scenario,
+ frescan_ss_t ss,
+ frescan_node_t node,
+ const frsh_contract_t *contract,
+ frsh_contract_t *old_contract);
+
+/**
+ * frescan_bwres_sa_remove_contract() - remove a contract from the scenario
+ *
+ * @scenario: the scenario (in out)
+ * @ss: the ss to remove (in)
+ * @node: the node this contract belongs to (in)
+ * @contract: if not null, returns a copy of the contract (out)
+ */
+
+extern int frescan_bwres_sa_remove_contract
+ (frescan_bwres_sa_scenario_t *scenario,
+ frescan_ss_t ss,
+ frescan_node_t node,
+ frsh_contract_t *contract);
+
+/**
+ * frescan_bwres_sa_sched_test() - perform a scheduling test on the scenario
+ *
+ * @scenario: the scenario (in out)
+ * @is_schedulable: if the scenario is schedulable or not (out)
+ */
+
+extern int frescan_bwres_sa_sched_test(frescan_bwres_sa_scenario_t *scenario,
+ bool *is_schedulable);
+
+/**
+ * frescan_bwres_sa_spare_capacity() - distribute the spare capacity
+ *
+ * @scenario: the scenario (in out)
+ */
+
+extern int frescan_bwres_sa_spare_capacity
+ (frescan_bwres_sa_scenario_t *scenario);
+
+#endif // _FRESCAN_BWRES_ANALYSIS_H_
--- /dev/null
+/*!
+ * @file frescan_bwres_fna.c
+ *
+ * @brief FRESCAN bandwidth reservation layer: FNA hooks
+ *
+ * This module contains hooks to integrate the FRESCAN protocol in FRSH
+ *
+ * @version 0.01
+ *
+ * @date 1-Apr-2008
+ *
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#include <math.h> /* ceil */
+
+#include "frsh.h" /* frsh_resource_id_t, .. */
+#include "frescan.h" /* frescan_init, ... */
+#include "frescan_bwres.h" /* frescan_bwres_init, ... */
+#include "frescan_types.h"
+#include "frescan_config.h"
+#include "fna.h" /* fna_vres_id_t, fna_endpoint_data_t */
+#include "frescan_debug.h" /* DEBUG, FRESCAN_ERROR */
+#include "frescan_servers.h"
+
+//////////////////////////////////////////////////////////////////////
+// INITIALIZATION
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * frescan_fna_init()
+ *
+ * This function will be hooked to the frsh_init function and it is
+ * intented to initialize the protocol and its structures.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_ALREADY_INITIALIZED:
+ * if the function has already been called before (with success) \n
+ *
+ **/
+int frescan_fna_init(const frsh_resource_id_t resource_id)
+{
+ int ret;
+ frescan_init_params_t init_params;
+
+ init_params.net = resource_id - FRESCAN_BWRES_FNA_NET_BASE;
+ init_params.node = FRESCAN_BWRES_FNA_LOCAL_NODE;
+ init_params.tx_fp_max_prio = FRESCAN_BWRES_TX_FP_MX_PRIO;
+ init_params.rx_num_of_channels = FRESCAN_BWRES_RX_NUM_CHANNELS;
+ init_params.rx_channel_max_prio = FRESCAN_BWRES_RX_CHAN_MX_PRIO;
+
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
+ "Initializing FRESCAN FNA node%u\n", init_params.node);
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) {
+ FRESCAN_ERROR ("could not init FRESCAN\n");
+ return ret;
+ }
+
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "Initializing BWRES\n");
+
+ ret = frescan_bwres_init(init_params.net);
+ if (ret != 0) {
+ FRESCAN_ERROR ("could not init BWRES\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+///////////////////////////////////////////////////////////////////
+// VIRTUAL RESOURCES
+///////////////////////////////////////////////////////////////////
+
+int frescan_fna_group_change_mode_sync
+ (const frsh_resource_id_t resource_id,
+ const frsh_contracts_group_t *contracts_to_neg,
+ const frsh_contracts_group_t *contracts_to_reneg,
+ const fna_vres_group_t *vres_to_reneg,
+ const fna_vres_group_t *vres_to_cancel,
+ fna_vres_group_t *new_vres)
+{
+ int ret, i;
+ bool accepted;
+ frescan_ss_group_t ss_to_reneg, ss_to_cancel, ss_new;
+
+ // convert fna_vres to ss
+ if (vres_to_reneg == NULL) {
+ ss_to_reneg.size = 0;
+ } else {
+ ss_to_reneg.size = vres_to_reneg->size;
+ if (ss_to_reneg.size > FRESCAN_BWRES_MAX_GROUP_OPS) {
+ FRESCAN_ERROR("FRESCAN_BWRES_MAX_GROUP_OPS small\n");
+ return -1;
+ }
+
+ for(i=0; i<ss_to_reneg.size; i++) {
+ ss_to_reneg.ss[i] =
+ (frescan_ss_t)vres_to_reneg->vres[i];
+ }
+ }
+
+ if (vres_to_cancel == NULL) {
+ ss_to_cancel.size = 0;
+ } else {
+ ss_to_cancel.size = vres_to_cancel->size;
+ if (ss_to_cancel.size > FRESCAN_BWRES_MAX_GROUP_OPS) {
+ FRESCAN_ERROR("FRESCAN_BWRES_MAX_GROUP_OPS small\n");
+ return -1;
+ }
+
+ for(i=0; i<ss_to_cancel.size; i++) {
+ ss_to_cancel.ss[i] =
+ (frescan_ss_t)vres_to_cancel->vres[i];
+ }
+ }
+
+ if ((contracts_to_neg != NULL) && (new_vres == NULL)) {
+ FRESCAN_ERROR("new_vres is NULL\n");
+ return -1;
+ }
+
+ // negotiate
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
+ "calling frescan_bwres_group_change_mode_sync\n");
+
+ ret = frescan_bwres_group_change_mode_sync
+ ((frescan_network_t)resource_id,
+ contracts_to_neg,
+ contracts_to_reneg,
+ &ss_to_reneg,
+ &ss_to_cancel,
+ &ss_new,
+ &accepted);
+ if (ret != 0) return -1;
+
+ if (accepted == false) {
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "negotiation not accepted\n");
+ return -1; // TODO: change to constant FNA_REJECTED
+ }
+
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "negotiation accepted\n");
+ // convert new ss to fna_vres
+ if (contracts_to_neg != NULL) {
+ new_vres->size = ss_new.size;
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
+ "new_vres->size:%d\n", new_vres->size);
+ for(i=0; i<new_vres->size; i++) {
+ new_vres->vres[i] = (fna_vres_id_t)ss_new.ss[i];
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
+ "new_vres->vres[%d]:%u\n", i, new_vres->vres[i]);
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * frescan_fna_contract_negotiate()
+ *
+ * The operation negotiates a contract and if accepted it will return
+ * a fna_vres_id_t. It will also check that the given contract_id is unique
+ * within the network.
+ *
+ * If the on-line admission test is enabled, it determines whether the
+ * contract can be admitted or not based on the current contracts
+ * established in the network. Then it creates the vres and
+ * recalculates all necessary parameters for the contracts already
+ * present in the system.
+ *
+ * This is a potentially blocking operation, it returns when the
+ * system has either rejected the contract, or admitted it and made it
+ * effective.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] contract The contract parameters to negotiate
+ * @param[out] vres The internal virtual resource id
+ *
+ * @return
+ * 0 if there are no errors (in this case it also means contract accepted) \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_TOO_MANY_VRES: if there is no space for more vres \n
+ * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
+ * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frescan_fna_contract_negotiate
+ (const frsh_resource_id_t resource_id,
+ const frsh_contract_t *contract,
+ fna_vres_id_t *vres)
+{
+ int ret;
+ frsh_contracts_group_t contracts_to_neg;
+ fna_vres_group_t new_vres;
+
+ contracts_to_neg.size = 1;
+ contracts_to_neg.contracts[0] = *contract;
+
+ ret = frescan_fna_group_change_mode_sync
+ (resource_id, &contracts_to_neg, NULL, NULL, NULL, &new_vres);
+ if (ret != 0) return ret;
+
+ *vres = new_vres.vres[0];
+ return 0;
+}
+
+/**
+ * frescan_fna_contract_renegotiate_sync()
+ *
+ * The operation renegotiates a contract for an existing vres. If
+ * the on-line admission test is enabled it determines whether the
+ * contract can be admitted or not based on the current contracts
+ * established in the system. If it cannot be admitted, the old
+ * contract remains in effect and an error is returned. If it can be
+ * admitted, it recalculates all necessary parameters for the
+ * contracts already present in the system and returns zero. This is a
+ * potentially blocking operation; it returns when the system has
+ * either rejected the new contract, or admitted it and made it
+ * effective.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id to renegotiate
+ * @param[in] new_contract The new contract
+ *
+ * @return
+ * 0 if there are no errors (in this case it also means contract accepted) \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
+ * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frescan_fna_contract_renegotiate_sync
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ const frsh_contract_t *new_contract)
+{
+ frsh_contracts_group_t contracts_to_reneg;
+ fna_vres_group_t vres_to_reneg;
+
+ contracts_to_reneg.size = 1;
+ contracts_to_reneg.contracts[0] = *new_contract;
+ vres_to_reneg.size = 1;
+ vres_to_reneg.vres[0] = vres;
+
+ return frescan_fna_group_change_mode_sync
+ (resource_id, NULL, &contracts_to_reneg,
+ &vres_to_reneg, NULL, NULL);
+}
+
+/**
+ * frescan_fna_contract_renegotiate_async()
+ *
+ * The operation enqueues a renegotiate operation for an existing
+ * vres, and returns immediately. The renegotiate operation is
+ * performed asynchronously, as soon as it is practical; meanwhile the
+ * system operation will continue normally. When the renegotiation is
+ * made, if the on-line admission test is enabled it determines
+ * whether the contract can be admitted or not based on the current
+ * contracts established in the system. If it cannot be admitted, the
+ * old contract remains in effect. If it can be admitted, it
+ * recalculates all necessary parameters for the contracts already
+ * present in the system.
+ *
+ * When the operation is completed, notification is made to the
+ * caller, if requested, via a signal. The status of the operation (in
+ * progress, admitted, rejected) can be checked with the
+ * frsh_vres_get_renegotiation_status() operation. The argument
+ * sig_notify can be FRSH_NULL_SIGNAL (no notification), or any FRSH
+ * signal value and in this case signal_info is to be sent with the signal.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id to renegotiate
+ * @param[in] new_contract The new contract
+ * @param[in] signal_to_notify Signal number to use to notify vres of
+ * the negotiation result. If FRSH_NULL_SIGNAL, no signal will be raised.
+ * @param[in] signal_info: Associated info that will come with the signal.
+ * This parameter will be ignored if signal_to_notify == FRSH_NULL_SIGNAL.
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL, or sig_notify is neither
+ * NULL nor a valid POSIX signal \n
+ *
+ **/
+int frescan_fna_contract_renegotiate_async
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ const frsh_contract_t *new_contract,
+ frsh_signal_t signal_to_notify,
+ frsh_signal_info_t signal_info)
+{
+ FRESCAN_ERROR("not implemented\n");
+ return -1;
+}
+
+/**
+ * frescan_fna_vres_get_renegotiation_status()
+ *
+ * The operation reports on the status of the last renegotiation
+ * operation enqueued for the specified vres. It is callable even
+ * after notification of the completion of such operation, if
+ * requested.
+ *
+ * If the vres is not and has not been involved in any of the
+ * frsh_contract_renegotiate_async() or frsh_group_change_mode_async()
+ * operations, the status returned is FNA_NOT_REQUESTED
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id we want the status from
+ * @param[in] renegotiation_status The status of the last renegotiation on
+ * vres (FRSH_RS_IN_PROGRESS, FRSH_RS_REJECTED, FRSH_RS_ADMITTED,
+ * FRSH_RS_NOT_REQUESTED)
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frescan_fna_vres_get_renegotiation_status
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ frsh_renegotiation_status_t *renegotiation_status)
+{
+ FRESCAN_ERROR("not implemented\n");
+ return -1;
+}
+
+/**
+ * frescan_fna_vres_destroy()
+ *
+ * The operation eliminates the specified vres
+ * and recalculates all necessary parameters for the contracts
+ * remaining in the system. This is a potentially blocking operation;
+ * it returns when the system has made the changes effective.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id to destroy
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frescan_fna_vres_destroy
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres)
+{
+ fna_vres_group_t vres_to_cancel;
+
+ vres_to_cancel.size = 1;
+ vres_to_cancel.vres[0] = vres;
+
+ return frescan_fna_group_change_mode_sync
+ (resource_id, NULL, NULL, NULL, &vres_to_cancel, NULL);
+}
+
+/**
+ * frescan_fna_vres_get_contract()
+ *
+ * This operation stores the contract parameters currently associated
+ * with the specified vres in the variable pointed to by
+ * contract. It returns an error if the vres_id is not recognised.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id
+ * @param[out] contract The contract parameters that we want
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frescan_fna_vres_get_contract
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ frsh_contract_t *contract)
+{
+ FRESCAN_ERROR("not implemented\n");
+ return -1;
+}
+
+/**
+ * frescan_fna_vres_get_usage()
+ *
+ * This function gets the execution time spent by all messages that have been
+ * sent through the specified vres.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id
+ * @param[out] usage Execution time spent by this vres
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frescan_fna_vres_get_usage
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ struct timespec *usage)
+{
+ FRESCAN_ERROR("not implemented\n");
+ return -1;
+}
+
+/**
+ * frescan_fna_vres_get_remaining_budget()
+ *
+ * This function stores in the variable pointed to by budget the
+ * remaining execution-time budget associated with the specified
+ * vres in the present period.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id
+ * @param[out] remaining_budget The remaining budget for this period
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frescan_fna_vres_get_remaining_budget
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ struct timespec *remaining_budget)
+{
+ FRESCAN_ERROR("not implemented\n");
+ return -1;
+}
+
+/**
+ * frescan_fna_vres_get_budget_and_period()
+ *
+ * This function gets the budget and period associated with the specified vres
+ * for each period. If one of these pointers is NULL, the corresponding
+ * information is not stored.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id
+ * @param[out] budget The budget associated to vres
+ * @param[out] period The period associated to vres
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if both pointers are NULL \n
+ *
+ **/
+int frescan_fna_vres_get_budget_and_period
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ struct timespec *budget,
+ struct timespec *period)
+{
+ int ret;
+ frescan_server_params_t server_params;
+
+ ret = frescan_servers_get_data((frescan_network_t)resource_id,
+ &server_params,
+ (frescan_ss_t)vres);
+ if (ret != 0) return ret;
+
+ *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US *
+ server_params.budget);
+
+ *period = server_params.period;
+
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
+ "budget(%d packets %ld us\n",
+ server_params.budget, frsh_rel_time_to_usec(*budget));
+
+ return 0;
+}
+
+/*@}*/
+
+///////////////////////////////////////////////////////////////////
+// SPARE CAPACITY FUNCIONS
+///////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup fnaspare FNA Spare Capacity
+ * @ingroup fna
+ *
+ * The following functions are used to get spare capacity data
+ *
+ * @{
+ **/
+
+/**
+ * frescan_fna_resource_get_capacity()
+ *
+ * This operation gets the spare capacity currently assigned to a importance
+ * level. If we divide this value by UINT32_MAX we will get the network
+ * utilization associated to the spare capacity of a importance level.
+ *
+ * The following is typically in stdint.h: \n
+ * - typedef unsigned int uint32_t; \n
+ * - # define UINT32_MAX (4294967295U) \n
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] importance The importance we want the capacity of
+ * @param[out] capacity The spare capacity for that importance level
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frescan_fna_resource_get_capacity
+ (const frsh_resource_id_t resource_id,
+ const int importance,
+ uint32_t *capacity)
+{
+ FRESCAN_ERROR("not implemented\n");
+ return -1;
+}
+
+/**
+ * frescan_fna_resource_get_total_weight()
+ *
+ * This function gets the sum of the weight parameters for all vres in a
+ * network of an importance level.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] importance The importance we want the total weight of
+ * @param[out] total_weight The total weight for that importance level
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frescan_fna_resource_get_total_weight
+ (const frsh_resource_id_t resource_id,
+ const int importance,
+ int *total_weight)
+{
+ FRESCAN_ERROR("not implemented\n");
+ return -1;
+}
+
+/**
+ * frescan_fna_vres_decrease_capacity()
+ *
+ * This function allows to ask for less budget and period than what we
+ * received. The request must be compatible with the rest of contract
+ * parameters of the vres. If we want to recover the released capacity
+ * we will need to renegotiate.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id
+ * @param[in] new_budget The new_budget
+ * @param[in] new_period The new Period
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ * FNA_ERR_CONTRACT_REJECTED: if it is incompatible with the current
+ * contract \n
+ *
+ **/
+int frescan_fna_vres_decrease_capacity
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ const struct timespec new_budget,
+ const struct timespec new_period)
+{
+ FRESCAN_ERROR("not implemented\n");
+ return -1;
+}
+
+///////////////////////////////////////////////////////////////////
+// SEND RECEIVE OPERATIONS
+///////////////////////////////////////////////////////////////////
+
+/**
+ * frescan_fna_send_sync()
+ *
+ * Similar to previous function but now the sending thread gets blocked
+ * until the message is already sent to the network.
+ *
+ * @param[in] endpoint The send endpoint we are sending through. It must
+ * be bound to a virtual resource (resource_id is in the endpoint).
+ * @param[in] msg The message we want to send
+ * @param[in] size The size in bytes of the message
+ *
+ * @returns
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
+ * FNA_ERR_BUFFER_FULL: if the message has been discarded because
+ * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
+ *
+ **/
+int frescan_fna_send_sync
+ (const fna_endpoint_data_t *endpoint,
+ const void *msg,
+ const size_t size)
+{
+ FRESCAN_ERROR("not implemented\n");
+ return -1;
+}
+
+/**
+ * frescan_fna_send_async()
+ *
+ * This operation sends a message stored in msg and of length size
+ * through the given send endpoint. The operation is non-blocking and
+ * returns immediately.
+ *
+ * @param[in] endpoint The send endpoint we are sending through. It must
+ * be bound to a virtual resource (resource_id is in the endpoint).
+ * @param[in] msg The message we want to send
+ * @param[in] size The size in bytes of the message
+ *
+ * @returns
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
+ * FNA_ERR_BUFFER_FULL: if the message has been discarded because
+ * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
+ *
+ **/
+int frescan_fna_send_async
+ (const fna_endpoint_data_t *endpoint,
+ const void *msg,
+ const size_t size)
+{
+ int ret;
+ frescan_send_params_t params;
+
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
+ "net:%u dest:%u chan:%u size:%u ss:%u\n",
+ endpoint->resource_id, endpoint->destination,
+ endpoint->stream_id, size, endpoint->vres);
+
+ params.net = (frescan_network_t)endpoint->resource_id;
+ params.to = (frescan_node_t)endpoint->destination;
+ params.channel = (frescan_channel_t)endpoint->stream_id;
+ params.flags = FRESCAN_SS | FRESCAN_ASYNC;
+ params.ss = endpoint->vres;
+
+ ret = frescan_send(¶ms, (uint8_t *)msg, size);
+ if (ret != 0) {
+ FRESCAN_ERROR ("could not send message\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * frescan_fna_receive_sync()
+ *
+ * This operation is used to receive messages from the network with a
+ * blocking behavior (if there are no messages this operation blocks
+ * the calling thread).
+ *
+ * When a message is available, it is copied to buffer (up to its size).
+ * The number of bytes copied is returned in received_bytes. The rest
+ * of the bytes of that message will be lost or not depending on the
+ * protocol (FNA_ERR_NO_SPACE will be returned if it is).
+ *
+ * The function fails with FNA_ERR_NO_SPACE if the buffersize is
+ * too small for the message received. In this case the message is
+ * lost.
+ *
+ * Messages arriving at a receiver buffer that is full will be handled
+ * according to the queueing policy of the endpoint (overwrite oldest,
+ * discard it,etc).
+ *
+ * @param[in] endpoint The receive endpoint we are receiving from.
+ * (resource_id is in the endpoint).
+ * @param[out] buffer Buffer for storing the received message
+ * @param[in] buffer_size The size in bytes of this buffer
+ * @param[out] received_bytes The actual number of received bytes
+ * @param[out] from Address of the sender node
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ * FNA_ERR_NO_SPACE: if the message size is bigger than the
+ * provided buffer. \n
+ *
+ **/
+int frescan_fna_receive_sync
+ (const fna_endpoint_data_t *endpoint,
+ void *buffer,
+ const size_t buffer_size,
+ size_t *received_bytes,
+ frsh_network_address_t *from)
+{
+ int ret;
+ frescan_recv_params_t params;
+ frescan_node_t frescan_from;
+ frescan_prio_t prio;
+
+ params.net = (frescan_network_t)endpoint->resource_id;
+ params.channel = (frescan_channel_t)endpoint->stream_id;
+ params.flags = FRESCAN_SYNC;
+
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
+ "net:%u chan:%u size:%u\n",
+ endpoint->resource_id, endpoint->stream_id, buffer_size);
+
+ ret = frescan_recv(¶ms, (uint8_t *)buffer, buffer_size,
+ received_bytes, &frescan_from, &prio);
+
+ if (ret != 0) {
+ FRESCAN_ERROR ("error while receiving message");
+ return -1;
+ }
+
+ *from = (frsh_network_address_t)frescan_from;
+
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
+ "msg received, from:%u bytes:%u prio:%u\n",
+ *from, *received_bytes, prio);
+
+ return 0;
+}
+
+/**
+ * frescan_fna_receive_async()
+ *
+ * This operation is similar to the previous one but it works in a non
+ * blocking (asynchronous) fashion. If no message is available it
+ * returns with error FNA_NO_MESSAGE.
+ *
+ * @param[in] endpoint The receive endpoint we are receiving from.
+ * (resource_id is in the endpoint).
+ * @param[out] buffer Buffer for storing the received message
+ * @param[in] buffer_size The size in bytes of this buffer
+ * @param[out] received_bytes The actual number of received bytes
+ * @param[out] from Address of the sender node
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ * FNA_ERR_NO_SPACE: if the message size is bigger than the
+ * provided buffer. \n
+ * FNA_NO_MESSAGE: if no messages are available in the queue. \n
+ *
+ **/
+int frescan_fna_receive_async
+ (const fna_endpoint_data_t *endpoint,
+ void *buffer,
+ const size_t buffer_size,
+ size_t *received_bytes,
+ frsh_network_address_t *from)
+{
+ FRESCAN_ERROR("not implemented\n");
+ return -1;
+}
+
+/**
+ * frescan_fna_send_endpoint_get_status()
+ *
+ * This function tells the number of messages still pending in the
+ * endpoint queue, whether the network is up or down with some
+ * optional information which is protocol_dependent.
+ *
+ * @param[in] endpoint The send endpoint (resource_id is in the endpoint).
+ * @param[out] number_of_pending_messages The number of pending messages
+ * @param[out] network_status How is the network (up, down..)
+ * @param[out] protocol_status Protocol dependent status info
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frescan_fna_send_endpoint_get_status
+ (const fna_endpoint_data_t *endpoint,
+ int *number_of_pending_messages,
+ frsh_endpoint_network_status_t *network_status,
+ frsh_protocol_status_t *protocol_status)
+{
+ FRESCAN_ERROR("not implemented\n");
+ return -1;
+}
+
+/**
+ * frescan_fna_receive_endpoint_created()
+ *
+ * This operation is a called from frsh_receive_endpoint_create with a
+ * receive_endpoint structure already filled.
+ *
+ * Receiving endpoints are not bound to any network vres, this is
+ * because don't originate any traffic.
+ *
+ * @param[in] endpoint the endpoint object.
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ **/
+int frescan_fna_receive_endpoint_created
+ (fna_endpoint_data_t *endpoint)
+{
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "receive endpoint created\n");
+ return 0;
+}
+
+/**
+ * frescan_fna_receive_endpoint_get_pending_messages
+ *
+ * This function tells the number of messages still pending in the
+ * endpoint queue, whether the network is up or down and some optional
+ * information which is protocol dependent.
+ *
+ * @param[in] endpoint The receive endpoint (resource_id is in the endpoint).
+ * @param[out] number_of_pending_messages The number of pending messages
+ * @param[out] network_status How is the network (up, down..)
+ * @param[out] protocol_status Protocol dependent status info
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frescan_fna_receive_endpoint_get_status
+ (const fna_endpoint_data_t *endpoint,
+ int *number_of_pending_messages,
+ frsh_endpoint_network_status_t *network_status,
+ frsh_protocol_status_t *protocol_status)
+{
+ FRESCAN_ERROR("not implemented\n");
+ return -1;
+}
+
+//////////////////////////////////////////////////////////////////////
+// NETWORK CONFIGURATION FUNCTIONS
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * frescan_fna_network_get_max_message_size()
+ *
+ * This operation gives the maximum number of bytes that can be sent
+ * at a time through the send function when using the network designated by
+ * 'resource_id' and sending it to 'destination'.
+ *
+ * If the application needs to send bigger messages it will have to
+ * split them.
+ *
+ * Some protocols, like IP, are capable of sending large messages
+ * (and use fragmentation internally) but other protocols don't.
+ *
+ * @param[in] resource_id The network we want the tx time from.
+ * @param[in] destination The destination address
+ * @param[out] max_size The maximum number of bytes for each message
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
+ * invalid \n
+ *
+ **/
+int frescan_fna_network_get_max_message_size
+ (const frsh_resource_id_t resource_id,
+ const frsh_network_address_t destination,
+ size_t *max_size)
+{
+ FRESCAN_ERROR("not implemented\n");
+ return -1;
+}
+
+/**
+ * frescan_fna_network_bytes_to_budget()
+ *
+ * This operation converts a number of bytes into a temporal budget for
+ * a specific network. Network overheads are not included here but are
+ * considered internally when negotiating a specific contract.
+ *
+ * @param[in] resource_id The network
+ * @param[in] nbytes Number of bytes
+ * @param[out] budget The network budget for nbytes
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or nbytes is less
+ * than zero \n
+ *
+ **/
+int frescan_fna_network_bytes_to_budget
+ (const frsh_resource_id_t resource_id,
+ const size_t nbytes,
+ frsh_rel_time_t *budget)
+{
+ int number_of_packets;
+
+ if (budget == NULL || nbytes < 0) {
+ return -1;
+ }
+
+ // number of FRESCAN frames (8 bytes)
+ number_of_packets = (int) ceil((double)nbytes / 8.0);
+ *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US *
+ number_of_packets);
+
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
+ "bytes: %d -> budget: %ld us\n",
+ nbytes, frsh_rel_time_to_usec(*budget));
+
+ return 0;
+}
+
+/**
+ * frescan_fna_network_budget_to_bytes()
+ *
+ * This operation converts a temporal budget into a number of bytes for
+ * a specific network. Network overheads are not included.
+ *
+ * @param[in] resource_id The network
+ * @param[in] budget The network budget for nbytes
+ * @param[out] nbytes Number of bytes
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
+ * an invalid time value \n
+ *
+ **/
+int frescan_fna_network_budget_to_bytes
+ (const frsh_resource_id_t resource_id,
+ const frsh_rel_time_t *budget,
+ size_t *nbytes)
+{
+ int number_of_packets;
+
+ if (budget == NULL || nbytes == NULL) {
+ return -1;
+ }
+
+ number_of_packets = frsh_rel_time_to_usec(*budget) /
+ FRESCAN_FRAME_TX_TIME_US;
+
+ *nbytes = number_of_packets * 8;
+
+ return 0;
+}
+
+/**
+ * frescan_fna_network_get_min_eff_budget()
+ *
+ * This operation gets the minimum effective budget for a network. Each message
+ * consumes a contracted budget in "chunks" (i.e: packets) that we call
+ * minimum effective budget.
+ *
+ * A negotiated contract, for N bytes in a period T, means that there is a
+ * virtual resource that reserves for the user:
+ *
+ * Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
+ *
+ * Note that if the user decides not to send these N bytes at once but, say,
+ * one byte at a time, it will consume one "CHUNK" at a time and the reserved
+ * budget will become exhausted before sending all the bytes.
+ *
+ * @param[in] resource_id The network
+ * @param[out] budget The network budget
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frescan_fna_network_get_min_eff_budget
+ (const frsh_resource_id_t resource_id,
+ struct timespec *budget)
+{
+ if (budget == NULL) {
+ return -1;
+ }
+
+ *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US);
+
+ return 0;
+}
+
+// GLOBAL variable to install the network protocol in FRESCOR
+
+fna_operations_t frescan_fna_operations = {
+#ifdef CONFIG_FNA_FRESCAN_CONNECTED
+ .fna_init = frescan_fna_init,
+ .fna_group_change_mode_sync = frescan_fna_group_change_mode_sync,
+ .fna_contract_negotiate = frescan_fna_contract_negotiate,
+ .fna_contract_renegotiate_sync = frescan_fna_contract_renegotiate_sync,
+ .fna_contract_renegotiate_async = frescan_fna_contract_renegotiate_async,
+ .fna_vres_get_renegotiation_status = frescan_fna_vres_get_renegotiation_status,
+ .fna_vres_destroy = frescan_fna_vres_destroy,
+ .fna_vres_get_contract = frescan_fna_vres_get_contract,
+ .fna_vres_get_usage = frescan_fna_vres_get_usage,
+ .fna_vres_get_remaining_budget = frescan_fna_vres_get_remaining_budget,
+ .fna_vres_get_budget_and_period = frescan_fna_vres_get_budget_and_period,
+ .fna_resource_get_capacity = frescan_fna_resource_get_capacity,
+ .fna_resource_get_total_weight = frescan_fna_resource_get_total_weight,
+ .fna_vres_decrease_capacity = frescan_fna_vres_decrease_capacity,
+ .fna_send_sync = frescan_fna_send_sync,
+ .fna_send_async = frescan_fna_send_async,
+ .fna_receive_sync = frescan_fna_receive_sync,
+ .fna_receive_async = frescan_fna_receive_async,
+ .fna_send_endpoint_get_status = frescan_fna_send_endpoint_get_status,
+ .fna_receive_endpoint_created = frescan_fna_receive_endpoint_created,
+ .fna_receive_endpoint_get_status = frescan_fna_receive_endpoint_get_status,
+#endif
+ .fna_network_get_max_message_size = frescan_fna_network_get_max_message_size,
+ .fna_network_bytes_to_budget = frescan_fna_network_bytes_to_budget,
+ .fna_network_budget_to_bytes = frescan_fna_network_budget_to_bytes,
+ .fna_network_get_min_eff_budget = frescan_fna_network_get_min_eff_budget
+};
--- /dev/null
+/*!
+ * @file frescan_bwres_fna.h
+ *
+ * @brief FRESCAN bandwidth reservation layer: FNA hooks
+ *
+ * This module contains hooks to integrate the FRESCAN protocol in FRSH
+ *
+ * @version 0.01
+ *
+ * @date 1-Apr-2008
+ *
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _FRESCAN_FNA_H_
+#define _FRESCAN_FNA_H_
+
+#include "fna.h" // for fna_operations_t
+
+extern fna_operations_t frescan_fna_operations;
+
+#endif // _FRESCAN_FNA_H_
+
--- /dev/null
+/*!
+ * @file frescan_bwres_frsh_fna.h
+ *
+ * @brief FRESCAN bandwidth reservation layer: FRSH FNA public functions
+ *
+ * This module contains FNA functions that need to be public mainly
+ * for mapping between network types and FNA or FRSH types.
+ *
+ * @version 0.01
+ *
+ * @date 1-Apr-2008
+ *
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#include "frsh_fna.h"
+#include "frescan.h"
+#include "frescan_debug.h"
+
+//////////////////////////////////////////////////////////////////////
+// MAPPING FUNCTIONS
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * frsh_XXXX_map_network_address()
+ *
+ * To map a XXXX protocol network address into a FRSH address.
+ * The protocol must keep this mapping consistent. Instead of using a function
+ * a hardwired mapping could be used.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] in_address The network address we want to map to a frsh address
+ * @param[out] out_address The FRSH abstract network address
+ *
+ * @return
+ * FNA_NO_ERROR: in this case it also means contract accepted \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frsh_frescan_map_network_address
+ (const frsh_resource_id_t resource_id,
+ const frescan_node_t in_address,
+ frsh_network_address_t *out_address)
+{
+ if (out_address == NULL) return -1;
+ *out_address = in_address;
+ return 0;
+}
+
+/**
+ * frsh_XXXX_map_stream_id()
+ *
+ * To map a XXXX protocol network stream, port, channel... into a FRSH stream.
+ * The protocol must keep this mapping consistent. Instead of using a function
+ * a hardwired mapping could be used.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] in_stream The network stream we want to map to a FRSH stream
+ * @param[out] out_stream The FRSH abstract network stream
+ *
+ * @return
+ * FNA_NO_ERROR: in this case it also means contract accepted \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frsh_frescan_map_stream_id
+ (const frsh_resource_id_t resource_id,
+ const frescan_channel_t in_stream,
+ frsh_stream_id_t *out_stream)
+{
+ if (out_stream == NULL) return -1;
+ *out_stream = in_stream;
+ return 0;
+}
+
+///////////////////////////////////////////////////////////////////
+// NEGOTIATION SERVICE PARAMETERS
+///////////////////////////////////////////////////////////////////
+
+/**
+ * frsh_XXXX_negotiation_messages__vres_renegotiate()
+ *
+ * This function allows the application to change the minimum period
+ * of the negotiation messages sent through the network. It is similar
+ * to the service thread but for the network messages. We do not provide
+ * budget here because the size of the negotiation messages is fixed.
+ *
+ * This change is similar to a renegotiation so a schedulability test
+ * must be done to see if the change can be accepted or not.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] period The new period for negotiation messages
+ * @param[out] accepted If the change has been accepted or not
+ *
+ * @return
+ * FNA_NO_ERROR: in this case it also means contract accepted \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+
+int frsh_frescan_negotiation_messages_vres_renegotiate
+ (const frsh_resource_id_t resource_id,
+ const struct timespec *period)
+{
+ FRESCAN_ERROR("not implemented\n");
+ return -1;
+}
+
+/**
+ * frsh_XXXX_negotiation_messages_vres_get_period()
+ *
+ * This function gets the minimum period of the negotiation messages
+ * sent through the network.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[out] period The period for negotiation messages
+ *
+ * @return
+ * FNA_NO_ERROR: in this case it also means contract accepted \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frsh_frescan_negotiation_messages_vres_get_period
+ (const frsh_resource_id_t resource_id,
+ struct timespec *period)
+{
+ FRESCAN_ERROR("not implemented\n");
+ return -1;
+}
+
+/**
+ * frsh_XXXX_service_thread_vres_renegotiate()
+ *
+ * This function allows the application to change the period and
+ * budget of the service thread that makes the negotiations and
+ * schedulability tests in a network.
+ *
+ * The service thread starts with a default budget and period that
+ * should be configurable
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] budget The new budget for the service thread
+ * @param[in] period The new period for the service thread
+ * @param[out] accepted If the negotiation has been accepted or not
+ *
+ * @return
+ * FNA_NO_ERROR: in this case it also means contract accepted \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frsh_frescan_service_thread_vres_renegotiate
+ (const frsh_resource_id_t resource_id,
+ const struct timespec *budget,
+ const struct timespec *period,
+ bool *accepted)
+{
+ FRESCAN_ERROR("not implemented\n");
+ return -1;
+}
+
+/**
+ * frsh_XXXX_service_thread_vres_get_budget_and_period()
+ *
+ * This function gets the budget and period of a service thread.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[out] budget The budget of the service thread
+ * @param[out] period The period of the service thread
+ *
+ * @return
+ * FNA_NO_ERROR: in this case it also means contract accepted \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frsh_frescan_service_thread_vres_get_budget_and_period
+ (const frsh_resource_id_t resource_id,
+ struct timespec *budget,
+ struct timespec *period)
+{
+ FRESCAN_ERROR("not implemented\n");
+ return -1;
+}
--- /dev/null
+/*!
+ * @file frescan_bwres_messages.c
+ *
+ * @brief FRESCAN bandwidth reservation layer: negotiation messages formating
+ *
+ * This module contains the data types that define the FRESCAN negotiation
+ * message format and operations to convert them into or from negotiation
+ * requests
+ *
+ * @version 0.01
+ *
+ * @date 2-Apr-2008
+ *
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#include <string.h>
+#include "frescan_bwres_messages.h"
+#include "frescan_bwres_requests.h"
+#include "frescan.h"
+#include "frescan_servers.h"
+#include "frescan_data.h"
+#include "frescan_config.h"
+#include "frescan_debug.h"
+#include "frsh_distributed.h"
+
+#define FRESCAN_BWRES_MX_MSG_SIZE 5000 // TODO: adjust to the accurate value
+
+/**
+ * frescan_messages_init()
+ */
+
+static frescan_send_params_t send_params[FRESCAN_MX_NETWORKS];
+static frescan_recv_params_t recv_params[FRESCAN_MX_NETWORKS];
+
+int frescan_messages_init(frescan_network_t net)
+{
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "initialization\n");
+
+ send_params[net].net = net;
+ send_params[net].channel = FRESCAN_BWRES_NEG_MSG_CHAN;
+ send_params[net].flags = FRESCAN_SS | FRESCAN_ASYNC;
+ send_params[net].ss = frescan_data[net].neg_messages_ss_id;
+ send_params[net].to = FRESCAN_BWRES_MASTER_NODE;
+
+ recv_params[net].net = net;
+ recv_params[net].channel = FRESCAN_BWRES_NEG_MSG_CHAN;
+ recv_params[net].flags = FRESCAN_SYNC;
+
+ return 0;
+}
+
+/**
+ * FRESCAN_BWRES_REQ_GN
+ * ====================
+ * This message is sent from a SLAVE to the MASTER when the slave wants
+ * to make a negotiation (including creating new vres, renegotiations and
+ * cancellations).
+ */
+
+static int frescan_request_to_gn_message
+ (const frescan_bwres_request_data_t *data,
+ uint8_t *msg,
+ size_t *size)
+{
+ int ret, i;
+ uint8_t *msg_begin, *msg_tmp;
+ size_t bytes_written;
+
+ msg_begin = msg;
+
+ // type: FRESCAN_GN_MESSAGE
+ *((uint8_t *)msg) = (uint8_t)FRESCAN_BWRES_REQ_GN;
+ bytes_written = sizeof(uint8_t);
+ msg = msg + bytes_written;
+
+ // req
+ *((frescan_bwres_request_id_t *)msg) = data->req;
+ bytes_written = sizeof(frescan_bwres_request_id_t);
+ msg = msg + bytes_written;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "GN message req:%u\n", data->req);
+
+ // NEG-GROUP
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "NEG-GROUP num contracts:%d\n", data->contracts_to_neg->size);
+
+ *((uint8_t *)msg) = (uint8_t)data->contracts_to_neg->size;
+ bytes_written = sizeof(uint8_t);
+ msg = msg + bytes_written;
+
+ for (i=0; i<data->contracts_to_neg->size; i++) {
+ // reserve 2 bytes for the size of the marshalled contract
+ msg_tmp = msg;
+ msg = msg + sizeof(uint16_t);
+ // marshal the contract
+ ret = frsh_contract_marshal
+ (&data->contracts_to_neg->contracts[i],
+ msg,
+ FRESCAN_BWRES_MX_MSG_SIZE - (msg - msg_begin),
+ &bytes_written);
+ if (ret != 0) {
+ FRESCAN_ERROR("frsh_contract_marshal return -1\n");
+ return -1;
+ }
+ // write the size and update the message pointer msg
+ *((uint16_t *)msg_tmp) = (uint16_t)bytes_written;
+ msg = msg + bytes_written;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "contract[%d].size:%u\n", i, bytes_written);
+ }
+
+ // RENEG-GROUP
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "RENEG-GROUP num contracts:%d\n",data->contracts_to_reneg->size);
+
+ *((uint8_t *)msg) = (uint8_t)data->contracts_to_reneg->size;
+ bytes_written = sizeof(uint8_t);
+ msg = msg + bytes_written;
+
+ for (i=0; i<data->contracts_to_reneg->size; i++) {
+ // write the ss
+ *((uint16_t *)msg) = (uint16_t)data->ss_to_reneg->ss[i];
+ bytes_written = sizeof(uint16_t);
+ msg = msg + bytes_written;
+ // reserve 2 bytes for the size of the marshalled contract
+ msg_tmp = msg;
+ msg = msg + sizeof(uint16_t);
+ // marshal the contract
+ ret = frsh_contract_marshal
+ (&data->contracts_to_reneg->contracts[i],
+ msg,
+ FRESCAN_BWRES_MX_MSG_SIZE - (msg - msg_begin),
+ &bytes_written);
+ if (ret != 0) {
+ FRESCAN_ERROR("frsh_contract_marshal return -1\n");
+ return -1;
+ }
+ // write the size and update the message pointer msg
+ *((uint16_t *)msg_tmp) = (uint16_t)bytes_written;
+ msg = msg + bytes_written;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "contract[%d].size:%u ss[%d]:%u\n",
+ i, bytes_written, i, data->ss_to_reneg->ss[i]);
+ }
+
+ // CANCEL-GROUP
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "CANCEL-GROUP num ss:%d\n",
+ data->ss_to_cancel->size);
+
+ *((uint8_t *)msg) = (uint8_t)data->ss_to_cancel->size;
+ bytes_written = sizeof(uint8_t);
+ msg = msg + bytes_written;
+
+ for (i=0; i<data->ss_to_cancel->size; i++) {
+ // write the ss
+ *((uint16_t *)msg) = (uint16_t)data->ss_to_cancel->ss[i];
+ bytes_written = sizeof(uint16_t);
+ msg = msg + bytes_written;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "ss[%d]:%u\n", i, data->ss_to_cancel->ss[i]);
+ }
+
+ *size = msg - msg_begin;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "size:%u\n", *size);
+
+ return 0;
+}
+
+static int frescan_gn_message_to_request(const uint8_t *msg_to_parse,
+ frescan_bwres_request_data_t *data,
+ size_t size)
+{
+ int ret, i;
+ uint8_t *msg;
+ size_t bytes_read, contract_size;
+
+ msg = (uint8_t *)msg_to_parse;
+
+ data->contracts_to_neg = &data->contracts_to_neg_data;
+ data->contracts_to_reneg = &data->contracts_to_reneg_data;
+ data->ss_to_reneg = &data->ss_to_reneg_data;
+ data->ss_to_cancel = &data->ss_to_cancel_data;
+ data->ss_new = &data->ss_new_data;
+
+ // req
+ data->req = *((frescan_bwres_request_id_t *)msg);
+ bytes_read = sizeof(frescan_bwres_request_id_t);
+ msg = msg + bytes_read;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "GN message req:%u\n", data->req);
+
+ // NEG-GROUP
+ data->contracts_to_neg->size = *((uint8_t *)msg);
+ bytes_read = sizeof(uint8_t);
+ msg = msg + bytes_read;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "NEG-GROUP num contracts:%u\n", data->contracts_to_neg->size);
+
+ for (i=0; i<data->contracts_to_neg->size; i++) {
+ contract_size = *((uint16_t *)msg);
+ bytes_read = sizeof(uint16_t);
+ msg = msg + bytes_read;
+
+ // unmarshal the contract
+ ret = frsh_contract_unmarshal
+ (&data->contracts_to_neg->contracts[i],
+ msg,
+ contract_size);
+ if (ret != 0) {
+ FRESCAN_ERROR("frsh_contract_unmarshal return -1\n");
+ return -1;
+ }
+
+ bytes_read = contract_size;
+ msg = msg + bytes_read;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "contract[%d].size:%u\n", i, contract_size);
+ }
+
+ // RENEG-GROUP
+ data->contracts_to_reneg->size = *((uint8_t *)msg);
+ bytes_read = sizeof(uint8_t);
+ msg = msg + bytes_read;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "RENEG-GROUP num contracts:%u\n",data->contracts_to_reneg->size);
+
+ for (i=0; i<data->contracts_to_reneg->size; i++) {
+ data->ss_to_reneg->ss[i] = *((uint16_t *)msg);
+ bytes_read = sizeof(uint16_t);
+ msg = msg + bytes_read;
+
+ contract_size = *((uint16_t *)msg);
+ bytes_read = sizeof(uint16_t);
+ msg = msg + bytes_read;
+
+ // unmarshal the contract
+ ret = frsh_contract_unmarshal
+ (&data->contracts_to_reneg->contracts[i],
+ msg,
+ contract_size);
+ if (ret != 0) {
+ FRESCAN_ERROR("frsh_contract_unmarshal return -1\n");
+ return -1;
+ }
+
+ bytes_read = contract_size;
+ msg = msg + bytes_read;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "contract[%d].size:%u ss[%d]:%u\n",
+ i, contract_size, i, data->ss_to_reneg->ss[i]);
+ }
+
+ // CANCEL-GROUP
+ data->ss_to_cancel->size = *((uint8_t *)msg);
+ bytes_read = sizeof(uint8_t);
+ msg = msg + bytes_read;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "CANCEL-GROUP num ss:%u\n", data->ss_to_cancel->size);
+
+ for (i=0; i<data->ss_to_cancel->size; i++) {
+ // write the ss
+ data->ss_to_cancel->ss[i] = *((uint16_t *)msg);
+ bytes_read = sizeof(uint16_t);
+ msg = msg + bytes_read;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "ss[%d]:%u\n", i, data->ss_to_cancel->ss[i]);
+ }
+
+ return 0;
+}
+
+/**
+ * FRESCAN_BWRES_REQ_MC
+ * ====================
+ * This message is sent from the MASTER to a slave when there is a change
+ * in the budget value assigned by the spare capacity algorithm.
+ */
+
+static int frescan_request_to_mc_message
+ (const frescan_bwres_request_data_t *data,
+ uint8_t *msg,
+ size_t *size)
+{
+ frescan_bwres_vres_t *vres;
+ uint8_t *msg_begin;
+ size_t bytes_written;
+
+ msg_begin = msg;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "MC send mode_change_type:0x%X\n", data->mode_change_type);
+
+ // type: FRESCAN_GN_MESSAGE
+ *((uint8_t *)msg) = (uint8_t)FRESCAN_BWRES_REQ_MC;
+ bytes_written = sizeof(uint8_t);
+ msg = msg + bytes_written;
+
+ // write the SS-mode_change_type-values fields
+ list_for_each_entry(vres,
+ &frescan_data[data->net].mode_change_list
+ [data->request_node],
+ mode_change_list)
+ {
+ if ((vres->mode_change_type & data->mode_change_type) !=
+ data->mode_change_type) continue;
+
+ *((frescan_ss_t *)msg) = vres->ss;
+ bytes_written = sizeof(frescan_ss_t);
+ msg = msg + bytes_written;
+
+ *((uint8_t *)msg) = (uint8_t)data->mode_change_type;
+ bytes_written = sizeof(uint8_t);
+ msg = msg + bytes_written;
+
+ if (data->mode_change_type & (FRESCAN_BWRES_MC_BUDGET_INC |
+ FRESCAN_BWRES_MC_BUDGET_DEC)) {
+ *((frsh_sa_time_t *)msg) = vres->old_c;
+ bytes_written = sizeof(frsh_sa_time_t);
+ msg = msg + bytes_written;
+ }
+
+ if (data->mode_change_type & (FRESCAN_BWRES_MC_PERIOD_INC |
+ FRESCAN_BWRES_MC_PERIOD_DEC)) {
+ *((frsh_sa_time_t *)msg) = vres->old_t;
+ bytes_written = sizeof(frsh_sa_time_t);
+ msg = msg + bytes_written;
+ }
+
+ if (data->mode_change_type & (FRESCAN_BWRES_MC_PRIO_INC |
+ FRESCAN_BWRES_MC_PRIO_DEC)) {
+ *((frsh_sa_prio_t *)msg) = vres->old_p;
+ bytes_written = sizeof(frsh_sa_prio_t);
+ msg = msg + bytes_written;
+ }
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "ss:%d c:%d t:%d p:%d\n",
+ vres->ss, vres->old_c, vres->old_t, vres->old_p);
+ }
+
+ *size = msg - msg_begin;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "size:%u\n", *size);
+
+ return 0;
+}
+
+static int frescan_mc_message_to_request(const uint8_t *msg_to_parse,
+ frescan_bwres_request_data_t *data,
+ size_t size)
+{
+ uint8_t *msg;
+ size_t bytes_read;
+ frescan_ss_t ss;
+ frescan_bwres_vres_t *vres;
+ frescan_node_t me;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "MC message received\n");
+
+ msg = (uint8_t *)msg_to_parse;
+ me = frescan_data[data->net].local_node;
+ data->mode_change_type = 0;
+
+ INIT_LIST_HEAD(&frescan_data[data->net].mode_change_list[me]);
+
+ while(msg < msg_to_parse + size) {
+ ss = *((frescan_ss_t *)msg);
+ bytes_read = sizeof(frescan_ss_t);
+ msg = msg + bytes_read;
+
+ vres = &frescan_data[data->net].scenario.vres_pool[me][ss];
+
+ vres->mode_change_type = *((uint8_t *)msg);
+ bytes_read = sizeof(uint8_t);
+ msg = msg + bytes_read;
+
+ if (vres->mode_change_type & (FRESCAN_BWRES_MC_BUDGET_INC |
+ FRESCAN_BWRES_MC_BUDGET_DEC)) {
+ vres->old_c = *((frsh_sa_time_t *)msg);
+ bytes_read = sizeof(frsh_sa_time_t);
+ msg = msg + bytes_read;
+ }
+
+ if (vres->mode_change_type & (FRESCAN_BWRES_MC_PERIOD_INC |
+ FRESCAN_BWRES_MC_PERIOD_DEC)) {
+ vres->old_t = *((frsh_sa_time_t *)msg);
+ bytes_read = sizeof(frsh_sa_time_t);
+ msg = msg + bytes_read;
+ }
+
+ if (vres->mode_change_type & (FRESCAN_BWRES_MC_PRIO_INC |
+ FRESCAN_BWRES_MC_PRIO_DEC)) {
+ vres->old_p = *((frsh_sa_prio_t *)msg);
+ bytes_read = sizeof(frsh_sa_prio_t);
+ msg = msg + bytes_read;
+ }
+
+ if (vres->mode_change_type != 0) {
+ list_add_tail(&(vres->mode_change_list),
+ &(frescan_data[data->net].
+ mode_change_list[me]));
+ }
+
+ data->mode_change_type |= vres->mode_change_type;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "mc:0x%X ss:%d vres->ss:%d c:%d t:%d p:%d\n",
+ vres->mode_change_type, ss, vres->ss,
+ vres->old_c, vres->old_t, vres->old_p);
+ }
+
+ return 0;
+}
+
+/**
+ * FRESCAN_BWRES_REP_GN
+ * ====================
+ * This message is sent from the MASTER to a slave as a reply to a
+ * FRESCAN_BWRES_REQ_GN message
+ */
+
+static int frescan_request_to_rep_gn_message
+ (const frescan_bwres_request_data_t *data,
+ uint8_t *msg,
+ size_t *size)
+{
+ int i;
+ uint8_t *msg_begin;
+ size_t bytes_written;
+ frescan_bwres_vres_t *vres;
+
+ msg_begin = msg;
+
+ // type
+ *((uint8_t *)msg) = (uint8_t)FRESCAN_BWRES_REP_GN;
+ bytes_written = sizeof(uint8_t);
+ msg = msg + bytes_written;
+
+ // req
+ *((frescan_bwres_request_id_t *)msg) = data->req;
+ bytes_written = sizeof(frescan_bwres_request_id_t);
+ msg = msg + bytes_written;
+
+ // return value
+ *((uint8_t *)msg) = data->return_value;
+ bytes_written = sizeof(uint8_t);
+ msg = msg + bytes_written;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "req:%d return:%s\n", data->req,
+ (data->return_value == FRESCAN_BWRES_REQ_ACCEPTED)?"OK":"FAIL");
+
+ if (data->return_value == FRESCAN_BWRES_REQ_ACCEPTED) {
+ // new ss values
+ for(i=0; i<data->contracts_to_neg->size; i++) {
+ // SS
+ *((uint16_t *)msg) = data->ss_new->ss[i];
+ bytes_written = sizeof(uint16_t);
+ msg = msg + bytes_written;
+
+ // B - T - P
+ vres = &frescan_data[data->net].scenario.
+ vres_pool[data->request_node]
+ [data->ss_new->ss[i]];
+
+ *((frsh_sa_time_t *)msg) = vres->old_c;
+ bytes_written = sizeof(frsh_sa_time_t);
+ msg = msg + bytes_written;
+
+ *((frsh_sa_time_t *)msg) = vres->old_t;
+ bytes_written = sizeof(frsh_sa_time_t);
+ msg = msg + bytes_written;
+
+ *((frsh_sa_prio_t *)msg) = vres->old_p;
+ bytes_written = sizeof(frsh_sa_prio_t);
+ msg = msg + bytes_written;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "ss[%d]:%u b:%d t:%d p:%d\n",
+ i, data->ss_new->ss[i],
+ vres->old_c, vres->old_t, vres->old_p);
+ }
+ }
+
+ *size = msg - msg_begin;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "size:%u\n", *size);
+
+ return 0;
+}
+
+static int frescan_rep_gn_message_to_request
+ (const uint8_t *msg_to_parse,
+ frescan_bwres_request_data_t *data,
+ size_t size)
+{
+ int ret;
+ uint8_t *msg;
+ size_t bytes_read;
+ frescan_ss_t ss;
+ frescan_server_params_t server_params;
+ frescan_bwres_vres_t *vres;
+ frescan_node_t me;
+
+ me = frescan_data[data->net].local_node;
+
+ msg = (uint8_t *)msg_to_parse;
+
+ // req
+ data->req = *((frescan_bwres_request_id_t *)msg);
+ bytes_read = sizeof(frescan_bwres_request_id_t);
+ msg = msg + bytes_read;
+
+ // return_value
+ data->return_value = *((uint8_t *)msg);
+ bytes_read = sizeof(uint8_t);
+ msg = msg + bytes_read;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "req:%d return:%s\n", data->req,
+ (data->return_value == FRESCAN_BWRES_REQ_ACCEPTED)?"OK":"FAIL");
+
+ if (data->return_value != FRESCAN_BWRES_REQ_ACCEPTED) return 0;
+
+ // create the new sporadic servers
+ data->ss_new->size = 0;
+
+ while(msg < msg_to_parse + size) {
+ // SS
+ data->ss_new->ss[data->ss_new->size] = *((uint16_t *)msg);
+ bytes_read = sizeof(uint16_t);
+ msg = msg + bytes_read;
+
+ // Set values in the scenario (for mode changes)
+ vres = &frescan_data[data->net].scenario.vres_pool[me]
+ [data->ss_new->ss[data->ss_new->size]];
+
+ vres->ss = data->ss_new->ss[data->ss_new->size];
+ vres->node = me;
+
+ // Budget
+ vres->old_c = *((frsh_sa_time_t *)msg);
+ bytes_read = sizeof(frsh_sa_time_t);
+ msg = msg + bytes_read;
+
+ // Period
+ vres->old_t = *((frsh_sa_time_t *)msg);
+ bytes_read = sizeof(frsh_sa_time_t);
+ msg = msg + bytes_read;
+
+ // Prio
+ vres->old_p = *((frsh_sa_prio_t *)msg);
+ bytes_read = sizeof(frsh_sa_prio_t);
+ msg = msg + bytes_read;
+
+ // Create server
+ server_params.budget = frsh_rel_time_to_usec
+ (frsh_sa_time_to_rel_time(vres->old_c)) /
+ FRESCAN_FRAME_TX_TIME_US;
+ server_params.period = frsh_sa_time_to_rel_time(vres->old_t);
+ server_params.prio = vres->old_p;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "ss_master[%d]:%u ss[%d]:%u b:%d t:%d p:%d\n",
+ data->ss_new->size, data->ss_new->ss[data->ss_new->size],
+ data->ss_new->size, ss,
+ vres->old_c, vres->old_t, vres->old_p);
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "server_params[%d] b:%d t:(%d,%d) p:%d\n",
+ data->ss_new->size, server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+
+ ret = frescan_servers_create(data->net, &server_params, &ss);
+ if (ret != 0) return ret;
+
+ if (ss != data->ss_new->ss[data->ss_new->size]) {
+ FRESCAN_ERROR("ss from master(%u) != ss created(%u)\n",
+ data->ss_new->ss[data->ss_new->size], ss);
+ return -1;
+ }
+
+ data->ss_new->size++;
+ }
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "data->ss_new->size:%u\n", data->ss_new->size);
+
+ return 0;
+}
+
+/**
+ * frescan_messages_send_request()
+ *
+ * this function converts a request with the necessary data into a message
+ * and sends it.
+ *
+ * @req_data: the request to be sent (NOTE: the network is in req_data)
+ *
+ */
+
+int frescan_messages_send_request(const frescan_bwres_request_data_t *req_data)
+{
+ int ret;
+ uint8_t msg[FRESCAN_BWRES_MX_MSG_SIZE];
+ size_t size;
+
+ switch(req_data->type) {
+ case FRESCAN_BWRES_REQ_GN:
+ ret = frescan_request_to_gn_message
+ (req_data, msg, &size);
+ if (ret != 0) return ret;
+ send_params[req_data->net].to =
+ FRESCAN_BWRES_MASTER_NODE;
+ break;
+ case FRESCAN_BWRES_REQ_MC:
+ ret = frescan_request_to_mc_message
+ (req_data, msg, &size);
+ if (ret != 0) return ret;
+ send_params[req_data->net].to = req_data->request_node;
+ break;
+ case FRESCAN_BWRES_REP_GN:
+ ret = frescan_request_to_rep_gn_message
+ (req_data, msg, &size);
+ if (ret != 0) return ret;
+ send_params[req_data->net].to = req_data->request_node;
+ break;
+ case FRESCAN_BWRES_REQ_RES:
+ case FRESCAN_BWRES_REQ_RES_GET:
+ case FRESCAN_BWRES_REP_RES_GET:
+ case FRESCAN_BWRES_REQ_RES_SET:
+ case FRESCAN_BWRES_REQ_RES_COMMIT:
+ case FRESCAN_BWRES_REQ_RES_CANCEL:
+ default:
+ FRESCAN_ERROR("request type not supported\n");
+ return -1;
+ }
+
+ ret = frescan_send(&send_params[req_data->net], msg, size);
+ if (ret != 0) return ret;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "sent request, type:%X size:%u\n",
+ req_data->type, size);
+
+ return 0;
+}
+
+/**
+ * frescan_messages_recv_request()
+ *
+ * this function BLOCKS the calling thread until receives a message
+ * and transforms it into a request.
+ *
+ * @req_data: the request data to fill from the message bytes (out)
+ *
+ */
+
+int frescan_messages_recv_request(frescan_network_t net,
+ frescan_bwres_request_id_t *req)
+{
+ int ret;
+ uint8_t msg[FRESCAN_BWRES_MX_MSG_SIZE];
+ uint8_t *msg_to_parse;
+ size_t recv_bytes;
+ frescan_node_t from;
+ frescan_prio_t prio;
+ frescan_bwres_request_data_t *req_data;
+
+ ret = frescan_bwres_requests_alloc(req);
+ if (ret != 0) return ret;
+
+ ret = frescan_bwres_requests_get_data(*req, &req_data);
+ if (ret != 0) return ret;
+
+ ret = frescan_recv(&recv_params[net],
+ msg,
+ sizeof(msg),
+ &recv_bytes,
+ &from,
+ &prio);
+ if (ret != 0) return ret;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "msg received! from:%u size:%u prio:%u chan:%u flags:%X\n",
+ from, recv_bytes, prio, recv_params[net].channel,
+ recv_params[net].flags);
+
+ req_data->request_node = from;
+ req_data->net = net;
+ req_data->type = *((uint8_t *)msg);
+
+ msg_to_parse = msg + sizeof(uint8_t);
+ recv_bytes = recv_bytes - sizeof(uint8_t);
+
+ switch(req_data->type) {
+ case FRESCAN_BWRES_REQ_GN:
+ return frescan_gn_message_to_request(msg_to_parse,
+ req_data,
+ recv_bytes);
+ case FRESCAN_BWRES_REQ_MC:
+ return frescan_mc_message_to_request(msg_to_parse,
+ req_data,
+ recv_bytes);
+ case FRESCAN_BWRES_REP_GN:
+ return frescan_rep_gn_message_to_request(msg_to_parse,
+ req_data,
+ recv_bytes);
+ case FRESCAN_BWRES_REQ_RES:
+ case FRESCAN_BWRES_REQ_RES_GET:
+ case FRESCAN_BWRES_REP_RES_GET:
+ case FRESCAN_BWRES_REQ_RES_SET:
+ case FRESCAN_BWRES_REQ_RES_COMMIT:
+ case FRESCAN_BWRES_REQ_RES_CANCEL:
+ default:
+ FRESCAN_ERROR("request type %d not supported\n",
+ req_data->type);
+ return -1;
+ }
+}
--- /dev/null
+/*!
+ * @file frescan_bwres_messages.h
+ *
+ * @brief FRESCAN bandwidth reservation layer: negotiation messages formating
+ *
+ * This module contains the data types that define the FRESCAN negotiation
+ * message format and operations to convert them into or from negotiation
+ * requests
+ *
+ * @version 0.01
+ *
+ * @date 2-Apr-2008
+ *
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _FRESCAN_BWRES_MESSAGES_H_
+#define _FRESCAN_BWRES_MESSAGES_H_
+
+#include "frescan_types.h"
+
+/**
+ * frescan_messages_init() - initialization function for the module
+ */
+
+extern int frescan_messages_init(frescan_network_t net);
+
+/**
+ * frescan_messages_send_request()
+ *
+ * this function converts a request with the necessary data into a message
+ * and sends it.
+ *
+ * @req_data: the request to be sent (NOTE: the network is in req_data)
+ *
+ */
+
+extern int frescan_messages_send_request
+ (const frescan_bwres_request_data_t *req_data);
+
+/**
+ * frescan_messages_recv_request()
+ *
+ * this function BLOCKS the calling thread until receives a message
+ * and transforms it into a request.
+ *
+ * @net: network from where we want to wait messages
+ * @req: the request received (it must be freed)
+ *
+ */
+
+extern int frescan_messages_recv_request(frescan_network_t net,
+ frescan_bwres_request_id_t *req);
+
+#endif // _FRESCAN_BWRES_MESSAGES_H_
--- /dev/null
+/*!
+ * @file frescan_bwres_analysis.h
+ *
+ * @brief FRESCAN bandwith reservation layer: mode change protocol
+ *
+ * @version 0.02
+ *
+ * @date 19-Jul-2008
+ *
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @comments
+ *
+ * This module contains the mode change protocol
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#include <misc/linux_list.h>
+#include <stdbool.h>
+
+#include "frescan_data.h"
+#include "frescan_servers.h"
+#include "frescan_bwres_messages.h"
+#include "frescan_bwres_mode_change.h"
+#include "frescan_debug.h"
+#include "frescan_config.h"
+
+static int frescan_bwres_send_mc_messages
+ (frescan_network_t net,
+ frescan_bwres_mode_change_type_t mode_change_type,
+ frescan_ss_group_t *ss_to_cancel);
+
+/**
+ * frescan_bwres_mode_change_protocol() - performs the mode change protocol
+ */
+
+int frescan_bwres_mode_change_protocol(frescan_bwres_request_data_t *req_data)
+{
+ int ret;
+ frescan_node_t node;
+ frescan_bwres_vres_t *vres;
+ frsh_sa_vres_data_t *sa_vres_data;
+ frsh_sa_time_t max_period_in_budget_dec;
+ frsh_sa_time_t max_period_in_budget_inc;
+ struct timespec start_timestamp, next_activation;
+
+ DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG, "START MODE CHANGE PROTOCOL\n");
+
+ for(node=0; node<FRESCAN_MX_NODES; node++) {
+ INIT_LIST_HEAD(&frescan_data[req_data->net].
+ mode_change_list[node]);
+
+ frescan_data[req_data->net].mode_change_type[node] = 0;
+ }
+
+ max_period_in_budget_dec = (frsh_sa_time_t)0;
+ max_period_in_budget_inc = (frsh_sa_time_t)0;
+
+ DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG, "1.- adding vres to mc list\n");
+
+ list_for_each_entry
+ (vres,
+ &frescan_data[req_data->net].scenario.vres_head.list,
+ list)
+ {
+ sa_vres_data = &frescan_data[req_data->net].
+ scenario.fsa_scenario.sa_vres_alloc
+ [vres->fsa_vres_global_id];
+ vres->mode_change_type = 0;
+
+ if ((vres->old_c == 0) &&
+ (vres->old_t == 0) &&
+ (vres->old_p == 0)) {
+ //new vres (transmitted in the reply message)
+ vres->old_c = sa_vres_data->c;
+ vres->old_t = sa_vres_data->t;
+ vres->old_p = sa_vres_data->p;
+ continue;
+ }
+
+ if (sa_vres_data->c > vres->old_c) {
+ vres->mode_change_type |= FRESCAN_BWRES_MC_BUDGET_INC;
+ if (sa_vres_data->t > max_period_in_budget_inc) {
+ max_period_in_budget_inc = sa_vres_data->t;
+ }
+ } else if (sa_vres_data->c < vres->old_c) {
+ vres->mode_change_type |= FRESCAN_BWRES_MC_BUDGET_DEC;
+ if (sa_vres_data->t > max_period_in_budget_dec) {
+ max_period_in_budget_dec = sa_vres_data->t;
+ }
+ }
+
+ if (sa_vres_data->t > vres->old_t) {
+ vres->mode_change_type |= FRESCAN_BWRES_MC_PERIOD_INC;
+ } else if (sa_vres_data->t < vres->old_t) {
+ vres->mode_change_type |= FRESCAN_BWRES_MC_PERIOD_DEC;
+ }
+
+ if (sa_vres_data->p > vres->old_p) {
+ vres->mode_change_type |= FRESCAN_BWRES_MC_PRIO_INC;
+ } else if (sa_vres_data->p < vres->old_p) {
+ vres->mode_change_type |= FRESCAN_BWRES_MC_PRIO_DEC;
+ }
+
+ if (vres->mode_change_type == 0) continue;
+
+ vres->old_c = sa_vres_data->c;
+ vres->old_t = sa_vres_data->t;
+ vres->old_p = sa_vres_data->p;
+
+ list_add_tail(&(vres->mode_change_list),
+ &(frescan_data[req_data->net].
+ mode_change_list[vres->node]));
+
+ frescan_data[req_data->net].mode_change_type[vres->node] |=
+ vres->mode_change_type;
+
+ DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG,
+ "vres:%u node:%u ss:%u mc_type:0x%X\n",
+ vres->fsa_vres_global_id, vres->node,
+ vres->ss, vres->mode_change_type);
+ }
+
+ DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG, "2.- Budget decrease\n");
+
+ ret = frescan_bwres_send_mc_messages(req_data->net,
+ FRESCAN_BWRES_MC_BUDGET_DEC,
+ req_data->ss_to_cancel);
+ if (ret != 0) return -1;
+
+ ret = frescan_bwres_mode_change_local(req_data->net,
+ FRESCAN_BWRES_MC_BUDGET_DEC,
+ req_data->ss_to_cancel);
+ if (ret != 0) return -1;
+
+ DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG, "3.- Wait max_period\n");
+
+ ret = clock_gettime(CLOCK_MONOTONIC, &start_timestamp);
+ if (ret != 0) return -1;
+
+ add_timespec(next_activation,
+ frsh_rel_time_to_timespec(frsh_sa_time_to_rel_time
+ (max_period_in_budget_inc)),
+ frsh_rel_time_to_timespec(frsh_sa_time_to_rel_time
+ (max_period_in_budget_dec)));
+
+ incr_timespec(next_activation, start_timestamp);
+
+ ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME,
+ &next_activation, NULL);
+ if (ret != 0) return -1;
+
+ DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG, "4.- Budget increase\n");
+
+ ret = frescan_bwres_send_mc_messages(req_data->net,
+ FRESCAN_BWRES_MC_BUDGET_INC,
+ NULL);
+ if (ret != 0) return -1;
+
+ ret = frescan_bwres_mode_change_local(req_data->net,
+ FRESCAN_BWRES_MC_BUDGET_INC,
+ NULL);
+ if (ret != 0) return -1;
+
+ return 0;
+}
+
+/**
+ * frescan_bwres_send_mc_messages()
+ *
+ * This function is executed at the master node to send mode change
+ * messages to the slaves
+ */
+
+static int frescan_bwres_send_mc_messages
+ (frescan_network_t net,
+ frescan_bwres_mode_change_type_t mode_change_type,
+ frescan_ss_group_t *ss_to_cancel)
+{
+ int ret;
+ frescan_node_t node;
+ frescan_bwres_request_data_t tmp_req_data;
+
+ tmp_req_data.net = net;
+ tmp_req_data.type = FRESCAN_BWRES_REQ_MC;
+ tmp_req_data.mode_change_type = mode_change_type;
+
+ for(node=0; node<FRESCAN_MX_NODES; node++) {
+ if (node == FRESCAN_BWRES_MASTER_NODE) continue;
+
+ if ((frescan_data[net].mode_change_type[node] &
+ mode_change_type) != mode_change_type) continue;
+
+ DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG,
+ "send MC message to node:%u\n", node);
+
+ tmp_req_data.request_node = node;
+ tmp_req_data.ss_to_cancel = ss_to_cancel;
+
+ ret = frescan_messages_send_request(&tmp_req_data);
+ if (ret != 0) return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * frescan_bwres_mode_change_local()
+ *
+ * This function updates local vres. When a slave receives a change mode
+ * message to change the values of any vres this function is called.
+ */
+
+int frescan_bwres_mode_change_local
+ (frescan_network_t net,
+ frescan_bwres_mode_change_type_t mode_change_type,
+ frescan_ss_group_t *ss_to_cancel)
+{
+ int ret, i;
+ frescan_server_params_t server_params;
+ frescan_bwres_vres_t *vres;
+ struct timespec start_timestamp, next_activation;
+ frescan_node_t me = frescan_data[net].local_node;
+
+ list_for_each_entry(vres,
+ &frescan_data[net].mode_change_list[me],
+ mode_change_list)
+ {
+ if ((vres->mode_change_type & mode_change_type) !=
+ mode_change_type) continue;
+
+ server_params.budget = frsh_rel_time_to_usec(
+ frsh_sa_time_to_rel_time(vres->old_c)) /
+ FRESCAN_FRAME_TX_TIME_US;
+ server_params.period = frsh_sa_time_to_rel_time(vres->old_t);
+ server_params.prio = vres->old_p;
+
+ if (mode_change_type == FRESCAN_BWRES_MC_BUDGET_INC) {
+ DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG,
+ "commit ss:%u\n", vres->ss);
+ ret = frescan_servers_update(net,
+ &server_params,
+ vres->ss);
+ if (ret != 0) return ret;
+ } else {
+ DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG,
+ "set perceived ss:%u\n", vres->ss);
+ ret = frescan_servers_set_perceived(net,
+ &server_params,
+ vres->ss);
+ if (ret != 0) return ret;
+ }
+ }
+
+ if (mode_change_type == FRESCAN_BWRES_MC_BUDGET_INC) return 0;
+
+ // for ss cancelled set the perceived capacity to cero
+ if (ss_to_cancel != NULL) {
+ for(i=0; i<ss_to_cancel->size; i++) {
+ server_params.budget = 0;
+ server_params.period = frsh_usec_to_rel_time(0);
+ server_params.prio = 0;
+ ret = frescan_servers_set_perceived
+ (net,
+ &server_params,
+ ss_to_cancel->ss[i]);
+ if (ret != 0) return ret;
+ }
+ }
+
+ ret = clock_gettime(CLOCK_MONOTONIC, &start_timestamp);
+ if (ret != 0) return -1;
+
+ list_for_each_entry(vres,
+ &frescan_data[net].mode_change_list[me],
+ mode_change_list)
+ {
+ if ((vres->mode_change_type & mode_change_type) !=
+ mode_change_type) continue;
+
+ DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG,
+ "wait ss:%u period\n", vres->ss);
+
+ add_timespec(next_activation, start_timestamp,
+ frsh_rel_time_to_timespec(
+ frsh_sa_time_to_rel_time(vres->old_t)));
+
+ ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME,
+ &next_activation, NULL);
+ if (ret != 0) return -1;
+
+ DEBUG(FRESCAN_BWRES_MC_ENABLE_DEBUG,
+ "commit ss:%u\n", vres->ss);
+
+ ret = frescan_servers_commit_perceived(net, vres->ss);
+ if (ret != 0) return ret;
+ }
+
+ if (ss_to_cancel != NULL) {
+ for(i=0; i<ss_to_cancel->size; i++) {
+ ret = frescan_servers_destroy
+ (net, ss_to_cancel->ss[i]);
+ if (ret != 0) return ret;
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+/*!
+ * @file frescan_bwres_analysis.h
+ *
+ * @brief FRESCAN bandwith reservation layer: mode change protocol
+ *
+ * @version 0.02
+ *
+ * @date 19-Jul-2008
+ *
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @comments
+ *
+ * This module contains the mode change protocol
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _FRESCAN_BWRES_MODE_CHANGE_H_
+#define _FRESCAN_BWRES_MODE_CHANGE_H_
+
+#include "frescan_types.h"
+
+/**
+ * frescan_bwres_mode_change_protocol()
+ *
+ * Performs the mode change protocol. This function is called by the master
+ * node who coordinates all the process.
+ */
+
+extern int frescan_bwres_mode_change_protocol
+ (frescan_bwres_request_data_t *req_data);
+
+/**
+ * frescan_bwres_mode_change_local()
+ *
+ * This function updates local vres. When a slave receives a change mode
+ * message to change the values of any vres this function is called.
+ */
+
+extern int frescan_bwres_mode_change_local
+ (frescan_network_t net,
+ frescan_bwres_mode_change_type_t mode_change_type,
+ frescan_ss_group_t *ss_to_cancel);
+
+#endif // _FRESCAN_BWRES_MODE_CHANGE_H_
--- /dev/null
+/*!
+ * @file frescan_bwres_requests.c
+ *
+ * @brief FRESCAN bandwith reservation layer: requests
+ *
+ * This module contains an operation to create the queue, an operation to
+ * enqueue a message (with a request), and an operation to
+ * dequeue a message.
+ *
+ * @version 0.01
+ *
+ * @date 1-Apr-2008
+ *
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#include <misc/freelist.h>
+#include <misc/linux_list.h>
+#include "frescan.h"
+#include "frescan_bwres_requests.h"
+#include "frescan_config.h"
+#include "frescan_debug.h"
+#include "fosa_mutexes_and_condvars.h"
+
+static bool is_initialized = false;
+
+/**
+ * the_requests_pool
+ *
+ * We will use a freelist to allocate and free the requests.
+ *
+ **/
+
+struct request_t {
+ frescan_bwres_request_data_t request_data;
+ struct list_head request_list;
+ int pool_pos;
+};
+
+static fosa_mutex_t requests_mutex;
+static fosa_cond_t requests_cond;
+
+static struct request_t the_requests_pool[FRESCAN_BWRES_MX_REQUESTS];
+static freelist_t freelist;
+
+static struct request_t the_requests_list;
+
+/**
+ * frescan_bwres_requests_init()
+ *
+ * Init the freelist, requests list, cond var and mutex.
+ *
+ **/
+
+int frescan_bwres_requests_init(int max_ceiling)
+{
+ int err;
+
+ err = fosa_mutex_init(&requests_mutex, max_ceiling);
+ if (err != 0) return err;
+
+ err = fosa_cond_init(&requests_cond);
+ if (err != 0) return err;
+
+ err = freelist_init(&freelist, FRESCAN_BWRES_MX_REQUESTS);
+ if (err != 0) return err;
+
+ INIT_LIST_HEAD(&the_requests_list.request_list);
+
+ is_initialized = true;
+ return 0;
+}
+
+/**
+ * frescan_bwres_requests_alloc()
+ *
+ * Allocate a request with the mutex locked
+ *
+ **/
+
+int frescan_bwres_requests_alloc(frescan_bwres_request_id_t *req)
+{
+ int err, pos;
+
+ DEBUG(FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG, "alloc\n");
+
+ if (is_initialized == false) return -1;
+
+ err = fosa_mutex_lock(&requests_mutex);
+ if (err != 0) return err;
+
+ pos = freelist_alloc(&freelist);
+ if (pos < 0) goto locked_error;
+
+ err = fosa_mutex_unlock(&requests_mutex);
+ if (err != 0) return err;
+
+ *req = (unsigned int)pos;
+ the_requests_pool[*req].pool_pos = pos;
+
+ return 0;
+
+locked_error:
+ fosa_mutex_unlock(&requests_mutex);
+ return pos;
+}
+
+/**
+ * frescan_bwres_requests_free()
+ *
+ * free the request from the pool
+ *
+ **/
+
+int frescan_bwres_requests_free(frescan_bwres_request_id_t req)
+{
+ int err;
+
+ DEBUG(FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG, "free\n");
+
+ if (is_initialized == false) return -1;
+
+ err = fosa_mutex_lock(&requests_mutex);
+ if (err != 0) return err;
+
+ err = freelist_free(&freelist, req);
+ if (err != 0) goto locked_error;
+
+ err = fosa_mutex_unlock(&requests_mutex);
+ if (err != 0) return err;
+
+ return 0;
+
+locked_error:
+ fosa_mutex_unlock(&requests_mutex);
+ return err;
+}
+
+/**
+ * frescan_bwres_requests_get_data() - gets the data of the request
+ *
+ */
+
+int frescan_bwres_requests_get_data(frescan_bwres_request_id_t req,
+ frescan_bwres_request_data_t **data)
+{
+ DEBUG(FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG, "request id:%d\n", req);
+ *data = &the_requests_pool[req].request_data;
+ return 0;
+}
+
+/**
+ * frescan_bwres_requests_enqueue()
+ *
+ **/
+
+int frescan_bwres_requests_enqueue(frescan_bwres_request_id_t req)
+{
+ int err;
+
+ err = fosa_mutex_lock(&requests_mutex);
+ if (err != 0) return err;
+
+ DEBUG(FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG,
+ "is list empty A? %d\n",
+ list_empty(&the_requests_list.request_list));
+
+ list_add_tail(&the_requests_pool[req].request_list,
+ &the_requests_list.request_list);
+
+ DEBUG(FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG,
+ "is list empty B? %d\n",
+ list_empty(&the_requests_list.request_list));
+
+ err = fosa_cond_signal(&requests_cond);
+ if (err != 0) goto locked_error;
+
+ err = fosa_mutex_unlock(&requests_mutex);
+ if (err != 0) return err;
+
+ return 0;
+
+locked_error:
+ fosa_mutex_unlock(&requests_mutex);
+ return err;
+}
+
+/**
+ * frescan_bwres_requestqueue_dequeue()
+ *
+ **/
+
+int frescan_bwres_requests_dequeue(frescan_bwres_request_id_t *req)
+{
+ int err;
+ struct list_head *pos;
+ struct request_t *request = NULL;
+
+ err = fosa_mutex_lock(&requests_mutex);
+ if (err != 0) return err;
+
+ DEBUG(FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG, "entering\n");
+
+ while (list_empty(&the_requests_list.request_list)) {
+ err = fosa_cond_wait(&requests_cond, &requests_mutex);
+ if (err != 0) goto locked_error;
+ DEBUG(FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG, "received signal\n");
+ }
+
+ DEBUG(FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG, "dequeueing a request\n");
+
+ list_for_each(pos, &the_requests_list.request_list) {
+ request = list_entry(pos, struct request_t, request_list);
+ break;
+ }
+
+ list_del(&request->request_list);
+
+ *req = request->pool_pos;
+
+ DEBUG(FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG,
+ "is list empty now? %d\n",
+ list_empty(&the_requests_list.request_list));
+
+ err = fosa_mutex_unlock(&requests_mutex);
+ if (err != 0) return err;
+
+ return 0;
+
+locked_error:
+ fosa_mutex_unlock(&requests_mutex);
+ return err;
+}
--- /dev/null
+/*!
+ * @file frescan_bwres_requests.h
+ *
+ * @brief FRESCAN bandwith reservation layer: requests
+ *
+ * This module contains the request type definition and queues. They are used
+ * to ask negotiation, renegotiation or cancel contracts.
+ *
+ * @version 0.01
+ *
+ * @date 1-Apr-2008
+ *
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _FRESCAN_BWRES_REQUESTS_H_
+#define _FRESCAN_BWRES_REQUESTS_H_
+
+#include "frescan_types.h"
+
+extern int frescan_bwres_requests_init(int max_ceiling);
+extern int frescan_bwres_requests_alloc(frescan_bwres_request_id_t *req);
+extern int frescan_bwres_requests_free(frescan_bwres_request_id_t req);
+extern int frescan_bwres_requests_enqueue(frescan_bwres_request_id_t req);
+extern int frescan_bwres_requests_dequeue(frescan_bwres_request_id_t *req);
+
+/**
+ * frescan_bwres_requests_get_data() - gets the data of the request
+ *
+ * @data: the data is obtained as a pointer an manipulated directly
+ * accesing to the members of the structure. Note that this is
+ * just an internal API so instead of using get/set functions we
+ * will just access to the members of the struc directly
+ */
+
+extern int frescan_bwres_requests_get_data(frescan_bwres_request_id_t req,
+ frescan_bwres_request_data_t **data);
+
+#endif // _FRESCAN_BWRES_REQUESTS_H_
--- /dev/null
+/*!
+ * @file frescan_bwres_robjs.c
+ *
+ * @brief FRESCAN bandwith reservation layer: reply objects
+ *
+ * This module contains the definition of the data object and operations to
+ * create a pool of objects, obtain the id of an unused object, wait upon it,
+ * signal it, and finish using it.
+ *
+ * @version 0.01
+ *
+ * @date 1-Apr-2008
+ *
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#include <misc/freelist.h>
+#include "frescan_bwres_robjs.h"
+#include "fosa_mutexes_and_condvars.h"
+#include "frescan_config.h"
+#include "frescan_debug.h"
+
+static bool is_initialized = false;
+
+/**
+ * the_reply_objects
+ *
+ * We will use a freelist to allocate and free the reply object. Reply objects
+ * are FOSA conditional variables (we can't use synchobjects because they are
+ * only for bound-workload) stored in an array together with their condition
+ * and a mutex variable to control the access and to be able to wait and
+ * signal the conditional variables. We could have used semaphores instead, but
+ * it would introduce a dependency on the OS because they are not in FOSA.
+ *
+ **/
+
+static fosa_mutex_t freelist_mutex;
+
+struct replyobj_t {
+ bool is_work_done;
+ fosa_cond_t cond;
+ fosa_mutex_t mutex;
+};
+
+static struct replyobj_t the_reply_objects[FRESCAN_BWRES_MX_REPLY_OBJECTS];
+static freelist_t freelist;
+
+/**
+ * frescan_bwres_robjs_init()
+ *
+ * Init the freelist and its mutex. The conditional variables are not
+ * initialized here but when allocating a reply object. This can be more
+ * efficient for memory usage in some OS (not in MaRTE OS though).
+ *
+ **/
+
+int frescan_bwres_robjs_init(int max_ceiling)
+{
+ int err;
+
+ err = fosa_mutex_init(&freelist_mutex, max_ceiling);
+ if (err != 0) return err;
+
+ err = freelist_init(&freelist, FRESCAN_BWRES_MX_REPLY_OBJECTS);
+ if (err != 0) return err;
+
+ is_initialized = true;
+ return 0;
+}
+
+/**
+ * frescan_bwres_robjs_alloc()
+ *
+ * Allocate an reply object with the freelist_mutex locked and then initialize
+ * its cond variable, condition (predicate) and mutex. The ID of the allocated
+ * reply object represents the position in the array the_reply_objects.
+ *
+ **/
+
+int frescan_bwres_robjs_alloc(frescan_bwres_robj_id_t *id, int ceiling)
+{
+ int err, pos;
+
+ DEBUG(FRESCAN_BWRES_ROBJS_ENABLE_DEBUG,
+ "allocating reply object, is_initialized=%d\n", is_initialized);
+
+ if (is_initialized == false) return -1;
+
+ err = fosa_mutex_lock(&freelist_mutex);
+ if (err != 0) return err;
+
+ pos = freelist_alloc(&freelist);
+ if (pos < 0) goto locked_error;
+
+ err = fosa_mutex_unlock(&freelist_mutex);
+ if (err != 0) return err;
+
+ err = fosa_cond_init(&the_reply_objects[pos].cond);
+ if (err != 0) return err;
+
+ the_reply_objects[pos].is_work_done = false;
+ *id = (unsigned int)pos;
+
+ err = fosa_mutex_init(&the_reply_objects[pos].mutex, ceiling);
+ if (err != 0) return err;
+
+ DEBUG(FRESCAN_BWRES_ROBJS_ENABLE_DEBUG,
+ "reply object allocated, id=%d\n", *id);
+
+ return 0;
+
+locked_error:
+ fosa_mutex_unlock(&freelist_mutex);
+ return pos;
+}
+
+/**
+ * frescan_bwres_robjs_free()
+ *
+ * Destroy the cond variable and then free the replyobject
+ *
+ **/
+
+int frescan_bwres_robjs_free(frescan_bwres_robj_id_t id)
+{
+ int err;
+
+ DEBUG(FRESCAN_BWRES_ROBJS_ENABLE_DEBUG,
+ "free reply id=%d, is_initialized=%d\n", id, is_initialized);
+
+ if (is_initialized == false) return -1;
+
+ err = fosa_mutex_lock(&freelist_mutex);
+ if (err != 0) return err;
+
+ err = freelist_free(&freelist, id);
+ if (err != 0) goto locked_error;
+
+ err = fosa_cond_destroy(&the_reply_objects[id].cond);
+ if (err != 0) return err;
+
+ err = fosa_mutex_destroy(&the_reply_objects[id].mutex);
+ if (err != 0) return err;
+
+ the_reply_objects[id].is_work_done = false;
+
+ err = fosa_mutex_unlock(&freelist_mutex);
+ if (err != 0) return err;
+
+ return 0;
+
+locked_error:
+ fosa_mutex_unlock(&freelist_mutex);
+ return err;
+}
+
+/**
+ * frescan_bwres_robjs_signal()
+ *
+ * Signal the cond variable
+ *
+ **/
+
+int frescan_bwres_robjs_signal(frescan_bwres_robj_id_t id)
+{
+ int err;
+
+ DEBUG(FRESCAN_BWRES_ROBJS_ENABLE_DEBUG,
+ "is_initialized=%d\n", is_initialized);
+ if (is_initialized == false) return -1;
+
+ DEBUG(FRESCAN_BWRES_ROBJS_ENABLE_DEBUG,
+ "taking mutex of the reply id=%d\n", id);
+ err = fosa_mutex_lock(&the_reply_objects[id].mutex);
+ if (err != 0) return err;
+
+ the_reply_objects[id].is_work_done = true;
+
+ DEBUG(FRESCAN_BWRES_ROBJS_ENABLE_DEBUG,
+ "signal the cond variable\n");
+ err = fosa_cond_signal(&the_reply_objects[id].cond);
+ if (err != 0) goto locked_error;
+
+ err = fosa_mutex_unlock(&the_reply_objects[id].mutex);
+ if (err != 0) return err;
+
+ return 0;
+
+locked_error:
+ FRESCAN_ERROR("locked error %d\n", err);
+ fosa_mutex_unlock(&the_reply_objects[id].mutex);
+ return err;
+}
+
+/**
+ * frescan_bwres_robjs_wait()
+ *
+ * Wait on the cond variable.
+ *
+ **/
+
+int frescan_bwres_robjs_wait(frescan_bwres_robj_id_t id)
+{
+ int err;
+
+ if (is_initialized == false) return -1;
+
+ err = fosa_mutex_lock(&the_reply_objects[id].mutex);
+ if (err != 0) return err;
+
+ while (the_reply_objects[id].is_work_done == false) {
+ err = fosa_cond_wait(&the_reply_objects[id].cond,
+ &the_reply_objects[id].mutex);
+ if (err != 0) goto locked_error;
+ }
+
+ the_reply_objects[id].is_work_done = false;
+
+ err = fosa_mutex_unlock(&the_reply_objects[id].mutex);
+ if (err != 0) return err;
+
+ return 0;
+
+locked_error:
+ fosa_mutex_unlock(&the_reply_objects[id].mutex);
+ return err;
+}
+
+/**
+ * frescan_bwres_robjs_timedwait()
+ *
+ * Wait on the cond variable with a timeout.
+ *
+ **/
+
+int frescan_bwres_robjs_timedwait(frescan_bwres_robj_id_t id,
+ const struct timespec *abstime)
+{
+ int err;
+
+ if (is_initialized == false) return -1;
+
+ err = fosa_mutex_lock(&the_reply_objects[id].mutex);
+ if (err != 0) return err;
+
+ while (the_reply_objects[id].is_work_done == false) {
+ err = fosa_cond_timedwait(&the_reply_objects[id].cond,
+ &the_reply_objects[id].mutex,
+ abstime);
+ if (err != 0) goto locked_error;
+ }
+
+ the_reply_objects[id].is_work_done = false;
+
+ err = fosa_mutex_unlock(&the_reply_objects[id].mutex);
+ if (err != 0) return err;
+
+ return 0;
+
+locked_error:
+ fosa_mutex_unlock(&the_reply_objects[id].mutex);
+ return err;
+}
--- /dev/null
+/*!
+ * @file frescan_bwres_robjs.h
+ *
+ * @brief FRESCAN bandwith reservation layer: reply objects
+ *
+ * This module contains the definition of the data object and operations to
+ * create a pool of objects, obtain the id of an unused object, wait upon it,
+ * signal it, and finish using it.
+ *
+ * @version 0.01
+ *
+ * @date 1-Apr-2008
+ *
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _FRESCAN_BWRES_ROBJS_H_
+#define _FRESCAN_BWRES_ROBJS_H_
+
+#include "frescan_types.h"
+
+extern int frescan_bwres_robjs_init(int max_ceiling);
+extern int frescan_bwres_robjs_alloc(frescan_bwres_robj_id_t *id, int ceiling);
+extern int frescan_bwres_robjs_free(frescan_bwres_robj_id_t id);
+extern int frescan_bwres_robjs_signal(frescan_bwres_robj_id_t id);
+extern int frescan_bwres_robjs_wait(frescan_bwres_robj_id_t id);
+extern int frescan_bwres_robjs_timedwait(frescan_bwres_robj_id_t id,
+ const struct timespec *abstime);
+
+#endif // _FRESCAN_BWRES_ROBJS_H_
--- /dev/null
+/*!
+ * @file frescan_bwres_threads.c
+ *
+ * @brief FRESCAN bandwidth reservation layer: negotiation threads
+ *
+ * This module contains the acceptor threads and the master thread for local
+ * negotiations, with functions to create them.
+ *
+ * @version 0.01
+ *
+ * @date 2-Apr-2008
+ *
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#include <assert.h>
+#include "fosa_threads_and_signals.h" // fosa_thread_attr_init...
+#include "frescan_bwres_threads.h"
+#include "frescan_bwres_messages.h"
+#include "frescan_bwres_requests.h"
+#include "frescan_bwres_robjs.h"
+#include "frescan_bwres_analysis.h"
+#include "frescan_bwres_mode_change.h"
+#include "frescan_config.h"
+#include "frescan_debug.h"
+#include "frescan_data.h"
+#include "frescan_servers.h"
+
+static void *frescan_manager_thread(void *arg);
+static void *frescan_acceptor_thread(void *arg);
+
+static void frescan_manager_gn_prepare_scenario
+ (frescan_bwres_sa_scenario_t *scenario,
+ frescan_bwres_request_data_t *req_data);
+
+static void frescan_manager_gn_restore_scenario
+ (frescan_bwres_sa_scenario_t *scenario,
+ frescan_bwres_request_data_t *req_data);
+
+static void frescan_manager_req_gn(frescan_bwres_request_data_t *req_data);
+static void frescan_manager_rep_gn(frescan_bwres_request_data_t *req_data);
+static void frescan_manager_req_mc(frescan_bwres_request_data_t *req_data);
+
+/**
+ * frescan_manager_thread_create()
+ *
+ * This call creates the manager thread at each node which will be waiting
+ * in a request queue for LOCAL or EXTERNAL requests.
+ */
+
+int frescan_manager_thread_create(frescan_network_t net)
+{
+ int ret;
+ fosa_thread_attr_t attr;
+
+ ret = fosa_thread_attr_init(&attr);
+ if (ret != 0) return ret;
+
+ ret = fosa_thread_attr_set_prio(&attr, FRESCAN_BWRES_NEG_THREAD_PRIO);
+ if (ret != 0) return ret;
+
+ ret = fosa_thread_create(&frescan_data[net].manager_thread_id,
+ &attr,
+ frescan_manager_thread,
+ (void *)(uint32_t)net);
+ if (ret != 0) return ret;
+
+ ret = fosa_thread_attr_destroy(&attr);
+ if (ret != 0) return ret;
+
+ return 0;
+}
+
+/**
+ * frescan_acceptor_thread_create()
+ *
+ * This call creates the acceptor thread which will be waiting negotiation
+ * messages from the network and converting them into requests.
+ */
+
+int frescan_acceptor_thread_create(frescan_network_t net)
+{
+ int ret;
+ fosa_thread_attr_t attr;
+
+ ret = fosa_thread_attr_init(&attr);
+ if (ret != 0) return ret;
+
+ ret = fosa_thread_attr_set_prio(&attr, FRESCAN_BWRES_ACCEPTOR_PRIO);
+ if (ret != 0) return ret;
+
+ ret = fosa_thread_create(&frescan_data[net].acceptor_thread_id,
+ &attr,
+ frescan_acceptor_thread,
+ (void *)(uint32_t)net);
+ if (ret != 0) return ret;
+
+ ret = fosa_thread_attr_destroy(&attr);
+ if (ret != 0) return ret;
+
+ return 0;
+}
+
+/**
+ * frescan_manager_thread
+ */
+
+static void *frescan_manager_thread(void *arg)
+{
+ int ret;
+ frescan_bwres_request_id_t req;
+ frescan_bwres_request_data_t *req_data;
+ frescan_network_t net = (uint32_t)arg;
+
+ DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG, "manager thread starts\n");
+
+ while(1) {
+ DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG, "wait for a request\n");
+
+ ret = frescan_bwres_requests_dequeue(&req);
+ assert(ret == 0);
+
+ ret = frescan_bwres_requests_get_data(req, &req_data);
+ assert(ret == 0);
+
+ switch(req_data->type) {
+ case FRESCAN_BWRES_REQ_GN:
+ frescan_manager_req_gn(req_data);
+ break;
+ case FRESCAN_BWRES_REP_GN:
+ frescan_manager_rep_gn(req_data);
+ break;
+ case FRESCAN_BWRES_REQ_MC:
+ frescan_manager_req_mc(req_data);
+ break;
+ case FRESCAN_BWRES_REQ_RES:
+ case FRESCAN_BWRES_REQ_RES_GET:
+ case FRESCAN_BWRES_REP_RES_GET:
+ case FRESCAN_BWRES_REQ_RES_SET:
+ case FRESCAN_BWRES_REQ_RES_COMMIT:
+ case FRESCAN_BWRES_REQ_RES_CANCEL:
+ default:
+ FRESCAN_ERROR("request type not supported\n");
+ assert(0);
+ }
+
+ if(req_data->request_node != frescan_data[net].local_node) {
+ ret = frescan_bwres_requests_free(req);
+ assert(ret == 0);
+ }
+ }
+}
+
+/**
+ * frescan_acceptor_thread()
+ */
+
+static void *frescan_acceptor_thread(void *arg)
+{
+ int ret;
+ frescan_bwres_request_id_t req;
+ frescan_network_t net = (uint32_t)arg;
+
+ DEBUG(FRESCAN_BWRES_ACCEPTOR_ENABLE_DEBUG, "acceptor thread starts\n");
+
+ while(1) {
+ ret = frescan_messages_recv_request(net, &req);
+ assert(ret == 0);
+
+ ret = frescan_bwres_requests_enqueue(req);
+ assert(ret == 0);
+ }
+
+ return NULL;
+}
+
+/**
+ * frescan_manager_req_gn
+ */
+
+static void frescan_manager_req_gn(frescan_bwres_request_data_t *req_data)
+{
+ int ret, i;
+ frescan_node_t me;
+ bool accepted;
+ frescan_bwres_sa_scenario_t *scenario;
+ frescan_ss_t ss;
+ frescan_server_params_t server_params;
+ frescan_bwres_vres_t *vres;
+
+ me = frescan_data[req_data->net].local_node;
+
+ if (me != FRESCAN_BWRES_MASTER_NODE) {
+ DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG,
+ "send gn req to master\n");
+ ret = frescan_messages_send_request(req_data);
+ assert(ret == 0);
+ return;
+ }
+
+ scenario = &frescan_data[req_data->net].scenario;
+
+ DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG, "prepare new scenario\n");
+ frescan_manager_gn_prepare_scenario(scenario, req_data);
+
+ DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG, "perform sched analysis\n");
+ ret = frescan_bwres_sa_sched_test(scenario, &accepted);
+ assert(ret == 0);
+
+ if (accepted) {
+ DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG, "ACCEPTED!\n");
+ req_data->return_value = FRESCAN_BWRES_REQ_ACCEPTED;
+
+ DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG,
+ "spare capacity and mode change\n");
+
+ ret = frescan_bwres_sa_spare_capacity(scenario);
+ assert(ret == 0);
+
+ ret = frescan_bwres_mode_change_protocol(req_data);
+ assert(ret == 0);
+ } else {
+ DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG, "FAILED!\n");
+ req_data->return_value = FRESCAN_BWRES_REQ_NOT_ACCEPTED;
+ frescan_manager_gn_restore_scenario(scenario, req_data);
+ }
+
+ if (req_data->request_node != me) {
+ DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG, "send reply\n");
+ req_data->type = FRESCAN_BWRES_REP_GN;
+
+ ret = frescan_messages_send_request(req_data);
+ assert(ret == 0);
+ return;
+ }
+
+ if (req_data->return_value == FRESCAN_BWRES_REQ_ACCEPTED) {
+ // create servers for new contracts
+ req_data->ss_new->size = req_data->contracts_to_neg->size;
+ for(i=0; i<req_data->ss_new->size; i++) {
+ vres = &frescan_data[req_data->net].scenario.
+ vres_pool[me]
+ [req_data->ss_new->ss[i]];
+
+ server_params.budget = frsh_rel_time_to_usec(
+ frsh_sa_time_to_rel_time(vres->old_c)) /
+ FRESCAN_FRAME_TX_TIME_US;
+
+ server_params.period = frsh_sa_time_to_rel_time
+ (vres->old_t);
+ server_params.prio = vres->old_p;
+
+ // Create server
+ ret = frescan_servers_create(req_data->net,
+ &server_params,
+ &ss);
+ assert(ret == 0);
+ assert (req_data->ss_new->ss[i] == ss);
+ }
+ }
+
+ DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG, "signal robj\n");
+ ret = frescan_bwres_robjs_signal(req_data->robj);
+ assert(ret == 0);
+}
+
+/**
+ * frescan_manager_gn_prepare_scenario
+ */
+
+static void frescan_manager_gn_prepare_scenario
+ (frescan_bwres_sa_scenario_t *scenario,
+ frescan_bwres_request_data_t *req_data)
+{
+ int ret, i;
+
+ // NEG-GROUP
+ for(i=0; i<req_data->contracts_to_neg->size; i++) {
+ ret = freelist_alloc(&frescan_data[req_data->net].scenario.
+ ss_id_freelist[req_data->request_node]);
+ assert(ret >= 0);
+
+ req_data->ss_new->ss[i] = (frescan_ss_t)ret;
+
+ DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG,
+ "prealloc net:%d node:%d ss_new->ss[%d]:%d\n",
+ req_data->net, req_data->request_node,
+ i, req_data->ss_new->ss[i]);
+
+ ret = frescan_bwres_sa_add_contract
+ (scenario,
+ req_data->ss_new->ss[i],
+ req_data->request_node,
+ &req_data->contracts_to_neg->contracts[i]);
+ assert(ret == 0);
+ }
+
+ req_data->ss_new->size = req_data->contracts_to_neg->size;
+
+ // RENEG-GROUP
+ scenario->backup_contracts_to_reneg.size =
+ req_data->contracts_to_reneg->size;
+
+ for(i=0; i<req_data->contracts_to_reneg->size; i++) {
+ ret = frescan_bwres_sa_update_contract
+ (scenario,
+ req_data->ss_to_reneg->ss[i],
+ req_data->request_node,
+ &req_data->contracts_to_reneg->contracts[i],
+ &scenario->backup_contracts_to_reneg.contracts[i]);
+ assert(ret == 0);
+ }
+
+ // CANCEL-GROUP
+ scenario->backup_contracts_to_cancel.size =
+ req_data->ss_to_cancel->size;
+
+ for(i=0; i<req_data->ss_to_cancel->size; i++) {
+ ret = frescan_bwres_sa_remove_contract
+ (scenario,
+ req_data->ss_to_cancel->ss[i],
+ req_data->request_node,
+ &scenario->backup_contracts_to_cancel.contracts[i]);
+ assert(ret == 0);
+ }
+}
+
+/**
+ * frescan_manager_gn_restore_scenario
+ */
+
+static void frescan_manager_gn_restore_scenario
+ (frescan_bwres_sa_scenario_t *scenario,
+ frescan_bwres_request_data_t *req_data)
+{
+ int ret, i;
+
+ // NEG-GROUP
+ for(i=0; i<req_data->contracts_to_neg->size; i++) {
+ ret = frescan_bwres_sa_remove_contract
+ (scenario,
+ req_data->ss_new->ss[i],
+ req_data->request_node,
+ NULL);
+ assert(ret == 0);
+
+ ret = freelist_free(&frescan_data[req_data->net].scenario.
+ ss_id_freelist[req_data->request_node],
+ req_data->ss_new->ss[i]);
+ assert(ret == 0);
+ }
+
+ // RENEG-GROUP
+ for(i=0; i<req_data->contracts_to_reneg->size; i++) {
+ ret = frescan_bwres_sa_update_contract
+ (scenario,
+ req_data->ss_to_reneg->ss[i],
+ req_data->request_node,
+ &scenario->backup_contracts_to_reneg.contracts[i],
+ NULL);
+ assert(ret == 0);
+ }
+
+ // CANCEL-GROUP
+ for(i=0; i<req_data->ss_to_cancel->size; i++) {
+ ret = frescan_bwres_sa_add_contract
+ (scenario,
+ req_data->ss_to_cancel->ss[i],
+ req_data->request_node,
+ &scenario->backup_contracts_to_cancel.contracts[i]);
+ assert(ret == 0);
+ }
+}
+
+/**
+ * frescan_manager_rep_gn
+ */
+
+static void frescan_manager_rep_gn(frescan_bwres_request_data_t *req_data)
+{
+ int ret, i;
+ frescan_bwres_request_data_t *caller_req;
+
+ ret = frescan_bwres_requests_get_data(req_data->req, &caller_req);
+ assert(ret == 0);
+
+ caller_req->return_value = req_data->return_value;
+
+ DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG,
+ "ret:%d -> %s\n", req_data->return_value,
+ (req_data->return_value ==
+ FRESCAN_BWRES_REQ_ACCEPTED) ? "OK" : "FAIL");
+
+ if (req_data->return_value == FRESCAN_BWRES_REQ_ACCEPTED) {
+ assert (req_data->ss_new->size ==
+ caller_req->contracts_to_neg->size);
+ caller_req->ss_new->size = req_data->ss_new->size;
+
+ DEBUG(FRESCAN_BWRES_MANAGER_ENABLE_DEBUG,
+ "ss_new->size:%u\n", caller_req->ss_new->size);
+
+ for (i=0; i<caller_req->ss_new->size; i++) {
+ caller_req->ss_new->ss[i] = req_data->ss_new->ss[i];
+ }
+ }
+
+ ret = frescan_bwres_robjs_signal(caller_req->robj);
+ assert(ret == 0);
+}
+
+/**
+ * frescan_manager_req_mc
+ */
+
+static void frescan_manager_req_mc(frescan_bwres_request_data_t *req_data)
+{
+ int ret;
+
+ ret = frescan_bwres_mode_change_local(req_data->net,
+ req_data->mode_change_type,
+ req_data->ss_to_cancel);
+ assert(ret == 0);
+}
--- /dev/null
+/*!
+ * @file frescan_bwres_threads.h
+ *
+ * @brief FRESCAN bandwidth reservation layer: negotiation threads
+ *
+ * This module contains the acceptor threads and the master thread for local
+ * negotiations, with functions to create them.
+ *
+ * @version 0.01
+ *
+ * @date 2-Apr-2008
+ *
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _FRESCAN_BWRES_THREADS_H_
+#define _FRESCAN_BWRES_THREADS_H_
+
+#include "frescan_types.h"
+
+/**
+ * frescan_manager_thread_create()
+ *
+ * This call creates the manager thread at each node which will be waiting
+ * in a request queue for LOCAL or EXTERNAL requests.
+ */
+
+extern int frescan_manager_thread_create(frescan_network_t net);
+
+/**
+ * frescan_acceptor_thread_create()
+ *
+ * This call creates the acceptor thread which will be waiting negotiation
+ * messages from the network and converting them into EXTERNAL requests for
+ * the manager thread.
+ */
+
+extern int frescan_acceptor_thread_create(frescan_network_t net);
+
+#endif // _FRESCAN_BWRES_THREADS_H_
--- /dev/null
+/*!
+ * @file frecan_config.h
+ *
+ * @brief constants to configure the frescan protocol
+ *
+ * @version 0.01
+ *
+ * @date 12-Mar-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This module contains some constants and macros to configure the
+ * frescan protocol. For example, the size of the packets pool, etc...
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _MARTE_FRESCAN_CONFIG_H_
+#define _MARTE_FRESCAN_CONFIG_H_
+
+#include "fosa_threads_and_signals.h" // FOSA_SIGNAL_MIN
+#include <sys/kernel.h> // kernel_enter_critic_section
+
+#define FRESCAN_MX_PACKETS 200
+#define FRESCAN_MX_NETWORKS 2
+#define FRESCAN_BROADCAST_ADDR 0xF
+#define FRESCAN_MX_IDS 255
+#define FRESCAN_MX_PRIOS 32
+#define FRESCAN_BACKGROUND_PRIO 0
+#define FRESCAN_REPL_SIGNAL_NUM FOSA_SIGNAL_MIN + 10 // real-time signal
+#define FRESCAN_REPL_THREAD_PRIO 60
+#define FRESCAN_MX_NODES 4
+#define FRESCAN_MX_REPL_OPS FRESCAN_MX_IDS*10
+
+// Configuration values for FRESCAN_BWRES
+#define FRESCAN_BWRES_MX_REPLY_OBJECTS 40
+#define FRESCAN_BWRES_MX_REQUESTS 40
+#define FRESCAN_BWRES_MASTER_NODE 0
+#define FRESCAN_BWRES_ROBJS_MX_CEILING 90
+#define FRESCAN_BWRES_REQ_MX_CEILING 90
+#define FRESCAN_BWRES_MX_PRIO 60
+#define FRESCAN_BWRES_NEG_THREAD_PRIO 50
+#define FRESCAN_BWRES_ACCEPTOR_PRIO FRESCAN_BWRES_NEG_THREAD_PRIO - 1
+#define FRESCAN_BWRES_NEG_MSG_PRIO 4
+#define FRESCAN_BWRES_NEG_MSG_BUDGET 5 // packets
+#define FRESCAN_BWRES_NEG_MSG_PERIOD 1000000 // us
+#define FRESCAN_BWRES_NEG_MSG_CHAN 0
+#define FRESCAN_BWRES_MX_CONTRACTS (FRESCAN_MX_NODES*FRESCAN_MX_IDS)
+#define FRESCAN_BWRES_MAX_GROUP_OPS 5
+#define FRESCAN_BWRES_SS_MIN_PRIO 1
+#define FRESCAN_BWRES_SS_MAX_PRIO FRESCAN_MX_PRIOS
+
+// Configuration values for FRESCAN_BWRES_FNA
+#define FRESCAN_BWRES_FNA_NET_BASE 0
+#define FRESCAN_BWRES_FNA_LOCAL_NODE 3
+#define FRESCAN_BWRES_TX_FP_MX_PRIO 10
+#define FRESCAN_BWRES_RX_NUM_CHANNELS 10
+#define FRESCAN_BWRES_RX_CHAN_MX_PRIO NULL
+
+// FRESCAN_FRAME_TX_TIME_US: measured transmission time of an 8byte frame
+#define FRESCAN_FRAME_TX_TIME_US 200
+
+#define FRESCAN_MLOCK_T unsigned
+#define FRESCAN_CREATE_LOCK(l)
+#define FRESCAN_DESTROY_LOCK(l)
+#define FRESCAN_ACQUIRE_LOCK(l) kernel_enter_critic_section(l)
+#define FRESCAN_RELEASE_LOCK(l) kernel_leave_critic_section(*(l))
+
+#endif // _MARTE_FRESCAN_CONFIG_H_
--- /dev/null
+/*!
+ * @file frescan_data.c
+ *
+ * @brief global data used from different modules in frescan
+ *
+ * @version 0.01
+ *
+ * @date 12-Mar-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * In frescan_data module we store global data to FRESCAN to make the protocol
+ * easier and efficient to implement.
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#include "frescan_data.h"
+
+frescan_network_data_t frescan_data[FRESCAN_MX_NETWORKS];
+
+int frescan_data_init(int fd, frescan_init_params_t *params)
+{
+ frescan_ss_t id;
+ frescan_prio_t prio;
+ frescan_node_t src;
+
+ frescan_data[params->net].fd = fd;
+ frescan_data[params->net].local_node = params->node;
+ frescan_data[params->net].last_packet = NULL;
+ frescan_data[params->net].last_packet_prio = 0;
+
+ FRESCAN_CREATE_LOCK(&frescan_data[params->net].lock);
+
+ for(id=0; id<FRESCAN_MX_IDS; id++) {
+ for(src=0; src<FRESCAN_MX_NODES; src++) {
+ frescan_data[params->net].id_queues[src][id] = NULL;
+ }
+ }
+
+ for(prio=0; prio<FRESCAN_MX_PRIOS; prio++) {
+ for(src=0; src<FRESCAN_MX_NODES; src++) {
+ frescan_data[params->net].id_fp_queues[src][prio] = NULL;
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+/*!
+ * @file frescan_data.h
+ *
+ * @brief global data used from different modules in frescan
+ *
+ * @version 0.01
+ *
+ * @date 12-Mar-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * In order to simplify we have a single module, frescan_data, to store the
+ * main internal structures and global data of the FRESCAN protocol.
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _MARTE_FRESCAN_DATA_H_
+#define _MARTE_FRESCAN_DATA_H_
+
+#include "frescan_types.h" // frescan_node_t, _prio_t, _budget_t
+#include "frescan_config.h" // FRESCAN_MLOCK_T, FRESCAN_MX_XXX
+
+extern frescan_network_data_t frescan_data[FRESCAN_MX_NETWORKS];
+
+extern int frescan_data_init(int fd, frescan_init_params_t *params);
+
+#endif // _MARTE_FRESCAN_DATA_H_
--- /dev/null
+/*!
+ * @file frecan_debug.h
+ *
+ * @brief debuggin macros and flags for the frescan protocol
+ *
+ * @version 0.01
+ *
+ * @date 21-Feb-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This module contains macros and flags to enable debugging in the
+ * frescan protocol for MaRTE OS
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _MARTE_FRESCAN_DEBUG_H_
+#define _MARTE_FRESCAN_DEBUG_H_
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+/**
+ * DEBUG macros
+ **/
+
+#define DEBUG(enable,x,args...) \
+ if(enable) printc("DEBUG (%s): " x, __func__ , ##args)
+
+#define FRESCAN_ERROR(x,args...) \
+ printe("ERROR (%s:%u): " x, __func__ , __LINE__ , ##args)
+
+#define FRESCAN_WARNING(x,args...) \
+ printe("WARNING (%s): " x, __func__ , ##args)
+
+/**
+ * DEBUGGING FLAGS to enable/disable debugging messages
+ **/
+
+#define FRESCAN_SERVERS_ENABLE_DEBUG false
+#define FRESCAN_PACKETPOOL_ENABLE_DEBUG false
+#define FRESCAN_FRAG_ENABLE_DEBUG false
+#define FRESCAN_INIT_ENABLE_DEBUG false
+#define FRESCAN_SEND_ENABLE_DEBUG false
+#define FRESCAN_RECV_ENABLE_DEBUG false
+#define FRESCAN_RX_HOOK_ENABLE_DEBUG false
+#define FRESCAN_SENT_HOOK_ENABLE_DEBUG false
+#define FRESCAN_QUEUES_ENABLE_DEBUG false
+#define FRESCAN_HW_BUFFER_ENABLE_DEBUG false
+#define FRESCAN_REPLENSH_ENABLE_DEBUG false
+
+#define FRESCAN_BWRES_ENABLE_DEBUG false
+#define FRESCAN_BWRES_ROBJS_ENABLE_DEBUG false
+#define FRESCAN_BWRES_REQUESTS_ENABLE_DEBUG false
+#define FRESCAN_BWRES_MANAGER_ENABLE_DEBUG false
+#define FRESCAN_BWRES_ACCEPTOR_ENABLE_DEBUG false
+#define FRESCAN_BWRES_MC_ENABLE_DEBUG false
+#define FRESCAN_BWRES_FNA_ENABLE_DEBUG false
+#define FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG false
+#define FRESCAN_BWRES_SA_ENABLE_DEBUG false
+
+/**
+ * MEASUREMENT FLAGS
+ */
+#define FRESCAN_MEASURE_REPL_TH false
+#define FRESCAN_MEASURE_REPL_PROGRAM false
+
+#endif // _MARTE_FRESCAN_DEBUG_H_
--- /dev/null
+/*!
+ * @file frescan_hw_buffer.c
+ *
+ * @brief functions to manage the hw transmission buffer
+ *
+ * @version 0.01
+ *
+ * @date 12-Mar-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This file contains the functions needed to manage the hw transmission buffer.
+ * This is needed to update the transmission buffer of the CAN chip with the
+ * message with highest priority. This could involve having to abort the
+ * frame that is currently in the buffer.
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#include "frescan_hw_buffer.h"
+
+#include <string.h> // memcpy
+#include <assert.h>
+
+#include "frescan_data.h" // frescan_data
+#include "frescan_debug.h" // DEBUG, FRESCAN_ERROR
+#include "frescan_servers.h" // frescan_servers_get_highest_prio
+#include "frescan_queues.h" // frescan_pqueue_xxx, frescan_servers_dequeue
+#include "frescan_id.h" // frescan_id_set_field
+
+/**
+ * frescan_hw_buffer_abort - abort the packet in the hw tx buffer
+ *
+ * This function aborts the packet that is currently in the hw transmission
+ * buffer of the chip. It is useful to prevent priority inversion when there
+ * is another packet with highest priority waiting in the frescan queues.
+ *
+ * NOTE: if the frame is already being transmitted it won't abort it. In both
+ * cases a IRQ will be raised and either 'frescan_hook_frame_sent' or
+ * 'frescan_hook_frame_aborted' will be called.
+ */
+
+int frescan_hw_buffer_abort(frescan_network_t net)
+{
+ int ret;
+
+ ret = ioctl(frescan_data[net].fd, CAN_IOCTL_ABORT_FRAME, NULL);
+ if (ret == -1) {
+ FRESCAN_ERROR ("could not abort the frame\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * frescan_hw_buffer_update - update the hw tx buffer
+ *
+ * This function updates the hw tx buffer with the packet with highest
+ * priority (including fp packets and server packets).
+ *
+ * TODO: use copy of pointer
+ */
+
+int frescan_hw_buffer_update(frescan_network_t net)
+{
+ int ret;
+ bool is_frame_in_chip, is_fp_highest_prio;
+ uint32_t frag_flag;
+ frescan_packet_t *packet;
+ frescan_prio_queue_t *pqueue;
+ frescan_prio_t fprio, sprio, prio;
+ frescan_ss_t id;
+
+ ret = frescan_servers_get_highest_prio(net, &id, &sprio);
+ assert(ret == 0);
+
+ pqueue = frescan_data[net].queues.tx_fp_queue;
+
+ ret = frescan_pqueue_get_highest_prio(pqueue, &packet, &fprio);
+ assert(ret == 0);
+
+ if ((id == FRESCAN_MX_IDS) && (packet == NULL)) {
+ DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG, "(ss:0 fp:0)\n");
+ return 0;
+ }
+
+ if ((id != FRESCAN_MX_IDS) && (packet == NULL)) {
+ DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG, "(ss:1 fp:0)\n");
+ is_fp_highest_prio = false;
+ }
+
+ if ((id == FRESCAN_MX_IDS) && (packet != NULL)) {
+ DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG, "(ss:0 fp:1)\n");
+ is_fp_highest_prio = true;
+ }
+
+ if ((id != FRESCAN_MX_IDS) && (packet != NULL)) {
+ DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG, "(ss:1 fp:1)\n");
+ is_fp_highest_prio = (fprio > sprio);
+ }
+
+ prio = (is_fp_highest_prio) ? fprio : sprio;
+ is_frame_in_chip = (frescan_data[net].last_packet != NULL);
+
+ if (is_frame_in_chip) {
+ if (prio > frescan_data[net].last_packet_prio) {
+ // TODO: if same server, dont abort
+ DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG, "abort frame\n");
+ ret = frescan_hw_buffer_abort(net);
+ assert(ret == 0);
+ return 0;
+ } else {
+ DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG,
+ "frame in chip with highest or equal prio\n");
+ return 0;
+ }
+ }
+
+ if (is_fp_highest_prio) {
+ ret = frescan_pqueue_dequeue(pqueue, &packet, &prio, 0);
+ assert(ret == 0);
+ } else {
+ ret = frescan_servers_dequeue(net, id, &packet, &prio);
+ assert(ret == 0);
+
+ frescan_id_set_field(&packet->frame->id,
+ FRESCAN_FIELD_PRIO,
+ (uint32_t)prio);
+ }
+
+ if (packet->buffer_pending_bytes > 8) {
+ packet->frame->dlc = 8;
+ } else {
+ packet->frame->dlc = packet->buffer_pending_bytes;
+ }
+
+ memcpy(packet->frame->data,
+ packet->buffer_read_pointer,
+ packet->frame->dlc);
+
+ packet->buffer_pending_bytes -= packet->frame->dlc;
+ packet->buffer_read_pointer += packet->frame->dlc;
+
+ frag_flag = (packet->buffer_pending_bytes > 0) ? 1 : 0;
+ frescan_id_set_field
+ (&packet->frame->id, FRESCAN_FIELD_FRAG_FLAG, frag_flag);
+
+ frescan_data[net].last_packet = packet;
+ frescan_data[net].last_packet_prio = prio;
+
+ DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG,
+ "frame->id:0x%X pend_bytes:%u dlc:%u fflag:%u\n",
+ packet->frame->id,
+ packet->buffer_pending_bytes,
+ packet->frame->dlc,
+ frag_flag);
+
+ ret = write(frescan_data[net].fd,
+ (void *)packet->frame,
+ sizeof(struct can_frame_t));
+
+ if (ret != sizeof(struct can_frame_t)) {
+ FRESCAN_ERROR ("could not send frame\n");
+ return ret;
+ }
+
+ return 0;
+}
--- /dev/null
+/*!
+ * @file frescan_hw_buffer.h
+ *
+ * @brief functions to manage the hw transmission buffer
+ *
+ * @version 0.01
+ *
+ * @date 12-Mar-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This file contains the functions needed to manage the hw transmission buffer.
+ * This is needed to update the transmission buffer of the CAN chip with the
+ * message with highest priority. This could involve having to abort the
+ * frame that is currently in the buffer.
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _MARTE_FRESCAN_HW_BUFFER_H_
+#define _MARTE_FRESCAN_HW_BUFFER_H_
+
+#include "frescan_types.h"
+
+extern int frescan_hw_buffer_update(frescan_network_t net);
+
+#endif // _MARTE_FRESCAN_HW_BUFFER_H_
--- /dev/null
+/*!
+ * @file frescan_id.c
+ *
+ * @brief functions to manage the fields of the FRESCAN Identifier
+ *
+ * @version 0.01
+ *
+ * @date 27-Feb-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This file contains the functions needed to manage the fields of a
+ * FRESCAN identifier. That is, how the 29 CAN ID bits of each frame are
+ * allocated in the FRESCAN protocol. If this configuration was to
+ * be changed (for example, the bits per field or the position of the
+ * fields inside the ID), then only these functions need to be modified
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#include "frescan_id.h"
+
+typedef struct {
+ uint32_t bit_offset; // offset of the field in the CAN id
+ uint32_t bit_mask; // the number of bits of the field in a mask
+} frescan_field_t;
+
+static frescan_field_t the_fields[] = {
+ {.bit_offset = 21, .bit_mask = 0xFF},
+ {.bit_offset = 17, .bit_mask = 0x0F},
+ {.bit_offset = 13, .bit_mask = 0x0F},
+ {.bit_offset = 9, .bit_mask = 0x0F},
+ {.bit_offset = 1, .bit_mask = 0xFF},
+ {.bit_offset = 0, .bit_mask = 0x01},
+};
+
+void frescan_id_set_field(uint32_t *id, uint32_t field, uint32_t value)
+{
+ frescan_field_t *f = &the_fields[field];
+
+ *id = *id & ~(f->bit_mask << f->bit_offset);
+ *id = *id | ((value & f->bit_mask) << f->bit_offset);
+}
+
+uint32_t frescan_id_get_field(uint32_t id, uint32_t field)
+{
+ frescan_field_t *f = &the_fields[field];
+ return ((id >> f->bit_offset) & f->bit_mask);
+}
--- /dev/null
+/*!
+ * @file frescan_id.h
+ *
+ * @brief functions to manage the fields of the FRESCAN Identifier
+ *
+ * @version 0.01
+ *
+ * @date 27-Feb-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This file contains the functions needed to manage the fields of a
+ * FRESCAN identifier. That is, how the 29 CAN ID bits of each frame are
+ * allocated in the FRESCAN protocol. If this configuration was to
+ * be changed (for example, the bits per field or the position of the
+ * fields inside the ID), then only these functions need to be modified
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _MARTE_FRESCAN_ID_H_
+#define _MARTE_FRESCAN_ID_H_
+
+#include <stdint.h> // uint32_t
+
+/**
+ * 8 4 4 4 8 1 bytes
+ * +----------------------------------------------------------------+
+ * | prio | dest | src | chan | frag_id | frag_flag |
+ * +----------------------------------------------------------------+
+ *
+ */
+
+#define FRESCAN_FIELD_PRIO 0
+#define FRESCAN_FIELD_DEST 1
+#define FRESCAN_FIELD_SRC 2
+#define FRESCAN_FIELD_CHAN 3
+#define FRESCAN_FIELD_FRAG_ID 4
+#define FRESCAN_FIELD_FRAG_FLAG 5
+
+extern void frescan_id_set_field(uint32_t *id, uint32_t field, uint32_t value);
+
+extern uint32_t frescan_id_get_field(uint32_t id, uint32_t field);
+
+#endif // _MARTE_FRESCAN_ID_H_
--- /dev/null
+/*!
+ * @file frescan_packets.h
+ *
+ * @brief FRESCAN packets definition and pool
+ *
+ * @version 0.01
+ *
+ * @date 27-Feb-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This file contains the FRESCAN packets definition and functions to
+ * allocate and free them from a global pool of packets statically
+ * preallocated.
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#include "frescan_packets.h"
+#include "frescan_debug.h"
+#include "frescan_config.h"
+#include <misc/freelist.h>
+
+/**
+ * the_packet_pool - pool of frescan packets
+ *
+ * Like in the CAN driver, in FRESCAN we have a statically preallocated pool
+ * of packets that we will manage through a freelist in O(1) time.
+ */
+
+static frescan_packet_t the_packet_pool[FRESCAN_MX_PACKETS];
+static freelist_t the_packet_pool_freelist;
+
+#ifdef FRESCAN_PACKETPOOL_ENABLE_DEBUG
+ static int allocated_total = 0;
+#endif
+
+/**
+ * frescan_packets_init
+ *
+ * Initializes a pool of packets that will be managed internally
+ * TODO: initalization flag
+ */
+
+int frescan_packets_init() {
+ DEBUG(FRESCAN_PACKETPOOL_ENABLE_DEBUG, "initialize freelist\n");
+ return freelist_init(&the_packet_pool_freelist, FRESCAN_MX_PACKETS);
+}
+
+/**
+ * frescan_packets_alloc
+ *
+ * Allocates a frame from the pool of packets. On error it returns NULL
+ */
+
+frescan_packet_t *frescan_packets_alloc() {
+ int pos;
+
+ pos = freelist_alloc(&the_packet_pool_freelist);
+ if (pos == -1) {
+ FRESCAN_ERROR("could not allocate packet\n");
+ FRESCAN_ERROR("hint: configure FRESCAN_MX_PACKETS\n");
+ return NULL;
+ }
+
+#ifdef FRESCAN_PACKETPOOL_ENABLE_DEBUG
+ allocated_total++;
+#endif
+
+ DEBUG(FRESCAN_PACKETPOOL_ENABLE_DEBUG,
+ "allocating packet, pos:%d, total:%d\n", pos, allocated_total);
+
+ the_packet_pool[pos].pool_pos = pos; // to know how to free it
+ return &the_packet_pool[pos];
+}
+
+/**
+ * frescan_packets_free
+ *
+ * Frees a frame and returns it to the pool of packets.
+ */
+
+int frescan_packets_free(frescan_packet_t *packet)
+{
+#ifdef FRESCAN_PACKETPOOL_ENABLE_DEBUG
+ allocated_total--;
+#endif
+ DEBUG(FRESCAN_PACKETPOOL_ENABLE_DEBUG,
+ "freeing packet, pos:%d, total:%d\n",
+ packet->pool_pos, allocated_total);
+
+ return freelist_free(&the_packet_pool_freelist, packet->pool_pos);
+}
--- /dev/null
+/*!
+ * @file frescan_packets.h
+ *
+ * @brief FRESCAN packets definition and pool
+ *
+ * @version 0.01
+ *
+ * @date 27-Feb-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This file contains the FRESCAN packets definition and functions to
+ * allocate and free them from a global pool of packets statically
+ * preallocated.
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _FRESCAN_PACKETS_H_
+#define _FRESCAN_PACKETS_H_
+
+#include "frescan_types.h"
+
+extern int frescan_packets_init();
+extern frescan_packet_t *frescan_packets_alloc();
+extern int frescan_packets_free(frescan_packet_t *packet);
+
+#endif // _FRESCAN_PACKETS_H_
--- /dev/null
+/*!
+ * @file frescan_queues.c
+ *
+ * @brief FRESCAN queues to manage the packets by prio and servers
+ *
+ * @version 0.01
+ *
+ * @date 27-Feb-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This file contains the FRESCAN queues where frescan packets are stored and
+ * managed.
+ *
+ * TODO: disable interrupts for mutual exclusion!!!
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#include <stdlib.h>
+#include <time.h>
+
+#include "frescan_queues.h"
+#include "frescan_packets.h"
+#include "frescan_debug.h"
+#include "frescan_id.h"
+#include "frescan_data.h"
+
+/**
+ * frescan_pqueue_create() - creates a priority queue
+ */
+
+static inline frescan_prio_queue_t *frescan_pqueue_create(uint32_t max_prio,
+ frescan_network_t net)
+{
+ int ret, prio;
+ frescan_prio_queue_t *pq; // priority queue
+
+ pq = (frescan_prio_queue_t *)malloc(sizeof(frescan_prio_queue_t));
+ if (pq == NULL) {
+ FRESCAN_ERROR("could not allocate memory for prio queue\n");
+ return NULL;
+ }
+
+ pq->max_prio = max_prio;
+ pq->net = net;
+
+ ret = sem_init (&pq->sem, 0, 0);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not init the semaphore\n");
+ free(pq);
+ return NULL;
+ }
+
+ pq->fifo_queues = (frescan_packet_t *)
+ malloc(max_prio * sizeof(frescan_packet_t));
+
+ for(prio=0; prio<max_prio; prio++) {
+ INIT_LIST_HEAD(&(pq->fifo_queues[prio].fifo_list));
+ }
+
+ return pq;
+}
+
+/**
+ * frescan_queues_init() - initialize the queues
+ *
+ * 1.- create the transmission fixed priority queue
+ * 2.- create the rx channels and its associated priority queues
+ *
+ * TODO: when error free memory
+ */
+
+int frescan_queues_init(frescan_queues_t *queues,
+ frescan_init_params_t *params)
+{
+ int i;
+ uint32_t max_prio;
+
+ // create transmission fixed priority queue
+ queues->tx_fp_queue = frescan_pqueue_create(params->tx_fp_max_prio,
+ params->net);
+
+ if (queues->tx_fp_queue == NULL) {
+ FRESCAN_ERROR("could not allocate memory for tx fp queue\n");
+ return -1;
+ }
+
+ // create receiving channels
+ queues->rx_channel_queues = (frescan_prio_queue_t **)
+ malloc(params->rx_num_of_channels *
+ sizeof(frescan_prio_queue_t *));
+
+ if (queues->rx_channel_queues == NULL) {
+ FRESCAN_ERROR
+ ("could not allocate memory for receiving channels\n");
+ return -1;
+ }
+
+ queues->num_rx_channels = params->rx_num_of_channels;
+
+ // create a priority queue for each channel
+ for(i=0; i<params->rx_num_of_channels; i++) {
+
+ if (params->rx_channel_max_prio == NULL) {
+ max_prio = params->tx_fp_max_prio;
+ } else {
+ max_prio = params->rx_channel_max_prio[i];
+ }
+
+ queues->rx_channel_queues[i] = frescan_pqueue_create
+ (max_prio, params->net);
+
+ if (queues->rx_channel_queues[i] == NULL) {
+ FRESCAN_ERROR
+ ("could not allocate memory for rx pq %d\n", i);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * frescan_pqueue_enqueue() - enqueue a packet
+ *
+ * check the packet flags and enqueue the packet in the appropiate queue
+ */
+
+int frescan_pqueue_enqueue(frescan_prio_queue_t *pqueue,
+ frescan_packet_t *packet,
+ frescan_prio_t prio)
+{
+ int ret;
+
+ if (prio >= pqueue->max_prio) {
+ FRESCAN_ERROR("priority of the packet is too high\n");
+ return -1;
+ }
+
+ DEBUG(FRESCAN_QUEUES_ENABLE_DEBUG,
+ "enqueue packet with prio %u, pending %u\n",
+ prio, packet->buffer_pending_bytes);
+
+ list_add_tail(&(packet->fifo_list),
+ &(pqueue->fifo_queues[prio].fifo_list));
+
+ ret = sem_post(&pqueue->sem);
+ if (ret != 0) return ret;
+
+ return 0;
+}
+
+/**
+ * frescan_pqueue_requeue() - requeue a packet
+ */
+
+int frescan_pqueue_requeue(frescan_prio_queue_t *pqueue,
+ frescan_packet_t *packet,
+ frescan_prio_t prio)
+{
+ int ret;
+
+ if (prio >= pqueue->max_prio) {
+ FRESCAN_ERROR("priority of the packet is too high\n");
+ return -1;
+ }
+
+ list_add(&packet->fifo_list, &(pqueue->fifo_queues[prio].fifo_list));
+
+ ret = sem_post(&pqueue->sem);
+ if (ret != 0) return ret;
+
+ return 0;
+}
+
+/**
+ * frescan_pqueue_dequeue() - dequeue the packet with highest priority
+ */
+
+int frescan_pqueue_dequeue(frescan_prio_queue_t *pqueue,
+ frescan_packet_t **packet,
+ frescan_prio_t *packet_prio,
+ bool blocking)
+{
+ int prio;
+ int ret;
+ frescan_packet_t *tmp = NULL;
+ struct list_head *pos;
+
+ *packet = NULL;
+
+ if (blocking) {
+ DEBUG(FRESCAN_QUEUES_ENABLE_DEBUG, "calling sem_wait\n");
+ sem_wait(&pqueue->sem);
+ } else {
+ ret = sem_trywait (&pqueue->sem);
+ if (ret != 0) {
+ DEBUG(FRESCAN_QUEUES_ENABLE_DEBUG,
+ "sem_trywait was locked (no packets)\n");
+ return 0;
+ }
+ }
+
+ DEBUG(FRESCAN_QUEUES_ENABLE_DEBUG,
+ "check priority fifo queues (max_prio=%u)\n", pqueue->max_prio);
+
+ // NOTE: we only acquire the lock if we block because non-blocking
+ // calls are made from a context with no interrupts (when updating
+ // the buffer at 'frescan_hw_buffer_update' which is always called
+ // with interrupts disabled)
+ if (blocking) FRESCAN_ACQUIRE_LOCK(&frescan_data[pqueue->net].lock);
+
+ for(prio=pqueue->max_prio-1; prio >= 0; prio--) {
+ if (!list_empty(&pqueue->fifo_queues[prio].fifo_list)) {
+ list_for_each(pos,
+ &pqueue->fifo_queues[prio].fifo_list) {
+ tmp = list_entry(pos, frescan_packet_t,
+ fifo_list);
+ break;
+ }
+ *packet = tmp;
+ list_del(&tmp->fifo_list);
+ break;
+ }
+ }
+
+ if (blocking) FRESCAN_RELEASE_LOCK(&frescan_data[pqueue->net].lock);
+
+ DEBUG(FRESCAN_QUEUES_ENABLE_DEBUG, "dequeued prio %u\n", prio);
+ *packet_prio = prio;
+
+ return 0;
+}
+
+/**
+ * frescan_pqueue_get_highest_prio() - returns the packet with highest prio
+ * but not extracting it from the queue.
+ */
+
+int frescan_pqueue_get_highest_prio(frescan_prio_queue_t *pqueue,
+ frescan_packet_t **packet,
+ frescan_prio_t *packet_prio)
+{
+ int prio;
+ frescan_packet_t *tmp = NULL;
+ struct list_head *pos;
+
+ *packet = NULL;
+
+ for(prio=pqueue->max_prio-1; prio >= 0; prio--) {
+ if (!list_empty(&pqueue->fifo_queues[prio].fifo_list)) {
+ list_for_each(pos,
+ &pqueue->fifo_queues[prio].fifo_list) {
+ tmp = list_entry(pos, frescan_packet_t,
+ fifo_list);
+ break;
+ }
+ *packet = tmp;
+ break;
+ }
+ }
+
+ DEBUG(FRESCAN_QUEUES_ENABLE_DEBUG, "highest prio %u\n", prio);
+ *packet_prio = prio;
+
+ return 0;
+}
+
+
+/**
+ * frescan_servers_enqueue() - enqueue a packet through a server
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ * @packet: the packet being enqueued
+ *
+ */
+
+int frescan_servers_enqueue(frescan_network_t net,
+ frescan_ss_t id,
+ frescan_packet_t *packet)
+{
+ frescan_ss_data_t *server = &frescan_data[net].ss_data[id];
+
+ clock_gettime (CLOCK_MONOTONIC, &packet->timestamp);
+
+ DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG, "id:%u timestamp:(%d, %d)\n",
+ id, packet->timestamp.tv_sec, packet->timestamp.tv_nsec);
+
+ // add the packet to the server fifo list
+ list_add_tail(&packet->fifo_list, &server->packet_list.fifo_list);
+
+ // if the server was inactive (no packets) put it in the active list
+ if (server->pending_packets == 0) {
+ DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG,
+ "ss becomes active act_time=timestamp\n");
+ list_add_tail(&server->servers_list,
+ &frescan_data[net].ss_active_head.servers_list);
+ server->act_time = packet->timestamp;
+ }
+
+ server->pending_packets++;
+ return 0;
+}
+
+/**
+ * frescan_servers_requeue() - requeue a packet through a server
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ * @packet: the packet being requeued
+ *
+ */
+
+int frescan_servers_requeue(frescan_network_t net,
+ frescan_ss_t id,
+ frescan_packet_t *packet)
+{
+ DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG,
+ "requeue packet for id:%u\n", id);
+
+ // add the packet to the server fifo list
+ list_add(&packet->fifo_list,
+ &frescan_data[net].ss_data[id].packet_list.fifo_list);
+
+ // if the server was inactive (no packets to send) put it active
+ // (in the active list)
+ if (frescan_data[net].ss_data[id].pending_packets == 0) {
+ DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG,
+ "server was inactive, put in the active list\n");
+ list_add(&frescan_data[net].ss_data[id].servers_list,
+ &frescan_data[net].ss_active_head.servers_list);
+ }
+
+ frescan_data[net].ss_data[id].pending_packets++;
+ return 0;
+}
+
+/**
+ * frescan_servers_dequeue() - dequeue a packet from a server
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ * @packet: the packet dequeued
+ * @packet_prio: the priority current of the server
+ *
+ */
+
+int frescan_servers_dequeue(frescan_network_t net,
+ frescan_ss_t id,
+ frescan_packet_t **packet,
+ frescan_prio_t *packet_prio)
+{
+ struct list_head *pos;
+ frescan_ss_data_t *server;
+
+ server = &frescan_data[net].ss_data[id];
+
+ if (list_empty(&server->packet_list.fifo_list)) {
+ FRESCAN_ERROR("no packet in server %d fifo list\n", id);
+ return -1;
+ }
+
+ list_for_each(pos, &server->packet_list.fifo_list) {
+ *packet = list_entry(pos, frescan_packet_t, fifo_list);
+ break;
+ }
+
+ list_del(&((*packet)->fifo_list));
+ *packet_prio = server->current_priority;
+ server->pending_packets--;
+
+ if (server->pending_packets == 0) {
+ DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG,
+ "no more packets, delete from active list\n");
+ list_del(&server->servers_list);
+ }
+
+ DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG,
+ "dequeued packet server:%u cur_prio:%u pending:%u\n",
+ id, *packet_prio, server->pending_packets);
+
+ return 0;
+}
--- /dev/null
+/*!
+ * @file frescan_queues.h
+ *
+ * @brief FRESCAN queues to manage the packets by prio and servers
+ *
+ * @version 0.01
+ *
+ * @date 27-Feb-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This file contains the FRESCAN queues where frescan packets are stored and
+ * managed.
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _MARTE_FRESCAN_QUEUES_H_
+#define _MARTE_FRESCAN_QUEUES_H_
+
+#include "frescan_types.h"
+
+/**
+ * frescan_queues_init() - initialize the queues
+ *
+ * This function initializes the queue structures for an instance of frescan
+ * protocol. We provide different sizes and constants so, at initialization
+ * time, the structures are allocated from the heap. Note, that this approach
+ * is not conflicting with real-time systems where typically static allocation
+ * is used because we only do it at the initialization and also because we
+ * are using a real-time memory allocator. The advantage is that we have the
+ * flexibility of using different values for different instances of the
+ * protocol and that we can also supply the protocol compiled as a library.
+ *
+ * @queues: the queues structures
+ * @frescan_init_params_t: some init parameters for the queues
+ *
+ * TODO: add maximum number of packets per queue?? so far they are taken from
+ * the same pool.
+ * TODO: add policy for overwritting
+ */
+
+int frescan_queues_init(frescan_queues_t *queues,
+ frescan_init_params_t *params);
+
+/**
+ * frescan_pqueue_enqueue() - enqueue a packet
+ *
+ * this function enqueues a frescan_packet into the a priority queue. For the
+ * case of same priority packets they are stored at the tail, following a FIFO
+ * enqueuing policy.
+ *
+ * @pqueue: the priority queue
+ * @packet: the packet that we want to store
+ *
+ */
+
+int frescan_pqueue_enqueue(frescan_prio_queue_t *pqueue,
+ frescan_packet_t *packet,
+ frescan_prio_t prio);
+
+/**
+ * frescan_pqueue_requeue() - requeue a packet
+ *
+ * this function requeues a previously extracted frescan_packet. It puts
+ * the packet at the head of the fifo queue. This is useful when you abort
+ * the transmission of the packet beacuse another one with highest priority
+ * has arrived, and you still want to preserve the order in which the packets
+ * where enqueued
+ *
+ * @pqueue: the priority queue
+ * @packet: the packet that we want to store
+ *
+ */
+
+int frescan_pqueue_requeue(frescan_prio_queue_t *pqueue,
+ frescan_packet_t *packet,
+ frescan_prio_t prio);
+
+/**
+ * frescan_pqueue_dequeue() - dequeue the packet with highest priority
+ *
+ * @pqueue: the priority queue
+ * @packet: the packet extracted
+ * @blocking: if there are no packets we can choose to block or not. In
+ * a non-blocking mode, if there are no packets 'packet' will be NULL
+ *
+ */
+
+int frescan_pqueue_dequeue(frescan_prio_queue_t *pqueue,
+ frescan_packet_t **packet,
+ frescan_prio_t *packet_prio,
+ bool blocking);
+
+/**
+ * frescan_pqueue_get_highest_prio() - returns the packet with highest prio
+ * but not extracting it from the queue.
+ *
+ * @pqueue: the priority queue
+ * @packet: the packet with highest prio (not extracted from the pqueue)
+ *
+ */
+
+int frescan_pqueue_get_highest_prio(frescan_prio_queue_t *pqueue,
+ frescan_packet_t **packet,
+ frescan_prio_t *packet_prio);
+
+/**
+ * frescan_servers_enqueue() - enqueue a packet through a server
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ * @packet: the packet being enqueued
+ *
+ */
+
+int frescan_servers_enqueue(frescan_network_t net,
+ frescan_ss_t id,
+ frescan_packet_t *packet);
+
+/**
+ * frescan_servers_requeue() - requeue a packet through a server
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ * @packet: the packet being requeued
+ *
+ */
+
+int frescan_servers_requeue(frescan_network_t net,
+ frescan_ss_t id,
+ frescan_packet_t *packet);
+
+/**
+ * frescan_servers_dequeue() - dequeue a packet from a server
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ * @packet: the packet dequeued
+ *
+ */
+
+int frescan_servers_dequeue(frescan_network_t net,
+ frescan_ss_t id,
+ frescan_packet_t **packet,
+ frescan_prio_t *packet_prio);
+
+#endif // _MARTE_FRESCAN_QUEUES_H_
--- /dev/null
+/*!
+ * @file frescan_servers.c
+ *
+ * @brief FRESCAN sporadic servers
+ *
+ * @version 0.01
+ *
+ * @date 27-Feb-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This file contains the FRESCAN sporadic servers that allow to isolate
+ * different streams of data by assigning them a budget and replenishment
+ * period.
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#include "frescan_servers.h"
+#include "frescan_servers_replenishments.h" // frescan_replenishments_xxx
+#include "frescan_debug.h"
+#include "frescan_packets.h"
+#include "frescan_data.h"
+#include <signal.h>
+#include <time.h>
+#include <misc/linux_list.h>
+#include "fosa_time_timespec.h" // smaller_timespec
+
+/**
+ * frescan_servers_init() - initialize server structures
+ *
+ * @net: the network instance
+ */
+
+int frescan_servers_init(frescan_network_t net)
+{
+ int ret, i;
+
+ DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG, "initializing servers\n");
+
+ ret = freelist_init(&frescan_data[net].ss_id_freelist, FRESCAN_MX_IDS);
+ if (ret != 0) return ret;
+
+ for (i=0; i<FRESCAN_MX_NETWORKS; i++) {
+ INIT_LIST_HEAD(&frescan_data[net].ss_active_head.servers_list);
+ }
+
+ ret = frescan_replenishments_init(net);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not initialize the replenishments\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * frescan_servers_create() - create a sporadic server
+ *
+ * @net: the network instance
+ * @params: the parameters for the server
+ * @id: the identificator for the server as a return value
+ *
+ */
+
+int frescan_servers_create(frescan_network_t net,
+ const frescan_server_params_t *params,
+ frescan_ss_t *id)
+{
+ int i, ret, pos;
+ struct sigevent evp;
+ frescan_ss_data_t *server;
+ frescan_repl_op_t *repl;
+
+ FRESCAN_ACQUIRE_LOCK(&frescan_data[net].lock);
+ pos = freelist_alloc(&frescan_data[net].ss_id_freelist);
+ FRESCAN_RELEASE_LOCK(&frescan_data[net].lock);
+
+ if (pos == -1) {
+ FRESCAN_ERROR("could not allocate servers\n");
+ return -1;
+ }
+
+ *id = (frescan_ss_t)pos;
+
+ server = &frescan_data[net].ss_data[*id];
+
+ server->net = net;
+ server->id = *id;
+ server->committed_params = *params;
+ server->perceived_params = server->committed_params;
+ server->current_priority = params->prio;
+ server->pending_packets = 0;
+
+ // the first act_time is set to the server creation time
+ clock_gettime (CLOCK_MONOTONIC, &server->act_time);
+
+ // init the list of packets associated to the server
+ INIT_LIST_HEAD(&server->packet_list.fifo_list);
+
+ // allocate the replenishment capacity queue
+ INIT_LIST_HEAD(&server->replenishments.repl_list);
+ for (i=0; i < params->budget; i++) {
+ repl = frescan_repl_op_alloc();
+ repl->when = server->act_time;
+ repl->amount = 1;
+ list_add_tail(&repl->repl_list,
+ &server->replenishments.repl_list);
+ }
+
+ // the repl timer sends a signal when it expires with the server id
+ evp.sigev_notify = SIGEV_SIGNAL;
+ evp.sigev_signo = FRESCAN_REPL_SIGNAL_NUM;
+ evp.sigev_value.sival_int = (int)*id;
+
+ ret = timer_create (CLOCK_MONOTONIC, &evp, &server->repl_timer);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not create timer\n");
+ return ret;
+ }
+
+ DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG,
+ "server created, id:%u budget:%u prio:%u\n",
+ *id, server->committed_params.budget,
+ server->committed_params.prio);
+
+ return 0;
+}
+
+/**
+ * frescan_servers_set_perceived() - update a sporadic server perceived data
+ *
+ * @net: the network instance
+ * @params: the parameters for the server
+ * @id: the identificator for the server
+ *
+ */
+
+int frescan_servers_set_perceived(frescan_network_t net,
+ const frescan_server_params_t *params,
+ frescan_ss_t id)
+{
+ frescan_data[net].ss_data[id].perceived_params = *params;
+ return 0;
+}
+
+/**
+ * frescan_servers_commit_perceived() - commit sporadic server perceived data
+ *
+ * Add or remove repl operations according to the budget change
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ *
+ */
+
+int frescan_servers_commit_perceived(frescan_network_t net,
+ frescan_ss_t id)
+{
+ int i, ret;
+ frescan_ss_data_t *server;
+ int budget_variation;
+ frescan_repl_op_t *repl = NULL;
+ struct list_head *pos;
+
+ server = &frescan_data[net].ss_data[id];
+ budget_variation = server->perceived_params.budget -
+ server->committed_params.budget;
+
+ if (budget_variation > 0) {
+ // we have more budget: add repl ops to the tail
+ for (i=0; i < budget_variation; i++) {
+ repl = frescan_repl_op_alloc();
+ repl->when = server->act_time; // TODO: check when!
+ repl->amount = 1;
+ list_add_tail(&repl->repl_list,
+ &server->replenishments.repl_list);
+ }
+ } else {
+ // we have less budget: remove repl ops from the tail
+ for (i=0; i > budget_variation; i--) {
+ list_for_each_prev(pos,
+ &server->replenishments.repl_list) {
+ repl = list_entry(pos,
+ frescan_repl_op_t,
+ repl_list);
+ break;
+ }
+ list_del(&repl->repl_list);
+
+ ret = frescan_repl_op_free(repl);
+ if (ret != 0) return ret;
+ }
+ }
+
+ server->committed_params = server->perceived_params;
+
+ return 0;
+}
+
+/**
+ * frescan_servers_update() - update a sporadic server data
+ *
+ * @net: the network instance
+ * @params: the parameters for the server
+ * @id: the identificator for the server
+ *
+ */
+
+int frescan_servers_update(frescan_network_t net,
+ const frescan_server_params_t *params,
+ frescan_ss_t id)
+{
+ int ret;
+
+ ret = frescan_servers_set_perceived(net, params, id);
+ if (ret != 0) return ret;
+
+ ret = frescan_servers_commit_perceived(net, id);
+ if (ret != 0) return ret;
+
+ return 0;
+}
+
+/**
+ * frescan_servers_destroy() - delete a sporadic server
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ *
+ */
+
+int frescan_servers_destroy(frescan_network_t net, frescan_ss_t id)
+{
+ int ret;
+ frescan_repl_op_t *repl;
+ frescan_packet_t *packet;
+ frescan_ss_data_t *server;
+
+ server = &frescan_data[net].ss_data[id];
+
+ ret = timer_delete (server->repl_timer);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not delete timer\n");
+ return ret;
+ }
+
+ // remove packets associated to the server
+ if (!list_empty(&server->packet_list.fifo_list)) {
+ FRESCAN_WARNING("destroying a server with packets enqueued\n");
+ list_for_each_entry(packet,
+ &server->packet_list.fifo_list,
+ fifo_list) {
+ ret = frescan_packets_free(packet);
+ if (ret != 0) return ret;
+ }
+ INIT_LIST_HEAD(&server->packet_list.fifo_list);
+ }
+
+ // remove the servers replenishment capacity queue
+ list_for_each_entry(repl,
+ &server->replenishments.repl_list,
+ repl_list) {
+ ret = frescan_repl_op_free(repl);
+ if (ret != 0) return ret;
+ }
+ INIT_LIST_HEAD(&server->replenishments.repl_list);
+
+ FRESCAN_ACQUIRE_LOCK(&frescan_data[net].lock);
+ list_del(&server->servers_list);
+ ret = freelist_free(&frescan_data[net].ss_id_freelist, id);
+ FRESCAN_RELEASE_LOCK(&frescan_data[net].lock);
+
+ if (ret != 0) {
+ FRESCAN_ERROR("could not free server data from pool\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * frescan_servers_get_data() - get a sporadic server data
+ *
+ * @net: the network instance
+ * @params: the parameters of the server
+ * @id: the identificator for the server
+ *
+ */
+
+int frescan_servers_get_data(frescan_network_t net,
+ frescan_server_params_t *params,
+ frescan_ss_t id)
+{
+ *params = frescan_data[net].ss_data[id].perceived_params;
+ return 0;
+}
+
+/**
+ * frescan_servers_get_current_budget() - get the current ss budget
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ * @current_budget: the current budget of the server
+ *
+ * Traverse the capacity queue until we find a replenishment operation
+ * that was programmed for a time later than now. The number of iterations
+ * is the budget in the capacity queue.
+ *
+ * That budget must be modified if the perceived budget has not been
+ * committed yet.
+ *
+ */
+
+int frescan_servers_get_current_budget(frescan_network_t net,
+ frescan_ss_t id,
+ frescan_budget_t *current_budget)
+{
+ struct timespec now;
+ frescan_repl_op_t *repl;
+ frescan_ss_data_t *server;
+ int count;
+
+ server = &frescan_data[net].ss_data[id];
+
+ // first we get the current real budget in the capacity queue
+ clock_gettime (CLOCK_MONOTONIC, &now);
+
+ count = 0;
+ list_for_each_entry(repl,
+ &server->replenishments.repl_list,
+ repl_list) {
+ if (smaller_timespec(now, repl->when)) break;
+ count = count + 1;
+ }
+
+ // if the perceived budget is less than the real budget
+ // we have to give a _perceived_ current budget
+ if (server->perceived_params.budget < server->committed_params.budget) {
+ count = server->perceived_params.budget -
+ (server->committed_params.budget - count);
+ if (count < 0) count = 0;
+ }
+
+ *current_budget = (frescan_budget_t)count;
+
+ return 0;
+}
+
+/**
+ * frescan_servers_get_highest_prio() - get the server with highest priority
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ * @prio: the priority of that server
+ *
+ * For each active server, check the priority.
+ * If "id" is returned with a value of FRESCAN_MX_IDS,
+ * there are no active servers.
+ * NOTE: id=FRESCAN_MX_IDS is the identifier for fixed priority messages
+ * TODO: use a priority queue of active servers
+ *
+ */
+
+int frescan_servers_get_highest_prio(frescan_network_t net,
+ frescan_ss_t *id,
+ frescan_prio_t *prio)
+{
+ frescan_ss_data_t *server;
+
+ if (list_empty(&frescan_data[net].ss_active_head.servers_list)) {
+ DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG, "server list is empty\n");
+ *id = FRESCAN_MX_IDS;
+ return 0;
+ }
+
+ *prio = 0;
+ list_for_each_entry(server,
+ &frescan_data[net].ss_active_head.servers_list,
+ servers_list) {
+ if (server->current_priority >= *prio) {
+ *id = server->id;
+ *prio = server->current_priority;
+ }
+ }
+
+ DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG,
+ "highest prio:%u id:%u\n", *prio, *id);
+
+ return 0;
+}
+
+/**
+ * frescan_servers_frame_sent() - hook to control the server budget and prio
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ *
+ * This function is called when a frame has been effectively sent through the
+ * CAN bus and that frame is associated to a certain server. The function
+ * decreases the capacity of the server and sets the priority to background
+ * in case the budget is exhausted.
+ *
+ * NOTE: the replenishment operation is programmed using the corresponding
+ * function at frescan_servers_replenishments module
+ */
+
+int frescan_servers_frame_sent(frescan_network_t net,
+ frescan_ss_t id,
+ frescan_packet_t *packet)
+{
+ int ret;
+ struct timespec *repl_time;
+ frescan_ss_data_t *server;
+
+ server = &frescan_data[net].ss_data[id];
+
+ if (server->current_priority != FRESCAN_BACKGROUND_PRIO) {
+ if (smaller_timespec(packet->timestamp, server->act_time)) {
+ repl_time = &server->act_time;
+ } else {
+ repl_time = &packet->timestamp;
+ }
+
+ ret = frescan_replenishment_program(net, id, repl_time);
+ if (ret != 0) return -1;
+ }
+
+ return 0;
+}
--- /dev/null
+/*!
+ * @file frescan_servers.c
+ *
+ * @brief FRESCAN sporadic servers
+ *
+ * @version 0.01
+ *
+ * @date 27-Feb-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This file contains the FRESCAN sporadic servers that allow to isolate
+ * different streams of data by assigning them a budget and replenishment
+ * period.
+ *
+ * @license
+ *
+ * -----------------------------------------------------------------------
+ * Copyright (C) 2006 - 2008 FRESCOR consortium partners:
+ *
+ * Universidad de Cantabria, SPAIN
+ * University of York, UK
+ * Scuola Superiore Sant'Anna, ITALY
+ * Kaiserslautern University, GERMANY
+ * Univ. Politécnica Valencia, SPAIN
+ * Czech Technical University in Prague, CZECH REPUBLIC
+ * ENEA SWEDEN
+ * Thales Communication S.A. FRANCE
+ * Visual Tools S.A. SPAIN
+ * Rapita Systems Ltd UK
+ * Evidence ITALY
+ *
+ * See http://www.frescor.org for a link to partners' websites
+ *
+ * FRESCOR project (FP6/2005/IST/5-034026) is funded
+ * in part by the European Union Sixth Framework Programme
+ * The European Union is not liable of any use that may be
+ * made of this code.
+ *
+ * This file is part of FRESCAN
+ *
+ * FRESCAN is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * FRESCAN is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * distributed with FRESCAN; see file COPYING. If not, write to the
+ * Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * As a special exception, including FRESCAN header files in a file,
+ * instantiating FRESCAN generics or templates, or linking other files
+ * with FRESCAN objects to produce an executable application, does not
+ * by itself cause the resulting executable application to be covered
+ * by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be
+ * covered by the GNU Public License.
+ * -----------------------------------------------------------------------
+ *
+ */
+
+#include "frescan_servers.h"
+#include "frescan_servers_replenishments.h" // frescan_replenishments_xxx
+#include "frescan_debug.h"
+#include "frescan_data.h"
+#include <misc/linux_list.h>
+#include <misc/timespec_operations.h>
+#include <signal.h>
+#include <time.h>
+
+/**
+ * frescan_servers_init() - initialize server structures
+ *
+ * @net: the network instance
+ */
+
+int frescan_servers_init(frescan_network_t net)
+{
+ int ret, i;
+
+ DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG, "initializing servers\n");
+
+ ret = freelist_init(&the_servers_pool_freelist[net], FRESCAN_MX_IDS);
+ if (ret != 0) return ret;
+
+ for (i=0; i<FRESCAN_MX_NETWORKS; i++) {
+ INIT_LIST_HEAD(&the_active_servers[net].servers_list);
+ }
+
+ ret = frescan_replenishments_init(net);
+ if (ret != 0) {
+ ERROR("could not initialize the replenishments\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * frescan_servers_create() - create a sporadic server
+ *
+ * @net: the network instance
+ * @params: the parameters for the server
+ * @id: the identificator for the server as a return value
+ *
+ */
+
+int frescan_servers_create(frescan_network_t net,
+ const frescan_server_params_t *params,
+ frescan_ss_t *id)
+{
+ int ret, pos;
+ struct sigevent evp;
+
+ FRESCAN_ACQUIRE_LOCK(&the_networks[net].lock);
+ pos = freelist_alloc(&the_servers_pool_freelist[net]);
+ FRESCAN_RELEASE_LOCK(&the_networks[net].lock);
+
+ if (pos == -1) {
+ ERROR("could not allocate servers\n");
+ return -1;
+ }
+
+ *id = (frescan_ss_t)pos;
+
+ the_servers_pool[net][*id].net = net;
+ the_servers_pool[net][*id].id = *id;
+ the_servers_pool[net][*id].params = *params;
+ the_servers_pool[net][*id].current_budget = params->values.budget;
+ the_servers_pool[net][*id].current_priority = params->prio;
+ the_servers_pool[net][*id].pending_packets = 0;
+
+ // the first act_time is set to the server creation time
+ clock_gettime (CLOCK_MONOTONIC, &the_servers_pool[net][*id].act_time);
+
+ INIT_LIST_HEAD(&the_servers_pool[net][*id].replenishments.repl_list);
+ INIT_LIST_HEAD(&the_servers_pool[net][*id].packet_list.fifo_list);
+
+ // the repl timer sends a signal when it expires with the server id
+ evp.sigev_notify = SIGEV_SIGNAL;
+ evp.sigev_signo = FRESCAN_REPL_SIGNAL_NUM;
+ evp.sigev_value.sival_int = (int)*id;
+
+ ret = timer_create (CLOCK_MONOTONIC,
+ &evp, &the_servers_pool[net][*id].repl_timer);
+ if (ret != 0) {
+ ERROR("could not create timer\n");
+ return ret;
+ }
+
+ DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG,
+ "server created, id:%u budget:%u prio:%u\n",
+ *id,
+ the_servers_pool[net][*id].params.values.budget,
+ the_servers_pool[net][*id].params.prio);
+
+ return 0;
+}
+
+/**
+ * frescan_servers_update() - update a sporadic server data
+ *
+ * @net: the network instance
+ * @params: the parameters for the server
+ * @id: the identificator for the server
+ *
+ */
+
+int frescan_servers_update(frescan_network_t net,
+ const frescan_server_params_t *params,
+ frescan_ss_t id)
+{
+ the_servers_pool[net][id].params = *params;
+ return 0;
+}
+
+/**
+ * frescan_servers_destroy() - delete a sporadic server
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ *
+ */
+
+int frescan_servers_destroy(frescan_network_t net, frescan_ss_t id)
+{
+ int ret;
+
+ // TODO: free the replenishment operations and the packets for the
+ // server.
+
+ ret = timer_delete (the_servers_pool[net][id].repl_timer);
+ if (ret != 0) {
+ ERROR("could not delete timer\n");
+ return ret;
+ }
+
+ FRESCAN_ACQUIRE_LOCK(&the_networks[net].lock);
+ list_del(&the_servers_pool[net][id].servers_list);
+
+ ret = freelist_free(&the_servers_pool_freelist[net], id);
+ FRESCAN_RELEASE_LOCK(&the_networks[net].lock);
+ if (ret != 0) {
+ ERROR("could not free server data from pool\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * frescan_servers_get_data() - get a sporadic server data
+ *
+ * @net: the network instance
+ * @params: the parameters of the server
+ * @id: the identificator for the server
+ *
+ */
+
+int frescan_servers_get_data(frescan_network_t net,
+ frescan_server_params_t *params,
+ frescan_ss_t id)
+{
+ *params = the_servers_pool[net][id].params;
+ return 0;
+}
+
+/**
+ * frescan_servers_get_current_budget() - get the current sporadic server budget
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ * @current_budget: the current budget of the server
+ *
+ */
+
+int frescan_servers_get_current_budget(frescan_network_t net,
+ frescan_ss_t id,
+ frescan_budget_t *current_budget)
+{
+ *current_budget = the_servers_pool[net][id].current_budget;
+ return 0;
+}
+
+/**
+ * frescan_servers_get_highest_prio() - get the server with highest priority
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ * @prio: the priority of that server
+ *
+ * For each active server, check the priority.
+ * If "id" is returned with a value of FRESCAN_MX_IDS,
+ * there are no active servers.
+ * NOTE: id=FRESCAN_MX_IDS is the identifier for fixed priority messages
+ * TODO: use a priority queue of active servers
+ *
+ */
+
+int frescan_servers_get_highest_prio(frescan_network_t net,
+ frescan_ss_t *id,
+ frescan_prio_t *prio)
+{
+ frescan_server_data_t *server;
+
+ if (list_empty(&the_active_servers->servers_list)) {
+ DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG, "server list is empty\n");
+ *id = FRESCAN_MX_IDS;
+ return 0;
+ }
+
+ *prio = 0;
+ list_for_each_entry(server, &the_active_servers[net].servers_list,
+ servers_list) {
+ if (server->current_priority >= *prio) {
+ *id = server->id;
+ *prio = server->current_priority;
+ }
+ }
+
+ DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG,
+ "highest prio:%u id:%u\n", *prio, *id);
+
+ return 0;
+}
+
+/**
+ * frescan_servers_frame_sent() - hook to control the server budget and prio
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ *
+ * This function is called when a frame has been effectively sent through the
+ * CAN bus and that frame is associated to a certain server. The function
+ * decreases the capacity of the server and sets the priority to background
+ * in case the budget is exhausted.
+ *
+ * NOTE: the replenishment operation is programmed using the corresponding
+ * function at frescan_servers_replenishments module
+ */
+
+int frescan_servers_frame_sent(frescan_network_t net,
+ frescan_ss_t id,
+ frescan_packet_t *packet)
+{
+ int ret;
+ struct timespec *repl_time;
+ frescan_server_data_t *server;
+
+ server = &the_servers_pool[net][id];
+
+ DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG,
+ "before.. id:%u, current_budget:%u, current_priority:%u\n",
+ id, server->current_budget, server->current_priority);
+
+ if (server->current_budget > 0) {
+ server->current_budget--;
+ if (server->current_budget == 0) {
+ server->current_priority = FRESCAN_BACKGROUND_PRIO;
+ }
+
+ if (smaller_timespec(&packet->timestamp, &server->act_time)) {
+ DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG, "using act_time\n");
+ repl_time = &server->act_time;
+ } else {
+ repl_time = &packet->timestamp;
+ }
+
+ ret = frescan_replenishment_program(net, id, repl_time);
+ if (ret != 0) return -1;
+ }
+
+ DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG,
+ "after.. id:%u, current_budget:%u, current_priority:%u\n",
+ id, server->current_budget, server->current_priority);
+
+ return 0;
+}
--- /dev/null
+/*!
+ * @file frescan_servers.h
+ *
+ * @brief FRESCAN sporadic servers
+ *
+ * @version 0.01
+ *
+ * @date 27-Feb-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This file contains the FRESCAN sporadic servers that allow to isolate
+ * different streams of data by assigning them a budget and replenishment
+ * period.
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _MARTE_FRESCAN_SERVERS_H_
+#define _MARTE_FRESCAN_SERVERS_H_
+
+#include "frescan_types.h"
+
+/**
+ * frescan_servers_init() - initialize server structures
+ *
+ * @net: the network instance
+ */
+
+extern int frescan_servers_init(frescan_network_t net);
+
+/**
+ * frescan_servers_create() - create a sporadic server
+ *
+ * @net: the network instance
+ * @params: the parameters for the server
+ * @id: the identificator for the server as a return value
+ *
+ */
+
+extern int frescan_servers_create(frescan_network_t net,
+ const frescan_server_params_t *params,
+ frescan_ss_t *id);
+
+/**
+ * frescan_servers_set_perceived() - update a sporadic server perceived data
+ *
+ * @net: the network instance
+ * @params: the parameters for the server
+ * @id: the identificator for the server
+ *
+ */
+
+extern int frescan_servers_set_perceived(frescan_network_t net,
+ const frescan_server_params_t *params,
+ frescan_ss_t id);
+
+/**
+ * frescan_servers_commit_perceived() - commit sporadic server perceived data
+ *
+ * @net: the network instance
+ * @params: the parameters for the server
+ * @id: the identificator for the server
+ *
+ */
+
+extern int frescan_servers_commit_perceived(frescan_network_t net,
+ frescan_ss_t id);
+
+/**
+ * frescan_servers_update() - update a sporadic server data
+ *
+ * It is similar to call 'frescan_servers_set_perceived' and then
+ * 'frescan_servers_commit_perceived'
+ *
+ * @net: the network instance
+ * @params: the parameters for the server
+ * @id: the identificator for the server
+ *
+ */
+
+extern int frescan_servers_update(frescan_network_t net,
+ const frescan_server_params_t *params,
+ frescan_ss_t id);
+
+/**
+ * frescan_servers_destroy() - delete a sporadic server
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ *
+ */
+
+extern int frescan_servers_destroy(frescan_network_t net, frescan_ss_t id);
+
+/**
+ * frescan_servers_get_data() - get a sporadic server data
+ *
+ * @net: the network instance
+ * @params: the parameters of the server
+ * @id: the identificator for the server
+ *
+ */
+
+extern int frescan_servers_get_data(frescan_network_t net,
+ frescan_server_params_t *params,
+ frescan_ss_t id);
+
+/**
+ * frescan_servers_get_current_budget() - get the current sporadic server budget
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ * @current_budget: the current budget of the server
+ *
+ */
+
+extern int frescan_servers_get_current_budget(frescan_network_t net,
+ frescan_ss_t id,
+ frescan_budget_t *current_budget);
+
+/**
+ * frescan_servers_get_highest_prio() - get the server with highest priority
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ * @prio: the priority of that server
+ *
+ * If "id" is returned with a value of FRESCAN_MX_IDS,
+ * there are no active servers.
+ * NOTE: id=FRESCAN_MX_IDS is the identifier for fixed priority messages
+ *
+ */
+
+extern int frescan_servers_get_highest_prio(frescan_network_t net,
+ frescan_ss_t *id,
+ frescan_prio_t *prio);
+
+/**
+ * frescan_servers_frame_sent() - hook to control the server budget and prio
+ *
+ * @net: the network instance
+ * @id: the identificator for the server
+ * @packet: the packet sent (with its timestamp)
+ *
+ * This function is called when a frame has been effectively sent through the
+ * CAN bus and that frame is associated to a certain server. The function
+ * decreases the capacity of the server and sets the priority to background
+ * in case the budget is exhausted.
+ *
+ * NOTE: the replenishment operation is programmed using the corresponding
+ * function at frescan_servers_replenishments module
+ */
+
+extern int frescan_servers_frame_sent(frescan_network_t net,
+ frescan_ss_t id,
+ frescan_packet_t *packet);
+
+#endif // _MARTE_FRESCAN_SERVERS_H_
--- /dev/null
+/*!
+ * @file frescan_servers_replenishments.c
+ *
+ * @brief the replenishment data and thread for the servers
+ *
+ * @version 0.01
+ *
+ * @date 12-Mar-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This module contains the thread that waits for server's replenishment
+ * timer signals and perform the necessary replenishments.
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#include <time.h> // clock_gettime
+#include <assert.h> // assert
+
+#include <misc/freelist.h> // freelist_t
+#include <misc/linux_list.h> // list_add_tail
+
+#include "frescan_servers_replenishments.h"
+#include "frescan_config.h" // FRESCAN_MX_REPL_OPS
+#include "frescan_debug.h" // FRESCAN_ERROR
+#include "frescan_data.h" // frescan_repl_op_t
+#include "fosa.h" // fosa_thread_attr_init, smaller_timespec, incr_timespec
+
+#if (FRESCAN_MEASURE_REPL_TH || FRESCAN_MEASURE_REPL_PROGRAM)
+#include <misc/time_measurement_posix.h>
+#include <misc/logger.h>
+static time_measure_id_t measure_id;
+#endif
+
+/**
+ * the_repl_op_pool - pool of replenishment operations
+ *
+ * We have a pool of replenishment operation structures and an associated
+ * freelist where we can get/put replenishment operations in O(1) time
+ *
+ * @the_repl_op_pool: array with the replenishment operations allocated
+ * @the_repl_op_pool_freelist: freelist for the_repl_op_pool
+ * @frescan_repl_op_init: initializes the freelist
+ * @frescan_repl_op_alloc: get a free replenishment operation structure
+ * @frescan_repl_op_free: free a replenishment operation structure
+ *
+ */
+
+static frescan_repl_op_t the_repl_op_pool[FRESCAN_MX_REPL_OPS];
+static freelist_t the_repl_op_pool_freelist;
+
+static int frescan_repl_op_init()
+{
+ return freelist_init(&the_repl_op_pool_freelist, FRESCAN_MX_REPL_OPS);
+}
+
+frescan_repl_op_t *frescan_repl_op_alloc()
+{
+ int pos;
+
+ pos = freelist_alloc(&the_repl_op_pool_freelist);
+ if (pos == -1) {
+ FRESCAN_ERROR("could not allocate repl op\n");
+ return NULL;
+ }
+ the_repl_op_pool[pos].pool_pos = pos; // to know how to free it
+ return &the_repl_op_pool[pos];
+}
+
+int frescan_repl_op_free(frescan_repl_op_t *repl_op)
+{
+ return freelist_free(&the_repl_op_pool_freelist, repl_op->pool_pos);
+}
+
+/**
+ * frescan_repl_thread - the thread that executes the replenishments
+ */
+
+static void *frescan_repl_thread(void *arg)
+{
+ int ret;
+ sigset_t set;
+ siginfo_t siginfo;
+ frescan_ss_t id;
+ frescan_network_t net;
+ frescan_ss_data_t *server;
+ struct itimerspec timerdata;
+
+ net = (frescan_network_t)(uint32_t)arg;
+ timerdata.it_interval.tv_sec = 0;
+ timerdata.it_interval.tv_nsec = 0;
+
+ sigemptyset(&set);
+ sigaddset(&set, FRESCAN_REPL_SIGNAL_NUM);
+
+ while (1) {
+#if FRESCAN_MEASURE_REPL_TH
+ ret = time_measure_posix_begin(measure_id);
+ assert(ret == 0);
+#endif
+ ret = sigwaitinfo(&set, &siginfo);
+ assert(ret != -1);
+
+ if (siginfo.si_signo != FRESCAN_REPL_SIGNAL_NUM) continue;
+
+ DEBUG(FRESCAN_REPLENSH_ENABLE_DEBUG,
+ "net:%u signal:%d code:%d value(server_id):%d\n",
+ net,
+ siginfo.si_signo, // FRESCAN_REPL_SIGNAL_NUM
+ siginfo.si_code, // SI_TIMER
+ siginfo.si_value.sival_int); // the server id
+
+ id = siginfo.si_value.sival_int;
+ server = &frescan_data[net].ss_data[id];
+
+ DEBUG(FRESCAN_REPLENSH_ENABLE_DEBUG,
+ "id:%u current_prio:%u\n", id, server->current_priority);
+
+ server->current_priority = server->committed_params.prio;
+
+ if (!list_empty(&server->packet_list.fifo_list)) {
+ clock_gettime (CLOCK_MONOTONIC, &server->act_time);
+ }
+#if FRESCAN_MEASURE_REPL_TH
+ ret = time_measure_posix_end(measure_id, "thread");
+ assert(ret == 0);
+
+ while (logger_manual_call() > 0);
+#endif
+ }
+
+ return NULL;
+}
+
+/**
+ * frescan_replenishments_init - init the replenishment structures and thread
+ *
+ * @net: the network instance
+ *
+ * Initialize the repl_op pool, set the mask for the timer signals and create
+ * the thread that will await for those signals and replenish the appropiate
+ * sporadic server.
+ */
+
+int frescan_replenishments_init(frescan_network_t net)
+{
+ int ret;
+ fosa_signal_t signal_set[1];
+ fosa_thread_attr_t attr;
+
+ ret = frescan_repl_op_init();
+ if (ret != 0) {
+ FRESCAN_ERROR("could not init repl_op pool\n");
+ return ret;
+ }
+
+ signal_set[0] = FRESCAN_REPL_SIGNAL_NUM;
+
+ ret = fosa_set_accepted_signals(signal_set, 1);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not set the repl signal\n");
+ return ret;
+ }
+
+ // create the replenishment thread
+#if (FRESCAN_MEASURE_REPL_TH || FRESCAN_MEASURE_REPL_PROGRAM)
+ ret = logger_init(LOG_ETHERNET);
+ assert(ret == 0);
+
+ ret = time_measure_posix_create("repl",
+ CLOCK_THREAD_CPUTIME_ID,
+ &measure_id);
+ assert(ret == 0);
+#endif
+
+ ret = fosa_thread_attr_init(&attr);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not init thread attributes\n");
+ return ret;
+ }
+
+ ret = fosa_thread_attr_set_prio(&attr, FRESCAN_REPL_THREAD_PRIO);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not set repl thread prio %d\n",
+ FRESCAN_REPL_THREAD_PRIO);
+ return ret;
+ }
+
+ ret = fosa_thread_create(&frescan_data[net].repl_thread_id,
+ &attr,
+ frescan_repl_thread,
+ (void *)(uint32_t)net);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not create the replenishment thread\n");
+ return ret;
+ }
+
+ ret = fosa_thread_attr_destroy(&attr);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not destroy thread attributes\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * frescan_replenishment_program - set a replenishment operation
+ *
+ * @net: the network instance
+ * @ss: the server
+ */
+
+int frescan_replenishment_program(frescan_network_t net,
+ frescan_ss_t id,
+ const struct timespec *timestamp)
+{
+ int ret;
+ frescan_repl_op_t *repl = NULL;
+ struct itimerspec timerdata;
+ frescan_ss_data_t *server;
+ struct list_head *pos;
+ struct timespec now;
+
+#if FRESCAN_MEASURE_REPL_PROGRAM
+ ret = time_measure_posix_begin(measure_id);
+ assert(ret == 0);
+#endif
+
+ server = &frescan_data[net].ss_data[id];
+
+ // extract the head
+ list_for_each(pos, &server->replenishments.repl_list) {
+ repl = list_entry(pos, frescan_repl_op_t, repl_list);
+ break;
+ }
+ list_del(&repl->repl_list);
+
+ // move to tail with new repl value
+ repl->when = *timestamp;
+ incr_timespec(repl->when, server->committed_params.period);
+ repl->amount = 1;
+
+ list_add_tail(&repl->repl_list,
+ &server->replenishments.repl_list);
+
+ // check the new head
+ list_for_each(pos, &server->replenishments.repl_list) {
+ repl = list_entry(pos, frescan_repl_op_t, repl_list);
+ break;
+ }
+
+ clock_gettime (CLOCK_MONOTONIC, &now);
+
+ if (smaller_timespec(now, repl->when)) {
+ server->current_priority = FRESCAN_BACKGROUND_PRIO;
+
+ timerdata.it_interval.tv_sec = 0;
+ timerdata.it_interval.tv_nsec = 0;
+ timerdata.it_value = repl->when;
+
+ DEBUG(FRESCAN_REPLENSH_ENABLE_DEBUG,
+ "set timer to %d sec, %d nsec\n",
+ repl->when.tv_sec, repl->when.tv_nsec);
+
+ ret = timer_settime(server->repl_timer,
+ TIMER_ABSTIME, &timerdata, NULL);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not set the replenishment timer\n");
+ return ret;
+ }
+ }
+
+#if FRESCAN_MEASURE_REPL_PROGRAM
+ ret = time_measure_posix_end(measure_id, "program");
+ assert(ret == 0);
+
+ while (logger_manual_call() > 0);
+#endif
+
+ return 0;
+}
--- /dev/null
+/*!
+ * @file frescan_servers_replenishments.c
+ *
+ * @brief the replenishment data and thread for the servers
+ *
+ * @version 0.01
+ *
+ * @date 12-Mar-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This module contains the thread that waits for server's replenishment
+ * timer signals and perform the necessary replenishments.
+ *
+ * @license
+ *
+ * -----------------------------------------------------------------------
+ * Copyright (C) 2006 - 2008 FRESCOR consortium partners:
+ *
+ * Universidad de Cantabria, SPAIN
+ * University of York, UK
+ * Scuola Superiore Sant'Anna, ITALY
+ * Kaiserslautern University, GERMANY
+ * Univ. Politécnica Valencia, SPAIN
+ * Czech Technical University in Prague, CZECH REPUBLIC
+ * ENEA SWEDEN
+ * Thales Communication S.A. FRANCE
+ * Visual Tools S.A. SPAIN
+ * Rapita Systems Ltd UK
+ * Evidence ITALY
+ *
+ * See http://www.frescor.org for a link to partners' websites
+ *
+ * FRESCOR project (FP6/2005/IST/5-034026) is funded
+ * in part by the European Union Sixth Framework Programme
+ * The European Union is not liable of any use that may be
+ * made of this code.
+ *
+ * This file is part of FRESCAN
+ *
+ * FRESCAN is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * FRESCAN is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * distributed with FRESCAN; see file COPYING. If not, write to the
+ * Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * As a special exception, including FRESCAN header files in a file,
+ * instantiating FRESCAN generics or templates, or linking other files
+ * with FRESCAN objects to produce an executable application, does not
+ * by itself cause the resulting executable application to be covered
+ * by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be
+ * covered by the GNU Public License.
+ * -----------------------------------------------------------------------
+ *
+ */
+
+#include <time.h> // clock_gettime
+#include <assert.h> // assert
+
+#include <misc/freelist.h> // freelist_t
+#include <misc/linux_list.h> // list_add_tail
+#include <misc/timespec_operations.h>
+
+#include "frescan_servers_replenishments.h"
+#include "frescan_config.h" // FRESCAN_MX_REPL_OPS
+#include "frescan_debug.h" // ERROR
+#include "frescan_data.h" // frescan_repl_op_t
+#include "fosa_threads_and_signals.h" // fosa_thread_attr_init...
+
+#if (FRESCAN_MEASURE_REPL_TH || FRESCAN_MEASURE_REPL_PROGRAM)
+#include <misc/time_measurement_posix.h>
+#include <misc/logger.h>
+static time_measure_id_t measure_id;
+#endif
+
+/**
+ * the_repl_op_pool - pool of replenishment operations
+ *
+ * We have a pool of replenishment operation structures and an associated
+ * freelist where we can get/put replenishment operations in O(1) time
+ *
+ * @the_repl_op_pool: array with the replenishment operations allocated
+ * @the_repl_op_pool_freelist: freelist for the_repl_op_pool
+ * @frescan_repl_op_init: initializes the freelist
+ * @frescan_repl_op_alloc: get a free replenishment operation structure
+ * @frescan_repl_op_free: free a replenishment operation structure
+ *
+ */
+
+static frescan_repl_op_t the_repl_op_pool[FRESCAN_MX_REPL_OPS];
+static freelist_t the_repl_op_pool_freelist;
+
+static int frescan_repl_op_init()
+{
+ return freelist_init(&the_repl_op_pool_freelist, FRESCAN_MX_REPL_OPS);
+}
+
+frescan_repl_op_t *frescan_repl_op_alloc()
+{
+ int pos;
+
+ pos = freelist_alloc(&the_repl_op_pool_freelist);
+ if (pos == -1) {
+ ERROR("could not allocate repl op\n");
+ return NULL;
+ }
+ the_repl_op_pool[pos].pool_pos = pos; // to know how to free it
+ return &the_repl_op_pool[pos];
+}
+
+int frescan_repl_op_free(frescan_repl_op_t *repl_op)
+{
+ return freelist_free(&the_repl_op_pool_freelist, repl_op->pool_pos);
+}
+
+/**
+ * frescan_repl_thread - the thread that executes the replenishments
+ */
+
+static void *frescan_repl_thread(void *arg)
+{
+ int ret;
+ sigset_t set;
+ siginfo_t siginfo;
+ frescan_ss_t id;
+ frescan_network_t net;
+ struct list_head *pos;
+ frescan_repl_op_t *repl = NULL;
+ frescan_server_data_t *server;
+ struct itimerspec timerdata;
+
+ net = (frescan_network_t)(uint32_t)arg;
+ timerdata.it_interval.tv_sec = 0;
+ timerdata.it_interval.tv_nsec = 0;
+
+ sigemptyset(&set);
+ sigaddset(&set, FRESCAN_REPL_SIGNAL_NUM);
+
+ while (1) {
+#if FRESCAN_MEASURE_REPL_TH
+ ret = time_measure_posix_begin(measure_id);
+ assert(ret == 0);
+#endif
+ ret = sigwaitinfo(&set, &siginfo);
+ if (ret == -1) {
+ ERROR("sigwaitinfo failed\n");
+ return NULL;
+ }
+
+ if (siginfo.si_signo != FRESCAN_REPL_SIGNAL_NUM) continue;
+
+ DEBUG(FRESCAN_REPLENSH_ENABLE_DEBUG,
+ "net:%u signal:%d code:%d value(server_id):%d\n",
+ net,
+ siginfo.si_signo, // FRESCAN_REPL_SIGNAL_NUM
+ siginfo.si_code, // SI_TIMER
+ siginfo.si_value.sival_int); // the server id
+
+ id = siginfo.si_value.sival_int;
+ server = &the_servers_pool[net][id];
+
+ DEBUG(FRESCAN_REPLENSH_ENABLE_DEBUG,
+ "id:%u, current_budget:%u, budget:%u, current_prio:%u\n",
+ id,
+ server->current_budget,
+ server->params.values.budget,
+ server->current_priority);
+
+ server->current_budget++;
+
+ if (server->current_priority == FRESCAN_BACKGROUND_PRIO) {
+ server->current_priority = server->params.prio;
+ if (!list_empty(&server->packet_list.fifo_list)) {
+ clock_gettime (CLOCK_MONOTONIC,
+ &server->act_time);
+ }
+ }
+
+ DEBUG(FRESCAN_REPLENSH_ENABLE_DEBUG,
+ "now... current_budget:%u, current_prio:%u\n",
+ server->current_budget,
+ server->current_priority);
+
+ // delete the replenishment of this call
+ list_for_each(pos, &server->replenishments.repl_list) {
+ repl = list_entry(pos, frescan_repl_op_t, repl_list);
+ break;
+ }
+
+ list_del(&repl->repl_list);
+
+ ret = frescan_repl_op_free(repl);
+ if (ret != 0) {
+ ERROR("could not free replenishment op\n");
+ return NULL;
+ }
+
+ // check if there are pending replenishments
+ if (list_empty(&server->replenishments.repl_list)) continue;
+
+ list_for_each(pos, &server->replenishments.repl_list) {
+ repl = list_entry(pos, frescan_repl_op_t, repl_list);
+ break;
+ }
+
+ timerdata.it_value = repl->when;
+
+ DEBUG(FRESCAN_REPLENSH_ENABLE_DEBUG,
+ "set timer to (%d, %d)\n",
+ repl->when.tv_sec, repl->when.tv_nsec);
+
+ ret = timer_settime(server->repl_timer,
+ TIMER_ABSTIME, &timerdata, NULL);
+ if (ret != 0) {
+ ERROR("could not set replenishment timer\n");
+ return NULL;
+ }
+#if FRESCAN_MEASURE_REPL_TH
+ ret = time_measure_posix_end(measure_id, "thread");
+ assert(ret == 0);
+
+ while (logger_manual_call() > 0);
+#endif
+ }
+
+ return NULL;
+}
+
+/**
+ * frescan_replenishments_init - init the replenishment structures and thread
+ *
+ * @net: the network instance
+ *
+ * Initialize the repl_op pool, set the mask for the timer signals and create
+ * the thread that will await for those signals and replenish the appropiate
+ * sporadic server.
+ */
+
+int frescan_replenishments_init(frescan_network_t net)
+{
+ int ret;
+ fosa_signal_t signal_set[1];
+ fosa_thread_attr_t attr;
+
+ ret = frescan_repl_op_init();
+ if (ret != 0) {
+ ERROR("could not init repl_op pool\n");
+ return ret;
+ }
+
+ signal_set[0] = FRESCAN_REPL_SIGNAL_NUM;
+
+ ret = fosa_set_accepted_signals(signal_set, 1);
+ if (ret != 0) {
+ ERROR("could not set the repl signal\n");
+ return ret;
+ }
+
+ // create the replenishment thread
+#if (FRESCAN_MEASURE_REPL_TH || FRESCAN_MEASURE_REPL_PROGRAM)
+ ret = logger_init(LOG_ETHERNET);
+ assert(ret == 0);
+
+ ret = time_measure_posix_create("repl",
+ CLOCK_THREAD_CPUTIME_ID,
+ &measure_id);
+ assert(ret == 0);
+#endif
+
+ ret = fosa_thread_attr_init(&attr);
+ if (ret != 0) {
+ ERROR("could not init thread attributes\n");
+ return ret;
+ }
+
+ ret = fosa_thread_attr_set_prio(&attr, FRESCAN_REPL_THREAD_PRIO);
+ if (ret != 0) {
+ ERROR("could not set repl thread prio %d\n",
+ FRESCAN_REPL_THREAD_PRIO);
+ return ret;
+ }
+
+ ret = fosa_thread_create(&the_networks[net].repl_thread_id,
+ &attr,
+ frescan_repl_thread,
+ (void *)(uint32_t)net);
+ if (ret != 0) {
+ ERROR("could not create the replenishment thread\n");
+ return ret;
+ }
+
+ ret = fosa_thread_attr_destroy(&attr);
+ if (ret != 0) {
+ ERROR("could not destroy thread attributes\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * frescan_replenishment_program - set a replenishment operation
+ *
+ * @net: the network instance
+ * @ss: the server
+ */
+
+int frescan_replenishment_program(frescan_network_t net,
+ frescan_ss_t ss,
+ const struct timespec *timestamp)
+{
+ int ret;
+ frescan_repl_op_t *repl;
+ bool empty;
+ struct itimerspec timerdata;
+ frescan_server_data_t *server;
+
+#if FRESCAN_MEASURE_REPL_PROGRAM
+ ret = time_measure_posix_begin(measure_id);
+ assert(ret == 0);
+#endif
+
+ server = &the_servers_pool[net][ss];
+
+ repl = frescan_repl_op_alloc();
+ if (repl == NULL) {
+ ERROR("could not allocate a repl operation\n");
+ return -1;
+ }
+
+ repl->when = *timestamp;
+ incr_timespec (&repl->when, &server->params.values.period);
+ repl->amount = 1;
+
+ empty = list_empty(&server->replenishments.repl_list);
+ DEBUG(FRESCAN_REPLENSH_ENABLE_DEBUG, "ss:%u, empty:%u\n", ss, empty);
+
+ list_add_tail(&repl->repl_list,
+ &server->replenishments.repl_list);
+
+ if (empty) {
+ timerdata.it_interval.tv_sec = 0;
+ timerdata.it_interval.tv_nsec = 0;
+ timerdata.it_value = repl->when;
+
+ DEBUG(FRESCAN_REPLENSH_ENABLE_DEBUG,
+ "set timer to %d sec, %d nsec\n",
+ repl->when.tv_sec, repl->when.tv_nsec);
+
+ ret = timer_settime(server->repl_timer,
+ TIMER_ABSTIME, &timerdata, NULL);
+ if (ret != 0) {
+ ERROR("could not set the replenishment timer\n");
+ return ret;
+ }
+ }
+
+#if FRESCAN_MEASURE_REPL_PROGRAM
+ ret = time_measure_posix_end(measure_id, "program");
+ assert(ret == 0);
+
+ while (logger_manual_call() > 0);
+#endif
+
+ return 0;
+}
--- /dev/null
+/*!
+ * @file frescan_servers_replenishments.h
+ *
+ * @brief the replenishment data and thread for the servers
+ *
+ * @version 0.01
+ *
+ * @date 12-Mar-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This module contains the thread that waits for server's replenishment
+ * timer signals and perform the necessary replenishments.
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _MARTE_FRESCAN_SERVERS_REPLENISHMENTS_H_
+#define _MARTE_FRESCAN_SERVERS_REPLENISHMENTS_H_
+
+#include "frescan_types.h"
+
+/**
+ * frescan_replenishments_init - init the replenishment structures and thread
+ *
+ * @net: the network instance
+ *
+ * Initialize the repl_op pool, set the mask for the timer signals and create
+ * the thread that will await for those signals and replenish the appropiate
+ * sporadic server.
+ *
+ * NOTE: it must be called from the MAIN because it sets the signal mask
+ */
+
+extern int frescan_replenishments_init(frescan_network_t net);
+
+extern frescan_repl_op_t *frescan_repl_op_alloc();
+
+extern int frescan_repl_op_free(frescan_repl_op_t *repl_op);
+
+/**
+ * frescan_replenishment_program - set a replenishment operation
+ *
+ * @net: the network instance
+ * @ss: the server
+ * @timestamp: timestamp
+ */
+
+extern int frescan_replenishment_program(frescan_network_t net,
+ frescan_ss_t id,
+ const struct timespec *timestamp);
+
+#endif // _MARTE_FRESCAN_SERVERS_REPLENISHMENTS_H_
--- /dev/null
+/*!
+ * @file frescan_types.h
+ *
+ * @brief types used in FRESCAN
+ *
+ * @version 0.01
+ *
+ * @date 16-Nov-2008
+ *
+ * @author
+ * Daniel Sangorrin
+ *
+ * @comments
+ *
+ * This file contains the types used in FRESCAN protocol
+ *
+ * @license
+ *
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef _FRESCAN_TYPES_H_
+#define _FRESCAN_TYPES_H_
+
+#include <stdint.h> // uint8_t, uint32_t..
+#include <stdbool.h> // bool
+#include <unistd.h> // size_t
+#include <time.h> // struct timespec, timer_t
+#include <semaphore.h> // sem_t
+
+#include "frsh.h" // for frsh_contract_t
+#include "fsa.h" // for frsh_sa_scenario_t
+#include "fosa_opaque_types.h" // for FOSA_ETIMEDOUT
+#include "fosa_threads_and_signals.h" // fosa_thread_id_t
+#include "frescan_config.h"
+
+#include <misc/linux_list.h> // struct list_head
+#include <drivers/can.h> // can_frame_t
+#include <misc/freelist.h> // freelist_t
+
+typedef uint8_t frescan_network_t;
+typedef uint8_t frescan_node_t;
+typedef uint8_t frescan_channel_t;
+typedef uint8_t frescan_prio_t;
+typedef uint8_t frescan_ss_t;
+typedef uint32_t frescan_budget_t;
+
+typedef struct {
+ int size;
+ frescan_ss_t ss[FRESCAN_BWRES_MAX_GROUP_OPS];
+} frescan_ss_group_t;
+
+/**
+ * frescan_flags_t - frescan flags
+ *
+ * @FRESCAN_SS: send the message using sporadic servers
+ * @FRESCAN_FP: send the message using fixed priorities
+ * @FRESCAN_POLL: no buffer copy, only pointer and use the ID to poll status
+ * @FRESCAN_SYNC: no buffer copy, only pointer and block until it is sent
+ * @FRESCAN_ASYNC: use buffer copy and return immediately
+ */
+
+typedef enum {
+ FRESCAN_SS = 1<<4, // sporadic server
+ FRESCAN_FP = 1<<3, // fixed priorities
+ FRESCAN_POLL = 1<<2, // polling
+ FRESCAN_SYNC = 1<<1, // synchronous
+ FRESCAN_ASYNC = 1 // asynchronous
+} frescan_flags_t;
+
+/**
+ * frescan_send_params_t - send parameters
+ *
+ * @net: the network to use
+ * @to: the node where the message shoud be sent to
+ * @channel: the channel in 'to' where the message shoud be sent to
+ * @flags: the flags (see frescan_flags_t)
+ * @prio: the priority for the message if (flags & FRESCAN_FP)
+ * @ss: the sporadic server for the message if (flags & FRESCAN_SS)
+ */
+
+typedef struct {
+ frescan_network_t net;
+ frescan_node_t to;
+ frescan_channel_t channel;
+ frescan_flags_t flags;
+ union {
+ frescan_prio_t prio;
+ frescan_ss_t ss;
+ };
+} frescan_send_params_t;
+
+/**
+ * frescan_recv_params_t - receive parameters
+ *
+ * @net: the network to use
+ * @channel: the channel from which we want to extract a message
+ * @flags: FRESCAN_SYNC/ASYNC
+ */
+
+typedef struct {
+ frescan_network_t net;
+ frescan_channel_t channel;
+ frescan_flags_t flags;
+} frescan_recv_params_t;
+
+/**
+ * frescan_init_params_t - initialization parameters
+ *
+ * @net: network to initialize (minor number ie: /dev/can0 -> 0)
+ * @node: set the local node identificator
+ * @tx_fp_max_prio: maximum number of priorities for the fixed priority
+ * transmission queues. (prio = 0 .. max_prio - 1)
+ * @rx_num_of_channels: number of rx channels (0 .. rx_num_of_channels - 1)
+ * @rx_channel_max_prio: array (range rx_num_of_channels) saying the number
+ * of priorities for each channel. If this parameter is
+ * NULL tx_fp_max_prio will be used for all queues.
+ */
+
+typedef struct {
+ frescan_network_t net;
+ frescan_node_t node;
+ uint32_t tx_fp_max_prio;
+ uint32_t rx_num_of_channels;
+ uint32_t *rx_channel_max_prio;
+} frescan_init_params_t;
+
+/**
+ * frescan_packet_t - a frescan packet
+ *
+ * This structure is very important and it is used to store a FRESCAN packet.
+ * As we support fragmentation, a FRESCAN packet can be composed of several
+ * CAN frames. This 'frescan_packet_t' structure is used in two main cases:
+ *
+ * 1.- When we are sending data. In this case, the buffer pointers store the
+ * real data we want to sent and we use a 'buffer_read_pointer' to know
+ * how many bytes of the buffer we already sent. In 'frame', we store the
+ * last sent frame (with the corresponding CAN id fields). We will have
+ * to update the fragmentation fields as long as we send more packets.
+ * The 'fifo_list' is used to chained frescan packets of the same priority
+ * or that belong to the same sporadic server. Finally, 'flags', specify
+ * if we are sending ASYNC or SYNC. If we are sending SYNC the buffer
+ * pointers are pointing to the buffer sent by the user (zero copying),
+ * while if we use ASYNC, a copy of the data is done to the buffer.
+ *
+ * 2.- When we are receiving data, we only use 'frame' and 'fifo_list' fields.
+ * The IRQ handler of the chip allocates a CAN frame and calls to our hook.
+ * We store the pointer to that frame in 'frame' and we make a chain with
+ * frames of the same message (using the fragmentation fields). When we
+ * have all of them, we move the packet list to the corresponding
+ * receiving channel to wait for the user to perform a receive operation
+ * when we will copy the data and free both the packets and the frames.
+ *
+ * @flags: to know if the packet is to be sent SYNC or ASYNC, FP or SERVER...
+ * @frame: pointer to the last sent frame or the received frame
+ * @fifo_list: list to put several packets together
+ * @msg_list: list to put packets of the same message together
+ * @buffer_head: pointer to first byte of the buffer that is going to be sent
+ * @buffer_read_pointer: pointer to the part of the buffer being read
+ * @buffer_pending_bytes: bytes waiting to be sent
+ * @timestamp: time when the packet was enqueued (activation time)
+ * @pool_pos: position in the packets pool to know how to free it
+ *
+ * NOTE: the buffers could also be used on the receiving part to support
+ * sequential reads, instead of reading the whole message at once.
+ *
+ */
+
+typedef struct {
+ frescan_flags_t flags;
+ struct can_frame_t *frame;
+ struct list_head fifo_list;
+ struct list_head msg_list;
+ uint8_t *buffer_head; // only for sending packets
+ uint8_t *buffer_read_pointer; // only for sending packets
+ uint32_t buffer_pending_bytes; // only for sending packets
+ struct timespec timestamp;
+ int pool_pos;
+} frescan_packet_t;
+
+/**
+ * frescan_repl_op_t - a replenishment operation
+ *
+ * @when: when the replenishment operation is programmed at
+ * @amount: number of frames to add to the available budget
+ * @repl_list: to chain the replenishments for a certain sporadic server
+ * @pool_pos: to know how to free it from the replenishment pool
+ */
+
+typedef struct {
+ struct timespec when;
+ frescan_budget_t amount;
+ struct list_head repl_list;
+ int pool_pos;
+} frescan_repl_op_t;
+
+/**
+ * frescan_server_params_t - server parameters
+ *
+ * @budget: the budget in CAN 8-byte frames
+ * @period: the replenishment period for the server
+ * @prio: the priority of the server
+ */
+
+typedef struct {
+ frescan_budget_t budget;
+ struct timespec period;
+ frescan_prio_t prio;
+} frescan_server_params_t;
+
+/**
+ * frescan_ss_data_t - sporadic server data
+ *
+ * @committed_params: the committed params (C,T,Prio) for the server
+ * @perceived_params: the params perceived by the user (we can lie to him)
+ * @current_priority: the current priority (0=background)
+ * @repl_list: the list of pending replenishment operations
+ * @repl_timer: the timer for the replenishments associated to this server
+ * NOTE: we could use a single timer for all but for now this is simpler
+ * @act_time: the last activation time for the server
+ * @packet_list: the packets enqueued on this server
+ * @servers_list: the list of servers
+ */
+
+typedef struct {
+ frescan_server_params_t committed_params;
+ frescan_server_params_t perceived_params;
+ frescan_network_t net;
+ frescan_ss_t id;
+ frescan_prio_t current_priority;
+ frescan_budget_t pending_packets;
+ frescan_repl_op_t replenishments; // TODO: use struct list_head
+ timer_t repl_timer;
+ struct timespec act_time;
+ frescan_packet_t packet_list; // TODO: use struct list_head
+ struct list_head servers_list;
+} frescan_ss_data_t;
+
+/**
+ * frescan_prio_queue_t - priority queue
+ *
+ * FRESCAN priority queues are implemented as an array of one 'fifo_queue' for
+ * each priority. Where the 'fifo_queues' are implemented using the
+ * 'struct list_head fifo_list;' field of each packet structure (Linux lists).
+ *
+ * So far mutual exclusion is achieved by disabling interrupts and
+ * synchronization is done using a semaphore. This is because the queues
+ * are accesed concurrently from user threads and the IRQ handler.
+ *
+ * @net: the network this priority queue belongs to (mainly for locking)
+ * @fifo_queues: an array of packets for each priority where each packet
+ * is just the head of a fifo_list. The array is allocated
+ * from the heap, using malloc, at initialization with range
+ * 0..max_prio-1
+ * @max_prio: defines the number of priorities as (0 .. max_prio - 1)
+ * @sem: semaphore used for synchronization
+ */
+
+typedef struct {
+ frescan_network_t net;
+ frescan_packet_t *fifo_queues;
+ uint32_t max_prio;
+ sem_t sem;
+} frescan_prio_queue_t;
+
+/**
+ * frescan_queues_t - the set of FRESCAN queues for each instance of a protocol
+ *
+ * @tx_fp_queue: priority queue for the fixed priority packets
+ * @rx_channel_queues: a priority queue for each receiving channel
+ *
+ * TODO: add here the sporadic server queues...
+ */
+
+typedef struct {
+ frescan_prio_queue_t *tx_fp_queue;
+ frescan_prio_queue_t **rx_channel_queues;
+ uint32_t num_rx_channels;
+} frescan_queues_t;
+
+
+// BWRES TYPES
+
+typedef unsigned int frescan_bwres_robj_id_t; /* 0 .. MX_REPLY_OBJECTS-1 */
+#define FRESCAN_ETIMEDOUT FOSA_ETIMEDOUT
+
+/**
+ * frescan_bwres_vres_t - a frescan virtual resource
+ *
+ * @contract: the contract of the virtual resource
+ * @node: the node where the vres belongs to
+ * @ss: the sporadic server identifier
+ * @list: the list of vres. Note that this is the list of all the vres
+ * in the network instace. As this is a master-slave protocol the master
+ * knows everything about the contracts of the rest of nodes.
+ */
+
+typedef enum {
+ FRESCAN_BWRES_MC_PERIOD_DEC = 1<<5,
+ FRESCAN_BWRES_MC_PERIOD_INC = 1<<4,
+ FRESCAN_BWRES_MC_BUDGET_DEC = 1<<3,
+ FRESCAN_BWRES_MC_BUDGET_INC = 1<<2,
+ FRESCAN_BWRES_MC_PRIO_DEC = 1<<1,
+ FRESCAN_BWRES_MC_PRIO_INC = 1
+} frescan_bwres_mode_change_type_t;
+
+typedef struct {
+ frsh_contract_t contract;
+ frescan_node_t node;
+ frescan_ss_t ss;
+ frsh_sa_vres_id_t fsa_vres_global_id;
+ struct list_head list;
+ // mode change variables
+ frsh_sa_time_t old_c;
+ frsh_sa_time_t old_t;
+ frsh_sa_prio_t old_p;
+ frescan_bwres_mode_change_type_t mode_change_type;
+ struct list_head mode_change_list;
+} frescan_bwres_vres_t;
+
+/**
+ * frescan_bwres_request_data_t
+ *
+ * This are the data contained in a request to perform the negotiation of
+ * contracts.
+ *
+ * @type: indicates the type of the request
+ * @contract: a contract to (re)negotiate
+ * @contract_ref: a pointer to the contract to (re)negotiate (optimization)
+ * @ss: the local sporadic server ID
+ * @request_node: the node that performed the request
+ * @req: the request id of the SLAVE to identify the request in the reply
+ * @return_value: the value returned in a Reply (accepted or not)
+ * @final_values: the values for the ss after the negotiation
+ * @net: the network instance where this request belongs to
+ * @robj: a reply object to wait until a negotiation is completed
+ *
+ */
+
+typedef uint16_t frescan_bwres_request_id_t; /* 0 .. MX_REQUESTS */
+
+typedef enum {
+ FRESCAN_BWRES_REQ_GN = 0, // group negotiation
+ FRESCAN_BWRES_REP_GN = 1, // negotiation reply
+ FRESCAN_BWRES_REQ_MC = 2, // mode change
+ FRESCAN_BWRES_REQ_RES = 3, // reservation negotiation
+ FRESCAN_BWRES_REQ_RES_GET = 4, // reservation get values
+ FRESCAN_BWRES_REP_RES_GET = 5, // reservation get values reply
+ FRESCAN_BWRES_REQ_RES_SET = 6, // reservation set values
+ FRESCAN_BWRES_REQ_RES_COMMIT = 7, // reservation commit
+ FRESCAN_BWRES_REQ_RES_CANCEL = 8, // reservation cancel
+} frescan_bwres_request_type_t;
+
+typedef enum {
+ FRESCAN_BWRES_REQ_ACCEPTED = 0, // negotiation accepted
+ FRESCAN_BWRES_REQ_NOT_ACCEPTED = 1, // negotiation not accepted
+ FRESCAN_BWRES_REQ_ERROR = 2, // there was an error
+} frescan_bwres_request_retval_t;
+
+typedef struct {
+ frescan_network_t net;
+ frescan_bwres_request_type_t type;
+ frescan_bwres_request_id_t req;
+ frescan_node_t request_node;
+ frescan_bwres_request_retval_t return_value;
+ frescan_bwres_robj_id_t robj;
+ // contracts and ss groups
+ frsh_contracts_group_t *contracts_to_neg;
+ frsh_contracts_group_t *contracts_to_reneg;
+ frescan_ss_group_t *ss_to_reneg;
+ frescan_ss_group_t *ss_to_cancel;
+ frescan_ss_group_t *ss_new;
+ // contracts and ss groups data (to store the info at master node)
+ frsh_contracts_group_t contracts_to_neg_data;
+ frsh_contracts_group_t contracts_to_reneg_data;
+ frescan_ss_group_t ss_to_reneg_data;
+ frescan_ss_group_t ss_to_cancel_data;
+ frescan_ss_group_t ss_new_data;
+ // for FRESCAN_BWRES_REQ_MC
+ frescan_bwres_mode_change_type_t mode_change_type;
+} frescan_bwres_request_data_t;
+
+/**
+ * frescan_bwres_sa_scenario_t - the scheduling analysis scenario
+ */
+
+typedef struct {
+ frescan_prio_t max_prio;
+ frescan_prio_t min_prio;
+} frescan_bwres_sa_init_params_t;
+
+typedef struct {
+ frescan_bwres_sa_init_params_t init_params;
+ frescan_bwres_vres_t vres_pool[FRESCAN_MX_NODES][FRESCAN_MX_IDS];
+ frescan_bwres_vres_t vres_head; // TODO: use struct list_head
+ freelist_t fsa_vres_global_id_freelist;
+ freelist_t ss_id_freelist[FRESCAN_MX_NODES];
+ frsh_sa_scenario_t fsa_scenario;
+ frsh_contracts_group_t backup_contracts_to_reneg;
+ frsh_contracts_group_t backup_contracts_to_cancel;
+} frescan_bwres_sa_scenario_t;
+
+/**
+ * frescan_network_data_t - data for each network instance
+ *
+ * @local_node: the local node id for that network. The implementation does not
+ * support several interfaces for the same network.
+ * @fd: file descriptor associated to /dev/canXX
+ * @repl_thread_id: replenishment thread id
+ * @manager_thread_id: manager thread id
+ * @acceptor_thread_id: acceptor thread id
+ * @neg_messages_ss_id: sporadic server for negotiation messages
+ * @queues: the queues of this network instance
+ * @last_packet: pointer to the last packet from which a frame was inserted
+ * in the chip and its transmission is not complete.
+ * @last_packet_prio: prio of the packet in the buffer
+ * @id_queues: queues to store received packets while the whole message is
+ * not complete (fragmentation). (id = 0 .. FRESCAN_MX_IDS - 1)
+ * @id_fp_queues: the same as id_queues but for fp messages, which have
+ * id=FRESCAN_MX_IDS and are distinguised through their
+ * priorities.
+ * @scenario: the scheduling analysis scenario for the network
+ * @mode_change_list: list of sa_vres that have changes to commit
+ * @mode_change_type: what type of changes are to commit
+ *
+ * the implementation can handle several FRESCAN networks at the same time
+ * in the same node, so we need a place to store its internal data. The data
+ * is allocated as an array where the index is the MINOR number (which also
+ * identifies the /dev/canx device for that network)
+ */
+
+typedef struct {
+ FRESCAN_MLOCK_T lock;
+ frescan_node_t local_node;
+ int fd;
+ fosa_thread_id_t repl_thread_id;
+ frescan_packet_t *last_packet;
+ frescan_prio_t last_packet_prio;
+ frescan_queues_t queues;
+ frescan_packet_t *id_queues[FRESCAN_MX_NODES][FRESCAN_MX_IDS]; // TODO: alloc at init
+ frescan_packet_t *id_fp_queues[FRESCAN_MX_NODES][FRESCAN_MX_PRIOS]; // TODO: alloc at init
+ frescan_ss_data_t ss_data[FRESCAN_MX_IDS];
+ freelist_t ss_id_freelist;
+ frescan_ss_data_t ss_active_head; // TODO: use struct list_head
+ // BWRES data
+ fosa_thread_id_t manager_thread_id;
+ fosa_thread_id_t acceptor_thread_id;
+ frescan_ss_t neg_messages_ss_id;
+ frescan_bwres_sa_scenario_t scenario;
+ struct list_head mode_change_list[FRESCAN_MX_NODES];
+ frescan_bwres_mode_change_type_t mode_change_type[FRESCAN_MX_NODES];
+} frescan_network_data_t;
+
+#endif // _FRESCAN_TYPES_H_
--- /dev/null
+.PHONY: all objs librtepfna.a
+
+all: librtepfna.a
+include ../config.mk
+include ../rules.mk
+
+SRCS := $(wildcard *.c)
+OBJS := $(patsubst %.c,%.o,$(wildcard *.c))
+HDRS := $(wildcard $(FNA_PATH)/include/*.h)
+CFLAGS += -I$(PLATFORM_PATH)/arch/drivers/rt-ep/
+
+objs: $(OBJS)
+
+%.o: %.c $(SRCS) $(HDRS)
+ $(CC) $(CFLAGS) -c $<
+
+librtepfna.a: objs
+ @exec echo -e "\n>> Building RTEP FNA:";
+ ld -r -o librtepfna.o *.o
+ @mv librtepfna.o $(FNA_PATH)/lib
+ @exec echo ">> end Building RTEP FNA [OK]"
+
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+// ******** **** ** **
+// **///// /**/** /** ****
+// ** /**//** /** **//**
+// ******* /** //** /** ** //**
+// **//// /** //**/** **********
+// ** /** //****/**//////**
+// ** /** //***/** /**
+// / // /// // //
+//
+// FNA(Frescor Network Adaptation layer), pronounced "efe ene a"
+//==============================================================
+
+#ifndef _RTEP_FNA_H_
+#define _RTEP_FNA_H_
+
+#include "fna.h" // for fna_operations_t
+
+extern fna_operations_t rtep_fna_operations;
+
+#endif // _RTEP_FNA_H_
+
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+// ******** **** ** **
+// **///// /**/** /** ****
+// ** /**//** /** **//**
+// ******* /** //** /** ** //**
+// **//// /** //**/** **********
+// ** /** //****/**//////**
+// ** /** //***/** /**
+// / // /// // //
+//
+// FNA(Frescor Network Adaptation layer), pronounced "efe ene a"
+//==============================================================
+#include <malloc.h> // for malloc and free
+
+#include "rtep.h" // for rtep_adainit, rtep_valid_multicast_id, ..
+#include "rtep_bandwith_reservation.h" // for rtep_bwres_*
+#include "rtep_fna.h" // function prototypes
+#include "fadt_freelist.h"
+
+#if 0
+#include <stdio.h>
+#define DEBUG(x,args...) printf("%s: " x, __func__ , ##args)
+#else
+#define DEBUG(x,args...)
+#endif
+
+// TODO: add a mutex for concurrent access if necessary
+static rtep_bwres_vres_t rtep_vres_list[MAX_N_RTEP_BWRES_VRES];
+static fadt_freelist_t rtep_vres_freelist;
+
+//////////////////////////////////////////////////////////////////////
+// INITIALIZATION
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * rtep_fna_init()
+ *
+ * This function will be hooked to the frsh_init function and it is
+ * intented to initialize the protocol and its structures.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_ALREADY_INITIALIZED:
+ * if the function has already been called before (with success) \n
+ *
+ **/
+int rtep_fna_init(const frsh_resource_id_t resource_id)
+{
+ int err = 0;
+
+ DEBUG("calling rtep_adainit\n");
+
+ // init Ada bindings
+ rtep_adainit();
+
+ DEBUG("calling freelist_init\n");
+
+ // initialize the freelist to handle the rtep_vres
+ err = fadt_freelist_init(&rtep_vres_freelist, NULL, MAX_N_RTEP_BWRES_VRES);
+ if (err != 0) return -1;
+
+ DEBUG("calling rtep_bwres_init\n");
+
+ return rtep_bwres_init();
+}
+
+///////////////////////////////////////////////////////////////////
+// VIRTUAL RESOURCES
+///////////////////////////////////////////////////////////////////
+
+/**
+ * rtep_fna_contract_negotiate()
+ *
+ * The operation negotiates a contract and if accepted it will return
+ * a fna_vres_id_t. It will also check that the given contract_id is unique
+ * within the network.
+ *
+ * If the on-line admission test is enabled, it determines whether the
+ * contract can be admitted or not based on the current contracts
+ * established in the network. Then it creates the vres and
+ * recalculates all necessary parameters for the contracts already
+ * present in the system.
+ *
+ * This is a potentially blocking operation, it returns when the
+ * system has either rejected the contract, or admitted it and made it
+ * effective.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] contract The contract parameters to negotiate
+ * @param[out] vres The internal virtual resource id
+ *
+ * @return
+ * 0 if there are no errors (in this case it also means contract accepted) \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_TOO_MANY_VRES: if there is no space for more vres \n
+ * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
+ * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int rtep_fna_contract_negotiate
+ (const frsh_resource_id_t resource_id,
+ const frsh_contract_t *contract,
+ fna_vres_id_t *vres)
+{
+ rtep_bwres_contract_t rtep_contract;
+ int accepted;
+ int pos;
+
+ // convert FRSH contract to RTEP BWRES contract
+ rtep_contract.period_max = contract->period_max;
+ rtep_contract.deadline = contract->deadline;
+ rtep_contract.prio = contract->preemption_level;
+ // in RTEP BWRES, budget is given in number of packets. We do a little trick
+ // in the function bytes_to_network_budget to use a the field tv_sec from
+ // the timespec in frsh_contract to store the budget in bytes directly
+ rtep_contract.budget_min = contract->budget_min.tv_sec;
+
+ // allocate a free internal vres.
+ pos = fadt_freelist_alloc(&rtep_vres_freelist);
+
+ if (pos < 0) {
+ DEBUG("not enough resources\n");
+ return -1;
+ }
+
+ DEBUG("calling rtep_bwres_contract_negotiate\n");
+ // negotiate the contract
+ accepted = rtep_bwres_contract_negotiate
+ (&rtep_contract, &rtep_vres_list[pos]);
+
+ // if accepted assign the vres, if not deallocate the rtep_vres
+ if (accepted == 0) {
+ DEBUG("contract accepted\n");
+ *vres = (fna_vres_id_t)pos;
+ } else {
+ DEBUG("contract not accepted\n");
+ fadt_freelist_free(&rtep_vres_freelist, pos);
+ }
+
+ return accepted;
+}
+
+/**
+ * rtep_fna_contract_renegotiate_sync()
+ *
+ * The operation renegotiates a contract for an existing vres. If
+ * the on-line admission test is enabled it determines whether the
+ * contract can be admitted or not based on the current contracts
+ * established in the system. If it cannot be admitted, the old
+ * contract remains in effect and an error is returned. If it can be
+ * admitted, it recalculates all necessary parameters for the
+ * contracts already present in the system and returns zero. This is a
+ * potentially blocking operation; it returns when the system has
+ * either rejected the new contract, or admitted it and made it
+ * effective.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id to renegotiate
+ * @param[in] new_contract The new contract
+ *
+ * @return
+ * 0 if there are no errors (in this case it also means contract accepted) \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
+ * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int rtep_fna_contract_renegotiate_sync
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ const frsh_contract_t *new_contract)
+{
+ rtep_bwres_contract_t rtep_contract;
+ int accepted;
+ int pos = (int) vres;
+
+ // convert FRSH contract to RTEP BWRES contract
+ rtep_contract.period_max = new_contract->period_max;
+ rtep_contract.deadline = new_contract->deadline;
+ rtep_contract.prio = new_contract->preemption_level;
+ // in RTEP BWRES, budget is given in number of packets. We do a little trick
+ // in the function bytes_to_network_budget to use a the field tv_sec from
+ // the timespec in frsh_contract to store the budget in bytes directly
+ rtep_contract.budget_min = new_contract->budget_min.tv_sec;
+
+ // renegotiate the contract
+ accepted = rtep_bwres_contract_renegotiate_sync
+ (&rtep_vres_list[pos], &rtep_contract);
+
+ return accepted;
+}
+
+/**
+ * rtep_fna_contract_renegotiate_async()
+ *
+ * The operation enqueues a renegotiate operation for an existing
+ * vres, and returns immediately. The renegotiate operation is
+ * performed asynchronously, as soon as it is practical; meanwhile the
+ * system operation will continue normally. When the renegotiation is
+ * made, if the on-line admission test is enabled it determines
+ * whether the contract can be admitted or not based on the current
+ * contracts established in the system. If it cannot be admitted, the
+ * old contract remains in effect. If it can be admitted, it
+ * recalculates all necessary parameters for the contracts already
+ * present in the system.
+ *
+ * When the operation is completed, notification is made to the
+ * caller, if requested, via a signal. The status of the operation (in
+ * progress, admitted, rejected) can be checked with the
+ * frsh_vres_get_renegotiation_status() operation. The argument
+ * sig_notify can be FRSH_NULL_SIGNAL (no notification), or any FRSH
+ * signal value and in this case signal_info is to be sent with the signal.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id to renegotiate
+ * @param[in] new_contract The new contract
+ * @param[in] signal_to_notify Signal number to use to notify vres of
+ * the negotiation result. If FRSH_NULL_SIGNAL, no signal will be raised.
+ * @param[in] signal_info: Associated info that will come with the signal.
+ * This parameter will be ignored if signal_to_notify == FRSH_NULL_SIGNAL.
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL, or sig_notify is neither
+ * NULL nor a valid POSIX signal \n
+ *
+ **/
+int rtep_fna_contract_renegotiate_async
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ const frsh_contract_t *new_contract,
+ frsh_signal_t signal_to_notify,
+ frsh_signal_info_t signal_info)
+{
+ return 0;
+}
+
+/**
+ * rtep_fna_vres_get_renegotiation_status()
+ *
+ * The operation reports on the status of the last renegotiation
+ * operation enqueued for the specified vres. It is callable even
+ * after notification of the completion of such operation, if
+ * requested.
+ *
+ * If the vres is not and has not been involved in any of the
+ * frsh_contract_renegotiate_async() or frsh_group_change_mode_async()
+ * operations, the status returned is FNA_NOT_REQUESTED
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id we want the status from
+ * @param[in] renegotiation_status The status of the last renegotiation on
+ * vres (FRSH_RS_IN_PROGRESS, FRSH_RS_REJECTED, FRSH_RS_ADMITTED,
+ * FRSH_RS_NOT_REQUESTED)
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int rtep_fna_vres_get_renegotiation_status
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ frsh_renegotiation_status_t *renegotiation_status)
+{
+ return 0;
+}
+
+/**
+ * rtep_fna_vres_destroy()
+ *
+ * The operation eliminates the specified vres
+ * and recalculates all necessary parameters for the contracts
+ * remaining in the system. This is a potentially blocking operation;
+ * it returns when the system has made the changes effective.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id to destroy
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int rtep_fna_vres_destroy
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres)
+{
+ int err = 0;
+ int pos = (int) vres;
+
+ // cancel de negotiated contract (the function spread results
+ // among nodes)
+ err = rtep_bwres_vres_destroy (&rtep_vres_list[pos]);
+ if (err != 0) return -1;
+
+ // free the element in the rtep_vres list
+ err = fadt_freelist_free(&rtep_vres_freelist, pos);
+ if (err != 0) return -1;
+
+ return 0;
+}
+
+/**
+ * rtep_fna_vres_get_contract()
+ *
+ * This operation stores the contract parameters currently associated
+ * with the specified vres in the variable pointed to by
+ * contract. It returns an error if the vres_id is not recognised.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id
+ * @param[out] contract The contract parameters that we want
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int rtep_fna_vres_get_contract
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ frsh_contract_t *contract)
+{
+ return 0;
+}
+
+/**
+ * rtep_fna_vres_get_usage()
+ *
+ * This function gets the execution time spent by all messages that have been
+ * sent through the specified vres.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id
+ * @param[out] usage Execution time spent by this vres
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int rtep_fna_vres_get_usage
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ struct timespec *usage)
+{
+ return 0;
+}
+
+/**
+ * rtep_fna_vres_get_remaining_budget()
+ *
+ * This function stores in the variable pointed to by budget the
+ * remaining execution-time budget associated with the specified
+ * vres in the present period.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id
+ * @param[out] remaining_budget The remaining budget for this period
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int rtep_fna_vres_get_remaining_budget
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ struct timespec *remaining_budget)
+{
+ return 0;
+}
+
+/**
+ * rtep_fna_vres_get_budget_and_period()
+ *
+ * This function gets the budget and period associated with the specified vres
+ * for each period. If one of these pointers is NULL, the corresponding
+ * information is not stored.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id
+ * @param[out] budget The budget associated to vres
+ * @param[out] period The period associated to vres
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if both pointers are NULL \n
+ *
+ **/
+int rtep_fna_vres_get_budget_and_period
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ struct timespec *budget,
+ struct timespec *period)
+{
+ return 0;
+}
+
+/*@}*/
+
+///////////////////////////////////////////////////////////////////
+// SPARE CAPACITY FUNCIONS
+///////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup fnaspare FNA Spare Capacity
+ * @ingroup fna
+ *
+ * The following functions are used to get spare capacity data
+ *
+ * @{
+ **/
+
+/**
+ * rtep_fna_resource_get_capacity()
+ *
+ * This operation gets the spare capacity currently assigned to a importance
+ * level. If we divide this value by UINT32_MAX we will get the network
+ * utilization associated to the spare capacity of a importance level.
+ *
+ * The following is typically in stdint.h: \n
+ * - typedef unsigned int uint32_t; \n
+ * - # define UINT32_MAX (4294967295U) \n
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] importance The importance we want the capacity of
+ * @param[out] capacity The spare capacity for that importance level
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int rtep_fna_resource_get_capacity
+ (const frsh_resource_id_t resource_id,
+ const int importance,
+ uint32_t *capacity)
+{
+ return 0;
+}
+
+/**
+ * rtep_fna_resource_get_total_weight()
+ *
+ * This function gets the sum of the weight parameters for all vres in a
+ * network of an importance level.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] importance The importance we want the total weight of
+ * @param[out] total_weight The total weight for that importance level
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int rtep_fna_resource_get_total_weight
+ (const frsh_resource_id_t resource_id,
+ const int importance,
+ int *total_weight)
+{
+ return 0;
+}
+
+/**
+ * rtep_fna_vres_decrease_capacity()
+ *
+ * This function allows to ask for less budget and period than what we
+ * received. The request must be compatible with the rest of contract
+ * parameters of the vres. If we want to recover the released capacity
+ * we will need to renegotiate.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] vres The internal virtual resource id
+ * @param[in] new_budget The new_budget
+ * @param[in] new_period The new Period
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ * FNA_ERR_CONTRACT_REJECTED: if it is incompatible with the current
+ * contract \n
+ *
+ **/
+int rtep_fna_vres_decrease_capacity
+ (const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ const struct timespec new_budget,
+ const struct timespec new_period)
+{
+ return 0;
+}
+
+///////////////////////////////////////////////////////////////////
+// SEND RECEIVE OPERATIONS
+///////////////////////////////////////////////////////////////////
+
+/**
+ * rtep_fna_send_sync()
+ *
+ * Similar to previous function but now the sending thread gets blocked
+ * until the message is already sent to the network.
+ *
+ * @param[in] endpoint The send endpoint we are sending through. It must
+ * be bound to a virtual resource (resource_id is in the endpoint).
+ * @param[in] msg The message we want to send
+ * @param[in] size The size in bytes of the message
+ *
+ * @returns
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
+ * FNA_ERR_BUFFER_FULL: if the message has been discarded because
+ * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
+ *
+ **/
+int rtep_fna_send_sync
+ (const fna_endpoint_data_t *endpoint,
+ const void *msg,
+ const size_t size)
+{
+ DEBUG("dest: %d, chan: %d, size: %d, server: %d\n",
+ endpoint->destination, endpoint->stream_id, size,
+ rtep_vres_list[endpoint->vres].server_id);
+
+ // TODO: check errors
+ rtep_server_send_info
+ ((rtep_station_id_t) endpoint->destination,
+ (rtep_channel_t) endpoint->stream_id,
+ (uint8_t *) msg,
+ size,
+ rtep_vres_list[endpoint->vres].server_id,
+ 1); // blocking
+ return 0;
+}
+
+/**
+ * rtep_fna_send_async()
+ *
+ * This operation sends a message stored in msg and of length size
+ * through the given send endpoint. The operation is non-blocking and
+ * returns immediately.
+ *
+ * @param[in] endpoint The send endpoint we are sending through. It must
+ * be bound to a virtual resource (resource_id is in the endpoint).
+ * @param[in] msg The message we want to send
+ * @param[in] size The size in bytes of the message
+ *
+ * @returns
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
+ * FNA_ERR_BUFFER_FULL: if the message has been discarded because
+ * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
+ *
+ **/
+int rtep_fna_send_async
+ (const fna_endpoint_data_t *endpoint,
+ const void *msg,
+ const size_t size)
+{
+ DEBUG("dest: %d, chan: %d, size: %d, server: %d\n",
+ endpoint->destination, endpoint->stream_id, size,
+ rtep_vres_list[endpoint->vres].server_id);
+
+ // TODO: check errors
+ rtep_server_send_info
+ ((rtep_station_id_t) endpoint->destination,
+ (rtep_channel_t) endpoint->stream_id,
+ (uint8_t *) msg,
+ size,
+ rtep_vres_list[endpoint->vres].server_id,
+ 0); // not blocking
+ return 0;
+}
+
+/**
+ * rtep_fna_receive_sync()
+ *
+ * This operation is used to receive messages from the network with a
+ * blocking behavior (if there are no messages this operation blocks
+ * the calling thread).
+ *
+ * When a message is available, it is copied to buffer (up to its size).
+ * The number of bytes copied is returned in received_bytes. The rest
+ * of the bytes of that message will be lost or not depending on the
+ * protocol (FNA_ERR_NO_SPACE will be returned if it is).
+ *
+ * The function fails with FNA_ERR_NO_SPACE if the buffersize is
+ * too small for the message received. In this case the message is
+ * lost.
+ *
+ * Messages arriving at a receiver buffer that is full will be handled
+ * according to the queueing policy of the endpoint (overwrite oldest,
+ * discard it,etc).
+ *
+ * @param[in] endpoint The receive endpoint we are receiving from.
+ * (resource_id is in the endpoint).
+ * @param[out] buffer Buffer for storing the received message
+ * @param[in] buffer_size The size in bytes of this buffer
+ * @param[out] received_bytes The actual number of received bytes
+ * @param[out] from Address of the sender node
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ * FNA_ERR_NO_SPACE: if the message size is bigger than the
+ * provided buffer. \n
+ *
+ **/
+int rtep_fna_receive_sync
+ (const fna_endpoint_data_t *endpoint,
+ void *buffer,
+ const size_t buffer_size,
+ size_t *received_bytes,
+ frsh_network_address_t *from)
+{
+ rtep_priority_t prio;
+ rtep_station_id_t rtep_from;
+ rtep_channel_t chan = (rtep_channel_t) endpoint->stream_id;
+
+ // TODO: checks for errors
+ rtep_recv_info
+ (&rtep_from,
+ chan,
+ (uint8_t *) buffer,
+ buffer_size,
+ received_bytes,
+ &prio);
+
+ *from = rtep_from;
+
+ DEBUG(" %u bytes, from %u, prio %u\n",
+ *received_bytes, rtep_from, prio);
+
+ return 0;
+}
+
+/**
+ * rtep_fna_receive_async()
+ *
+ * This operation is similar to the previous one but it works in a non
+ * blocking (asynchronous) fashion. If no message is available it
+ * returns with error FNA_NO_MESSAGE.
+ *
+ * @param[in] endpoint The receive endpoint we are receiving from.
+ * (resource_id is in the endpoint).
+ * @param[out] buffer Buffer for storing the received message
+ * @param[in] buffer_size The size in bytes of this buffer
+ * @param[out] received_bytes The actual number of received bytes
+ * @param[out] from Address of the sender node
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ * FNA_ERR_NO_SPACE: if the message size is bigger than the
+ * provided buffer. \n
+ * FNA_NO_MESSAGE: if no messages are available in the queue. \n
+ *
+ **/
+int rtep_fna_receive_async
+ (const fna_endpoint_data_t *endpoint,
+ void *buffer,
+ const size_t buffer_size,
+ size_t *received_bytes,
+ frsh_network_address_t *from)
+{
+ return 0;
+}
+
+/**
+ * rtep_fna_send_endpoint_get_status()
+ *
+ * This function tells the number of messages still pending in the
+ * endpoint queue, whether the network is up or down with some
+ * optional information which is protocol_dependent.
+ *
+ * @param[in] endpoint The send endpoint (resource_id is in the endpoint).
+ * @param[out] number_of_pending_messages The number of pending messages
+ * @param[out] network_status How is the network (up, down..)
+ * @param[out] protocol_status Protocol dependent status info
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int rtep_fna_send_endpoint_get_status
+ (const fna_endpoint_data_t *endpoint,
+ int *number_of_pending_messages,
+ frsh_endpoint_network_status_t *network_status,
+ frsh_protocol_status_t *protocol_status)
+{
+ return 0;
+}
+
+/**
+ * rtep_fna_receive_endpoint_created()
+ *
+ * This operation is a called from frsh_receive_endpoint_create with a
+ * receive_endpoint structure already filled.
+ *
+ * Receiving endpoints are not bound to any network vres, this is
+ * because don't originate any traffic.
+ *
+ * @param[in] endpoint the endpoint object.
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ **/
+int rtep_fna_receive_endpoint_created
+ (fna_endpoint_data_t *endpoint)
+{
+ return 0;
+}
+
+/**
+ * rtep_fna_receive_endpoint_get_pending_messages
+ *
+ * This function tells the number of messages still pending in the
+ * endpoint queue, whether the network is up or down and some optional
+ * information which is protocol dependent.
+ *
+ * @param[in] endpoint The receive endpoint (resource_id is in the endpoint).
+ * @param[out] number_of_pending_messages The number of pending messages
+ * @param[out] network_status How is the network (up, down..)
+ * @param[out] protocol_status Protocol dependent status info
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int rtep_fna_receive_endpoint_get_status
+ (const fna_endpoint_data_t *endpoint,
+ int *number_of_pending_messages,
+ frsh_endpoint_network_status_t *network_status,
+ frsh_protocol_status_t *protocol_status)
+{
+ return 0;
+}
+
+//////////////////////////////////////////////////////////////////////
+// NETWORK CONFIGURATION FUNCTIONS
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * rtep_fna_network_get_max_message_size()
+ *
+ * This operation gives the maximum number of bytes that can be sent
+ * at a time through the send function when using the network designated by
+ * 'resource_id' and sending it to 'destination'.
+ *
+ * If the application needs to send bigger messages it will have to
+ * split them.
+ *
+ * Some protocols, like IP, are capable of sending large messages
+ * (and use fragmentation internally) but other protocols don't.
+ *
+ * @param[in] resource_id The network we want the tx time from.
+ * @param[in] destination The destination address
+ * @param[out] max_size The maximum number of bytes for each message
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
+ * invalid \n
+ *
+ **/
+int rtep_fna_network_get_max_message_size
+ (const frsh_resource_id_t resource_id,
+ const frsh_network_address_t destination,
+ size_t *max_size)
+{
+ int is_multicast;
+
+ if (max_size == NULL) {
+ return -1;
+ }
+
+ is_multicast = rtep_valid_multicast_id((rtep_station_id_t) destination);
+ if (is_multicast) {
+ *max_size = MULTICAST_MTU;
+ } else {
+ *max_size = MAX_RTEP_MTU;
+ }
+ return 0;
+}
+
+/**
+ * rtep_fna_network_bytes_to_budget()
+ *
+ * This operation converts a number of bytes into a temporal budget for
+ * a specific network. Network overheads are not included here but are
+ * considered internally when negotiating a specific contract.
+ *
+ * @param[in] resource_id The network
+ * @param[in] nbytes Number of bytes
+ * @param[out] budget The network budget for nbytes
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or nbytes is less
+ * than zero \n
+ *
+ **/
+int rtep_fna_network_bytes_to_budget
+ (const frsh_resource_id_t resource_id,
+ const size_t nbytes,
+ struct timespec *budget)
+{
+ int number_of_packets;
+
+ if (budget == NULL || nbytes < 0) {
+ return -1;
+ }
+
+ // we measure the budget in number of RTEP packets of maximum size
+ number_of_packets = nbytes / MAX_RTEP_MTU + 1;
+ // we store the budget in number of packets instead of in time. We
+ // use a field in the timespec structure.
+ budget->tv_sec = number_of_packets;
+ DEBUG("bytes: %d -> budget: %d\n", nbytes, budget->tv_sec);
+ return 0;
+}
+
+/**
+ * rtep_fna_network_budget_to_bytes()
+ *
+ * This operation converts a temporal budget into a number of bytes for
+ * a specific network. Network overheads are not included.
+ *
+ * @param[in] resource_id The network
+ * @param[in] budget The network budget for nbytes
+ * @param[out] nbytes Number of bytes
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
+ * an invalid time value \n
+ *
+ **/
+int rtep_fna_network_budget_to_bytes
+ (const frsh_resource_id_t resource_id,
+ const struct timespec *budget,
+ size_t *nbytes)
+{
+ int number_of_packets;
+
+ if (budget == NULL || nbytes == NULL) {
+ return -1;
+ }
+ number_of_packets = budget->tv_sec;
+ *nbytes = number_of_packets * MAX_RTEP_MTU;
+ return 0;
+}
+
+/**
+ * rtep_fna_network_get_min_eff_budget()
+ *
+ * This operation gets the minimum effective budget for a network. Each message
+ * consumes a contracted budget in "chunks" (i.e: packets) that we call
+ * minimum effective budget.
+ *
+ * A negotiated contract, for N bytes in a period T, means that there is a
+ * virtual resource that reserves for the user:
+ *
+ * Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
+ *
+ * Note that if the user decides not to send these N bytes at once but, say,
+ * one byte at a time, it will consume one "CHUNK" at a time and the reserved
+ * budget will become exhausted before sending all the bytes.
+ *
+ * @param[in] resource_id The network
+ * @param[out] budget The network budget
+ *
+ * @return
+ * 0 if there are no errors \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int rtep_fna_network_get_min_eff_budget
+ (const frsh_resource_id_t resource_id,
+ struct timespec *budget)
+{
+ if (budget == NULL) {
+ return -1;
+ }
+ budget->tv_sec = 1;
+ return 0;
+}
+
+// GLOBAL variable to install the network protocol in FRESCOR
+
+fna_operations_t rtep_fna_operations = {
+#ifdef CONFIG_FNA_RTEP_CONNECTED
+ .fna_init = rtep_fna_init,
+ .fna_contract_negotiate = rtep_fna_contract_negotiate,
+ .fna_contract_renegotiate_sync = rtep_fna_contract_renegotiate_sync,
+ .fna_contract_renegotiate_async = rtep_fna_contract_renegotiate_async,
+ .fna_vres_get_renegotiation_status = rtep_fna_vres_get_renegotiation_status,
+ .fna_vres_destroy = rtep_fna_vres_destroy,
+ .fna_vres_get_contract = rtep_fna_vres_get_contract,
+ .fna_vres_get_usage = rtep_fna_vres_get_usage,
+ .fna_vres_get_remaining_budget = rtep_fna_vres_get_remaining_budget,
+ .fna_vres_get_budget_and_period = rtep_fna_vres_get_budget_and_period,
+ .fna_resource_get_capacity = rtep_fna_resource_get_capacity,
+ .fna_resource_get_total_weight = rtep_fna_resource_get_total_weight,
+ .fna_vres_decrease_capacity = rtep_fna_vres_decrease_capacity,
+ .fna_send_sync = rtep_fna_send_sync,
+ .fna_send_async = rtep_fna_send_async,
+ .fna_receive_sync = rtep_fna_receive_sync,
+ .fna_receive_async = rtep_fna_receive_async,
+ .fna_send_endpoint_get_status = rtep_fna_send_endpoint_get_status,
+ .fna_receive_endpoint_created = rtep_fna_receive_endpoint_created,
+ .fna_receive_endpoint_get_status = rtep_fna_receive_endpoint_get_status,
+#endif
+ .fna_network_get_max_message_size = rtep_fna_network_get_max_message_size,
+ .fna_network_bytes_to_budget = rtep_fna_network_bytes_to_budget,
+ .fna_network_budget_to_bytes = rtep_fna_network_budget_to_bytes,
+ .fna_network_get_min_eff_budget = rtep_fna_network_get_min_eff_budget
+};
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+
+#include "frsh_fna.h"
+#include "rtep_bandwith_reservation.h"
+
+//////////////////////////////////////////////////////////////////////
+// MAPPING FUNCTIONS
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * frsh_XXXX_map_network_address()
+ *
+ * To map a XXXX protocol network address into a FRSH address.
+ * The protocol must keep this mapping consistent. Instead of using a function
+ * a hardwired mapping could be used.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] in_address The network address we want to map to a frsh address
+ * @param[out] out_address The FRSH abstract network address
+ *
+ * @return
+ * FNA_NO_ERROR: in this case it also means contract accepted \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frsh_rtep_map_network_address
+ (const frsh_resource_id_t resource_id,
+ const rtep_station_id_t in_address,
+ frsh_network_address_t *out_address)
+{
+ if (out_address == NULL) return -1;
+ *out_address = in_address;
+ return 0;
+}
+
+/**
+ * frsh_XXXX_map_stream_id()
+ *
+ * To map a XXXX protocol network stream, port, channel... into a FRSH stream.
+ * The protocol must keep this mapping consistent. Instead of using a function
+ * a hardwired mapping could be used.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] in_stream The network stream we want to map to a FRSH stream
+ * @param[out] out_stream The FRSH abstract network stream
+ *
+ * @return
+ * FNA_NO_ERROR: in this case it also means contract accepted \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frsh_rtep_map_stream_id
+ (const frsh_resource_id_t resource_id,
+ const rtep_channel_t in_stream,
+ frsh_stream_id_t *out_stream)
+{
+ if (out_stream == NULL) return -1;
+ *out_stream = in_stream;
+ return 0;
+}
+
+///////////////////////////////////////////////////////////////////
+// NEGOTIATION SERVICE PARAMETERS
+///////////////////////////////////////////////////////////////////
+
+/**
+ * frsh_XXXX_negotiation_messages__vres_renegotiate()
+ *
+ * This function allows the application to change the minimum period
+ * of the negotiation messages sent through the network. It is similar
+ * to the service thread but for the network messages. We do not provide
+ * budget here because the size of the negotiation messages is fixed.
+ *
+ * This change is similar to a renegotiation so a schedulability test
+ * must be done to see if the change can be accepted or not.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] period The new period for negotiation messages
+ * @param[out] accepted If the change has been accepted or not
+ *
+ * @return
+ * FNA_NO_ERROR: in this case it also means contract accepted \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+
+int frsh_rtep_negotiation_messages_vres_renegotiate
+ (const frsh_resource_id_t resource_id,
+ const struct timespec *period)
+{
+ return rtep_bwres_renegotiate_negotiation_period(period);
+}
+
+/**
+ * frsh_XXXX_negotiation_messages_vres_get_period()
+ *
+ * This function gets the minimum period of the negotiation messages
+ * sent through the network.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[out] period The period for negotiation messages
+ *
+ * @return
+ * FNA_NO_ERROR: in this case it also means contract accepted \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frsh_rtep_negotiation_messages_vres_get_period
+ (const frsh_resource_id_t resource_id,
+ struct timespec *period)
+{
+ return rtep_bwres_get_negotiation_period (period);
+}
+
+/**
+ * frsh_XXXX_service_thread_vres_renegotiate()
+ *
+ * This function allows the application to change the period and
+ * budget of the service thread that makes the negotiations and
+ * schedulability tests in a network.
+ *
+ * The service thread starts with a default budget and period that
+ * should be configurable
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[in] budget The new budget for the service thread
+ * @param[in] period The new period for the service thread
+ * @param[out] accepted If the negotiation has been accepted or not
+ *
+ * @return
+ * FNA_NO_ERROR: in this case it also means contract accepted \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frsh_rtep_service_thread_vres_renegotiate
+ (const frsh_resource_id_t resource_id,
+ const struct timespec *budget,
+ const struct timespec *period,
+ bool *accepted)
+{
+ return -1;
+}
+
+/**
+ * frsh_XXXX_service_thread_vres_get_budget_and_period()
+ *
+ * This function gets the budget and period of a service thread.
+ *
+ * @param[in] resource_id The network we are referring to (a protocol
+ * could be able to handle several networks at the same time)
+ * @param[out] budget The budget of the service thread
+ * @param[out] period The period of the service thread
+ *
+ * @return
+ * FNA_NO_ERROR: in this case it also means contract accepted \n
+ * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
+ * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frsh_rtep_service_thread_vres_get_budget_and_period
+ (const frsh_resource_id_t resource_id,
+ struct timespec *budget,
+ struct timespec *period)
+{
+ return -1;
+}
+
--- /dev/null
+.PHONY: all objs libunixfna.a
+
+all: libunixfna.a
+include ../config.mk
+include ../rules.mk
+
+SRCS := $(wildcard *.c)
+OBJS := $(patsubst %.c,%.o,$(wildcard *.c))
+HDRS := $(wildcard $(FNA_PATH)/include/*.h)
+
+objs: $(OBJS)
+
+%.o: %.c $(SRCS) $(HDRS)
+ $(CC) $(CFLAGS) -c $<
+
+libunixfna.a: objs
+ @exec echo -e "\n>> Building UNIX FNA:";
+ @ar -rc libunixfna.a *.o
+ @mv libunixfna.a $(FNA_PATH)/lib
+ @exec echo ">> end Building UNIX FNA [OK]"
--- /dev/null
+lib_LIBRARIES=unixfna
+unixfna_SOURCES=$(notdir $(wildcard $(SOURCES_DIR)/*.c))
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+// ******** **** ** **
+// **///// /**/** /** ****
+// ** /**//** /** **//**
+// ******* /** //** /** ** //**
+// **//// /** //**/** **********
+// ** /** //****/**//////**
+// ** /** //***/** /**
+// / // /// // //
+//
+// FNA(Frescor Network Adaptation layer), pronounced "efe ene a"
+//==============================================================
+
+/**
+ * unix fna implementation
+ *
+ * In the following functions we implement a DUMMY FNA implementation without
+ * contracts or real-time requirements just for testing purposes. We provide
+ * send/receive capabilities between Linux processes through UNIX domain
+ * datagram sockets.
+ *
+ * The goal is to run FRSH on several processes by using the Linux_lib arch
+ * of MaRTE OS or Partikle to simulate a distributed system in a single PC.
+ *
+ * The main tricks of the implementation are the following:
+ *
+ * - We encode the address and stream in the Unix socket path as:
+ * '/tmp/unix_fna-address-stream'
+ * - At initialization we create MX_UNIX_STREAM_IDS sockets for our address
+ * (our address number is defined by FRSH_CPU_ID_DEFAULT)
+ * - When the user SENDS we obtain the address creating the mentioned string
+ * from the destination address and the stream.
+ * - When the user RECEIVES we use the appropiate socket by using the
+ * stream_id information.
+ *
+ **/
+
+#include <malloc.h> /* for malloc and free */
+#include <assert.h>
+#include <string.h> /* for string functions: strtok, strcpy, ... */
+
+#include "frsh_distributed_types.h" /* for frsh_network_address_t, frsh_stream_id_t */
+#include "unix_fna.h" /* function prototypes */
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+/* DEBUGGING FLAGS and MACROS */
+#include <stdio.h>
+#define DEBUG(enable,x,args...) if(enable) printf("\t>> Called %s: " x, __func__ , ##args)
+#define DBG_UNIX_FNA_NOT_IMPLEMENTED true
+
+/**
+ * to_unix_path()
+ *
+ **/
+
+static int to_unix_path(const frsh_network_address_t addr,
+ const frsh_stream_id_t stream,
+ char *str,
+ size_t mx_size)
+{
+ return snprintf(str, mx_size, "/tmp/unix_fna-%d-%d", addr, stream);
+}
+
+/**
+ * to_addr_stream()
+ *
+ **/
+
+static int to_addr_stream(frsh_network_address_t *addr,
+ frsh_stream_id_t *stream,
+ char *str,
+ size_t size)
+{
+ char *token;
+ char *search = "-";
+
+ token = strtok(str, search);
+ token = strtok(NULL, search);
+ *addr = atoi(token);
+ token = strtok(NULL, search);
+ *stream = atoi(token);
+
+ return 0;
+}
+
+//////////////////////////////////////////////////////////////////////
+// INITIALIZATION
+//////////////////////////////////////////////////////////////////////
+
+int the_unix_sockets[MX_UNIX_STREAM_IDS];
+
+/**
+ * unix_fna_init()
+ *
+ * for each stream_id create a socket and bind it to the address obtained
+ * from "/tmp/unix_fna-addr-stream"
+ *
+ **/
+
+int unix_fna_init(const frsh_resource_id_t resource_id)
+{
+ int i, err;
+ struct sockaddr_un sock_addr;
+
+ DEBUG(true, "creating unix sockets\n");
+
+ for(i=0; i<MX_UNIX_STREAM_IDS; i++) {
+ the_unix_sockets[i] = socket(AF_UNIX, SOCK_DGRAM, 0);
+ assert(the_unix_sockets[i] >= 0);
+
+ memset(&sock_addr, 0, sizeof(sock_addr));
+ sock_addr.sun_family = AF_UNIX;
+ err = to_unix_path(FRSH_CPU_ID_DEFAULT,
+ (frsh_stream_id_t) i,
+ sock_addr.sun_path,
+ sizeof(sock_addr.sun_path));
+ assert(err >= 0);
+
+ err = bind(the_unix_sockets[i],
+ (struct sockaddr *)&sock_addr,
+ sizeof(sock_addr));
+ assert(err >= 0);
+ }
+
+ return 0;
+}
+
+///////////////////////////////////////////////////////////////////
+// VIRTUAL RESOURCES
+///////////////////////////////////////////////////////////////////
+
+/**
+ * unix_fna_contract_negotiate()
+ *
+ **/
+
+int unix_fna_contract_negotiate(const frsh_resource_id_t resource_id,
+ const frsh_contract_t *contract,
+ fna_vres_id_t *vres)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+/**
+ * unix_fna_contract_renegotiate_sync()
+ *
+ **/
+
+int unix_fna_contract_renegotiate_sync(const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ const frsh_contract_t *new_contract)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+/**
+ * unix_fna_contract_renegotiate_async()
+ *
+ **/
+
+int unix_fna_contract_renegotiate_async(const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ const frsh_contract_t *new_contract,
+ frsh_signal_t signal_to_notify,
+ frsh_signal_info_t signal_info)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+/**
+ * unix_fna_vres_get_renegotiation_status()
+ *
+ **/
+
+int unix_fna_vres_get_renegotiation_status(const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ frsh_renegotiation_status_t *renegotiation_status)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+/**
+ * unix_fna_vres_destroy()
+ *
+ **/
+
+int unix_fna_vres_destroy(const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+/**
+ * unix_fna_vres_get_contract()
+ *
+ **/
+
+int unix_fna_vres_get_contract(const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ frsh_contract_t *contract)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+/**
+ * unix_fna_vres_get_usage()
+ *
+ **/
+
+int unix_fna_vres_get_usage(const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ struct timespec *usage)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+/**
+ * unix_fna_vres_get_remaining_budget()
+ *
+ **/
+
+int unix_fna_vres_get_remaining_budget(const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ struct timespec *remaining_budget)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+/**
+ * unix_fna_vres_get_budget_and_period()
+ *
+ **/
+
+int unix_fna_vres_get_budget_and_period(const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ struct timespec *budget,
+ struct timespec *period)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+///////////////////////////////////////////////////////////////////
+// SPARE CAPACITY FUNCIONS
+///////////////////////////////////////////////////////////////////
+
+/**
+ * unix_fna_resource_get_capacity()
+ *
+ **/
+
+int unix_fna_resource_get_capacity(const frsh_resource_id_t resource_id,
+ const int importance,
+ uint32_t *capacity)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+/**
+ * unix_fna_resource_get_total_weight()
+ *
+ **/
+
+int unix_fna_resource_get_total_weight(const frsh_resource_id_t resource_id,
+ const int importance,
+ int *total_weight)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+/**
+ * unix_fna_vres_decrease_capacity()
+ *
+ **/
+
+int unix_fna_vres_decrease_capacity(const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres,
+ const struct timespec new_budget,
+ const struct timespec new_period)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+///////////////////////////////////////////////////////////////////
+// SEND RECEIVE OPERATIONS
+///////////////////////////////////////////////////////////////////
+
+/**
+ * unix_fna_send_sync()
+ *
+ **/
+
+int unix_fna_send_sync(const fna_endpoint_data_t *endpoint,
+ const void *msg,
+ const size_t size)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+/**
+ * unix_fna_send_async()
+ *
+ * To send we use one of our sockets (it doesn't matter which one so we use
+ * the first one). The destination is obtained from the endpoint values for
+ * dest and stream.
+ *
+ **/
+
+int unix_fna_send_async(const fna_endpoint_data_t *endpoint,
+ const void *msg,
+ const size_t size)
+{
+ int err;
+ struct sockaddr_un to;
+ ssize_t sent_bytes;
+
+ DEBUG(true, "send async\n");
+
+ assert(endpoint->is_bound);
+
+ memset(&to, 0, sizeof(to));
+ to.sun_family = AF_UNIX;
+
+ err = to_unix_path(endpoint->destination,
+ endpoint->stream_id,
+ to.sun_path,
+ sizeof(to.sun_path));
+ assert(err >= 0);
+
+ sent_bytes = sendto(the_unix_sockets[0],
+ msg,
+ size,
+ 0,
+ (struct sockaddr *) &to,
+ sizeof(to));
+ assert(sent_bytes >= 0);
+
+ return 0;
+}
+
+/**
+ * unix_fna_receive_sync()
+ *
+ * We call recvfrom using the socket associated to the corresponding stream_id.
+ * The "from" address is obtained by parsing the unix address path.
+ *
+ **/
+
+int unix_fna_receive_sync(const fna_endpoint_data_t *endpoint,
+ void *buffer,
+ const size_t buffer_size,
+ size_t *received_bytes,
+ frsh_network_address_t *from)
+{
+ int err;
+ struct sockaddr_un sender_addr;
+ ssize_t recv_bytes;
+ socklen_t from_len;
+ frsh_network_address_t addr;
+ frsh_stream_id_t stream;
+
+ DEBUG(true, "receive sync\n");
+
+ from_len = sizeof(sender_addr);
+ recv_bytes = recvfrom(the_unix_sockets[endpoint->stream_id],
+ buffer,
+ buffer_size,
+ 0,
+ (struct sockaddr *)&sender_addr,
+ &from_len);
+
+ assert(recv_bytes >= 0);
+ *received_bytes = recv_bytes;
+
+ err = to_addr_stream(&addr,
+ &stream,
+ sender_addr.sun_path,
+ sizeof(sender_addr.sun_path));
+ assert(err == 0);
+ *from = addr;
+
+ return 0;
+}
+
+/**
+ * unix_fna_receive_async()
+ *
+ **/
+
+int unix_fna_receive_async(const fna_endpoint_data_t *endpoint,
+ void *buffer,
+ const size_t buffer_size,
+ size_t *received_bytes,
+ frsh_network_address_t *from)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+/**
+ * unix_fna_send_endpoint_get_status()
+ *
+ **/
+
+int unix_fna_send_endpoint_get_status(const fna_endpoint_data_t *endpoint,
+ int *number_of_pending_messages,
+ frsh_endpoint_network_status_t *network_status,
+ frsh_protocol_status_t *protocol_status)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+/**
+ * unix_fna_receive_endpoint_created()
+ *
+ **/
+int unix_fna_receive_endpoint_created(fna_endpoint_data_t *endpoint)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+/**
+ * unix_fna_receive_endpoint_get_pending_messages
+ *
+ **/
+
+int unix_fna_receive_endpoint_get_status(const fna_endpoint_data_t *endpoint,
+ int *number_of_pending_messages,
+ frsh_endpoint_network_status_t *network_status,
+ frsh_protocol_status_t *protocol_status)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+//////////////////////////////////////////////////////////////////////
+// NETWORK CONFIGURATION FUNCTIONS
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * unix_fna_network_get_max_message_size()
+ *
+ **/
+
+int unix_fna_network_get_max_message_size(const frsh_resource_id_t resource_id,
+ const frsh_network_address_t destination,
+ size_t *max_size)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+/**
+ * unix_fna_network_bytes_to_budget()
+ *
+ **/
+
+int unix_fna_network_bytes_to_budget(const frsh_resource_id_t resource_id,
+ const size_t nbytes,
+ struct timespec *budget)
+{
+ DEBUG(true, "let's put 1 microsecond for all\n");
+ budget->tv_sec = 0;
+ budget->tv_nsec = 1000;
+ return 0;
+}
+
+/**
+ * unix_fna_network_budget_to_bytes()
+ *
+ **/
+
+int unix_fna_network_budget_to_bytes(const frsh_resource_id_t resource_id,
+ const struct timespec *budget,
+ size_t *nbytes)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+/**
+ * unix_fna_network_get_min_eff_budget()
+ *
+ **/
+
+int unix_fna_network_get_min_eff_budget(const frsh_resource_id_t resource_id,
+ struct timespec *budget)
+{
+ DEBUG(DBG_UNIX_FNA_NOT_IMPLEMENTED, "NOT IMPLEMENTED\n");
+ return 0;
+}
+
+// GLOBAL variable to install the network protocol in FRESCOR
+
+fna_operations_t unix_fna_operations = {
+ .fna_init = unix_fna_init,
+ .fna_contract_negotiate = unix_fna_contract_negotiate,
+ .fna_contract_renegotiate_sync = unix_fna_contract_renegotiate_sync,
+ .fna_contract_renegotiate_async = unix_fna_contract_renegotiate_async,
+ .fna_vres_get_renegotiation_status = unix_fna_vres_get_renegotiation_status,
+ .fna_vres_destroy = unix_fna_vres_destroy,
+ .fna_vres_get_contract = unix_fna_vres_get_contract,
+ .fna_vres_get_usage = unix_fna_vres_get_usage,
+ .fna_vres_get_remaining_budget = unix_fna_vres_get_remaining_budget,
+ .fna_vres_get_budget_and_period = unix_fna_vres_get_budget_and_period,
+ .fna_resource_get_capacity = unix_fna_resource_get_capacity,
+ .fna_resource_get_total_weight = unix_fna_resource_get_total_weight,
+ .fna_vres_decrease_capacity = unix_fna_vres_decrease_capacity,
+ .fna_send_sync = unix_fna_send_sync,
+ .fna_send_async = unix_fna_send_async,
+ .fna_receive_sync = unix_fna_receive_sync,
+ .fna_receive_async = unix_fna_receive_async,
+ .fna_send_endpoint_get_status = unix_fna_send_endpoint_get_status,
+ .fna_receive_endpoint_created = unix_fna_receive_endpoint_created,
+ .fna_receive_endpoint_get_status = unix_fna_receive_endpoint_get_status,
+ .fna_network_get_max_message_size = unix_fna_network_get_max_message_size,
+ .fna_network_bytes_to_budget = unix_fna_network_bytes_to_budget,
+ .fna_network_budget_to_bytes = unix_fna_network_budget_to_bytes,
+ .fna_network_get_min_eff_budget = unix_fna_network_get_min_eff_budget
+};
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+// ******** **** ** **
+// **///// /**/** /** ****
+// ** /**//** /** **//**
+// ******* /** //** /** ** //**
+// **//// /** //**/** **********
+// ** /** //****/**//////**
+// ** /** //***/** /**
+// / // /// // //
+//
+// FNA(Frescor Network Adaptation layer), pronounced "efe ene a"
+//==============================================================
+
+#ifndef _UNIX_FNA_H_
+#define _UNIX_FNA_H_
+
+#include "fna.h" // for fna_operations_t
+
+extern fna_operations_t unix_fna_operations;
+
+#define MX_UNIX_STREAM_IDS 6
+#define MX_UNIX_NETWORK_ADDR 3
+
+#endif // _UNIX_FNA_H_
--- /dev/null
+.PHONY: tests
+include ../../config.mk
+include ../../rules.mk
+
+EXES := $(patsubst %.c,%.exe,$(wildcard *.c))
+
+tests: $(EXES)
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+
+#include "frsh.h"
+
+#include "frescan.h"
+#include "frescan_bwres.h"
+#include "frescan_servers.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+#define LOCAL_NODE 0
+
+int main ()
+{
+ int ret;
+ frescan_init_params_t init_params;
+ frescan_ss_t ss1, ss2, ss3;
+ frsh_contract_t contract;
+ bool accepted;
+ frescan_server_params_t server_params;
+ frsh_rel_time_t budget_min, period_max;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 10;
+ init_params.rx_channel_max_prio = NULL;
+
+ printf("Initializing FRESCAN\n");
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("Initializing BWRES\n");
+ ret = frescan_bwres_init(NETWORK);
+ if (ret != 0) PUT_ERROR ("could not init BWRES");
+
+ ret = frsh_contract_init(&contract);
+ if (ret != 0) PUT_ERROR ("could not init contract");
+
+ budget_min.tv_sec = 5;
+ period_max = frsh_msec_to_rel_time(3333);
+
+ ret = frsh_contract_set_basic_params
+ (&contract,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ if (ret != 0) PUT_ERROR ("could not set basic params");
+
+#if !FRSH_AUTOMATIC_PRIO_ASSIGN_ENABLE
+ ret = frsh_contract_set_preemption_level(&contract, 7);
+ if (ret != 0) PUT_ERROR ("could not set preemption level");
+#endif
+
+ ret = frescan_bwres_negotiate(NETWORK, &contract, &ss1, &accepted);
+ if (ret != 0) PUT_ERROR ("could not negotiate");
+
+ if (accepted) {
+ printf("The contract was accepted, ss:%u\n", ss1);
+ ret = frescan_servers_get_data(NETWORK, &server_params, ss1);
+ if (ret != 0) PUT_ERROR ("could not get servers data");
+
+ printf("B:%u, T=(%u,%u), P:%u\n",
+ server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+ } else {
+ printf("The contract was not accepted\n");
+ }
+
+ budget_min.tv_sec = 6;
+ period_max = frsh_msec_to_rel_time(2600);
+
+ ret = frsh_contract_set_basic_params
+ (&contract,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ if (ret != 0) PUT_ERROR ("could not set basic params");
+
+#if !FRSH_AUTOMATIC_PRIO_ASSIGN_ENABLE
+ ret = frsh_contract_set_preemption_level(&contract, 4);
+ if (ret != 0) PUT_ERROR ("could not set preemption level");
+#endif
+
+ ret = frescan_bwres_negotiate(NETWORK, &contract, &ss2, &accepted);
+ if (ret != 0) PUT_ERROR ("could not negotiate");
+
+ if (accepted) {
+ printf("The contract was accepted, ss:%u\n", ss2);
+ ret = frescan_servers_get_data(NETWORK, &server_params, ss2);
+ if (ret != 0) PUT_ERROR ("could not get servers data");
+
+ printf("B:%u, T=(%u,%u), P:%u\n",
+ server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+ } else {
+ printf("The contract was not accepted\n");
+ }
+
+ ret = frescan_bwres_cancel(NETWORK, ss1);
+ if (ret != 0) PUT_ERROR ("could not cancel server");
+
+ budget_min.tv_sec = 1;
+ period_max = frsh_msec_to_rel_time(6666);
+
+ ret = frsh_contract_set_basic_params
+ (&contract,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ if (ret != 0) PUT_ERROR ("could not set basic params");
+
+#if !FRSH_AUTOMATIC_PRIO_ASSIGN_ENABLE
+ ret = frsh_contract_set_preemption_level(&contract, 3);
+ if (ret != 0) PUT_ERROR ("could not set preemption level");
+#endif
+
+ ret = frescan_bwres_negotiate(NETWORK, &contract, &ss3, &accepted);
+ if (ret != 0) PUT_ERROR ("could not negotiate");
+
+ if (accepted) {
+ printf("The contract was accepted, ss:%u\n", ss3);
+ ret = frescan_servers_get_data(NETWORK, &server_params, ss3);
+ if (ret != 0) PUT_ERROR ("could not get servers data");
+
+ printf("B:%u, T=(%u,%u), P:%u\n",
+ server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+ } else {
+ printf("The contract was not accepted\n");
+ }
+
+ while (1) {
+ sleep(1);
+ }
+
+ return 0;
+}
+
+
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+
+#include "frsh.h"
+
+#include "frescan.h"
+#include "frescan_bwres.h"
+#include "frescan_servers.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+#define LOCAL_NODE 1
+
+int main ()
+{
+ int ret;
+ frescan_init_params_t init_params;
+ frescan_ss_t ss1, ss2, ss3;
+ frsh_contract_t contract;
+ frescan_server_params_t server_params;
+ bool accepted;
+ frsh_rel_time_t budget_min, period_max;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 10;
+ init_params.rx_channel_max_prio = NULL;
+
+ printf("Initializing FRESCAN\n");
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("Initializing BWRES\n");
+ ret = frescan_bwres_init(NETWORK);
+ if (ret != 0) PUT_ERROR ("could not init BWRES");
+
+ ret = frsh_contract_init(&contract);
+ if (ret != 0) PUT_ERROR ("could not init contract");
+
+ budget_min.tv_sec = 5;
+ period_max = frsh_msec_to_rel_time(3000);
+
+ ret = frsh_contract_set_basic_params
+ (&contract,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ if (ret != 0) PUT_ERROR ("could not set basic params");
+
+#if !FRSH_AUTOMATIC_PRIO_ASSIGN_ENABLE
+ ret = frsh_contract_set_preemption_level(&contract, 5);
+ if (ret != 0) PUT_ERROR ("could not set preemption level");
+#endif
+
+ printf("Negotiating a contract 1\n");
+ ret = frescan_bwres_negotiate(NETWORK, &contract, &ss1, &accepted);
+ if (ret != 0) PUT_ERROR ("could not negotiate succesfully");
+
+ if (accepted) {
+ printf("The contract was accepted, ss:%u\n", ss1);
+ ret = frescan_servers_get_data(NETWORK, &server_params, ss1);
+ if (ret != 0) PUT_ERROR ("could not get servers data");
+
+ printf("B:%u, T=(%u,%u), P:%u\n",
+ server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+ } else {
+ printf("The contract was not accepted\n");
+ }
+
+ budget_min.tv_sec = 6;
+ period_max = frsh_msec_to_rel_time(2600);
+
+ ret = frsh_contract_set_basic_params
+ (&contract,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ if (ret != 0) PUT_ERROR ("could not set basic params");
+
+#if !FRSH_AUTOMATIC_PRIO_ASSIGN_ENABLE
+ ret = frsh_contract_set_preemption_level(&contract, 4);
+ if (ret != 0) PUT_ERROR ("could not set preemption level");
+#endif
+
+ printf("Negotiating a contract 2\n");
+ ret = frescan_bwres_negotiate(NETWORK, &contract, &ss2, &accepted);
+ if (ret != 0) PUT_ERROR ("could not negotiate");
+
+ if (accepted) {
+ printf("The contract was accepted, ss:%u\n", ss2);
+ ret = frescan_servers_get_data(NETWORK, &server_params, ss2);
+ if (ret != 0) PUT_ERROR ("could not get servers data");
+
+ printf("B:%u, T=(%u,%u), P:%u\n",
+ server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+ } else {
+ printf("The contract was not accepted\n");
+ }
+
+ printf("cancelling contract for ss:%u\n", ss1);
+ ret = frescan_bwres_cancel(NETWORK, ss1);
+ if (ret != 0) PUT_ERROR ("could not cancel server");
+
+ budget_min.tv_sec = 1;
+ period_max = frsh_msec_to_rel_time(6666);
+
+ ret = frsh_contract_set_basic_params
+ (&contract,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ if (ret != 0) PUT_ERROR ("could not set basic params");
+
+#if !FRSH_AUTOMATIC_PRIO_ASSIGN_ENABLE
+ ret = frsh_contract_set_preemption_level(&contract, 3);
+ if (ret != 0) PUT_ERROR ("could not set preemption level");
+#endif
+
+ printf("Negotiating a contract 3\n");
+ ret = frescan_bwres_negotiate(NETWORK, &contract, &ss3, &accepted);
+ if (ret != 0) PUT_ERROR ("could not negotiate");
+
+ if (accepted) {
+ printf("The contract was accepted, ss:%u\n", ss3);
+ ret = frescan_servers_get_data(NETWORK, &server_params, ss3);
+ if (ret != 0) PUT_ERROR ("could not get servers data");
+
+ printf("B:%u, T=(%u,%u), P:%u\n",
+ server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+ } else {
+ printf("The contract was not accepted\n");
+ }
+
+ while (1) {
+ sleep(1);
+ }
+
+ return 0;
+}
+
+
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+#include <assert.h>
+
+#include "frsh.h"
+
+#include "frescan.h"
+#include "frescan_bwres.h"
+#include "frescan_servers.h"
+
+#define ENABLE_MEASURES
+
+#ifdef ENABLE_MEASURES
+#include <misc/time_measurement_hwtime.h>
+#include <misc/logger.h>
+
+static const trace_point_id_t BEGIN_GN_NEG = 0;
+static const trace_point_id_t END_GN_NEG = 1;
+#endif
+
+#define NETWORK 0
+#define LOCAL_NODE 0
+#define NUM_CONTRACTS 2 // 1 .. FRESCAN_BWRES_MAX_GROUP_OPS
+
+// #define USE_GN
+
+#if 0
+#include <stdio.h>
+#define DEBUG(x,args...) printf("%s: " x, __func__ , ##args)
+#else
+#define DEBUG(x,args...)
+#endif
+
+extern int frescan_fna_network_bytes_to_budget
+ (const frsh_resource_id_t resource_id,
+ const size_t nbytes,
+ frsh_rel_time_t *budget);
+
+static void create_contract(frsh_contract_t *contract);
+
+int main ()
+{
+ int ret, i;
+ frescan_init_params_t init_params;
+ frescan_ss_group_t ss_new;
+ frsh_contracts_group_t contracts_to_neg;
+ bool accepted;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 10;
+ init_params.rx_channel_max_prio = NULL;
+
+#ifdef ENABLE_MEASURES
+ ret = logger_init(LOG_ETHERNET);
+ assert(ret == 0);
+
+#if (LOCAL_NODE == 0)
+ ret = time_measure_hwtime_init(BEGIN_GN_NEG, "master_begin");
+ assert(ret == 0);
+ ret = time_measure_hwtime_init(END_GN_NEG, "master_end");
+ assert(ret == 0);
+#else
+ ret = time_measure_hwtime_init(BEGIN_GN_NEG, "slave_begin");
+ assert(ret == 0);
+ ret = time_measure_hwtime_init(END_GN_NEG, "slave_end");
+ assert(ret == 0);
+#endif
+#endif
+
+ DEBUG("Initializing FRESCAN\n");
+ ret = frescan_init(&init_params);
+ assert(ret == 0);
+
+ DEBUG("Initializing BWRES\n");
+ ret = frescan_bwres_init(NETWORK);
+ assert(ret == 0);
+
+ DEBUG("Creating contracts\n");
+ for(i=0; i<NUM_CONTRACTS; i++) {
+ contracts_to_neg.size = i + 1;
+ DEBUG("Creating contract %d\n", contracts_to_neg.size);
+ create_contract(&contracts_to_neg.contracts[i]);
+ }
+
+#ifdef ENABLE_MEASURES
+ time_measure_hwtime_set_timestamp(BEGIN_GN_NEG);
+#endif
+
+#ifdef USE_GN
+ DEBUG("Negotiating GN\n");
+ ret = frescan_bwres_group_change_mode_sync(NETWORK, &contracts_to_neg,
+ NULL, NULL, NULL, &ss_new,
+ &accepted);
+ assert(ret == 0);
+ assert(accepted == true);
+#else
+ for(i=0; i<NUM_CONTRACTS; i++) {
+ DEBUG("Negotiating contract %d\n", contracts_to_neg.size);
+ ret = frescan_bwres_negotiate(NETWORK,
+ &contracts_to_neg.contracts[i],
+ &ss_new.ss[i],
+ &accepted);
+ assert(ret == 0);
+ assert(accepted == true);
+ }
+#endif
+
+#ifdef ENABLE_MEASURES
+ time_measure_hwtime_set_timestamp(END_GN_NEG);
+
+ ret = time_measure_hwtime_write_membuffer(BEGIN_GN_NEG);
+ assert(ret == 0);
+
+ ret = time_measure_hwtime_write_membuffer(END_GN_NEG);
+ assert(ret == 0);
+
+ while (logger_manual_call() > 0);
+#endif
+
+ DEBUG("MAIN DONE\n");
+ while(1) sleep(10);
+}
+
+static void create_contract(frsh_contract_t *contract)
+{
+ int ret;
+ frsh_rel_time_t budget_min, period_max;
+
+ ret = frsh_contract_init(contract);
+ assert(ret == 0);
+
+ ret = frescan_fna_network_bytes_to_budget (NETWORK, 10, &budget_min);
+ assert(ret == 0);
+
+ period_max = frsh_msec_to_rel_time(3369); // 3,369 secs
+
+ ret = frsh_contract_set_basic_params
+ (contract,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ assert(ret == 0);
+
+// DEBUG("Setting preemption level manually to the contract\n");
+// ret = frsh_contract_set_preemption_level(contract, 7);
+// assert(ret == 0);
+}
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+
+#include "frescan.h"
+#include "frescan_bwres.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+#define LOCAL_NODE 0
+
+int main ()
+{
+ int ret;
+ frescan_init_params_t init_params;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ printf("Initializing FRESCAN\n");
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("Initializing BWRES\n");
+ ret = frescan_bwres_init(NETWORK);
+ if (ret != 0) PUT_ERROR ("could not init BWRES");
+
+ printf("BWRES Initialized\n");
+
+ while (1) {
+ sleep(1);
+ }
+
+ return 0;
+}
+
+
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+#include <assert.h>
+
+#include "frsh.h"
+#include "frescan.h"
+#include "frescan_types.h"
+#include "frescan_bwres_requests.h"
+#include "frescan_bwres_robjs.h"
+#include "frescan_bwres_fna.h"
+
+#define NETWORK 0
+#define LOCAL_NODE 1
+
+#if 0
+#include <stdio.h>
+#define DEBUG(x,args...) printf("%s: " x, __func__ , ##args)
+#else
+#define DEBUG(x,args...)
+#endif
+
+#include <misc/time_measurement_hwtime.h>
+#include <misc/logger.h>
+static const trace_point_id_t BEGIN_MEASURE = 0;
+static const trace_point_id_t END_MEASURE = 1;
+
+static int frescan_request_to_gn_message
+ (const frescan_bwres_request_data_t *data,
+ uint8_t *msg,
+ size_t *size);
+
+static int frescan_gn_message_to_request(const uint8_t *msg_to_parse,
+ frescan_bwres_request_data_t *data,
+ size_t size);
+
+static void create_contract(frsh_contract_t *contract);
+
+#define FRESCAN_BWRES_MX_MSG_SIZE 5000 // TODO: adjust to the accurate value
+
+int main ()
+{
+ int ret, i, j;
+ frescan_init_params_t init_params;
+ uint8_t msg[FRESCAN_BWRES_MX_MSG_SIZE];
+ size_t size;
+ frescan_bwres_request_data_t *req_in;
+ frescan_bwres_request_id_t req;
+ frescan_send_params_t send_params;
+ frescan_node_t from;
+ frescan_prio_t prio;
+ size_t recv_bytes;
+ frescan_recv_params_t recv_params;
+ frescan_bwres_request_data_t *req_out;
+ uint8_t *msg_to_parse;
+
+ ret = logger_init(LOG_ETHERNET);
+ assert(ret == 0);
+
+ ret = time_measure_hwtime_init(BEGIN_MEASURE, "measure_begin");
+ assert(ret == 0);
+
+ ret = time_measure_hwtime_init(END_MEASURE, "measure_end");
+ assert(ret == 0);
+
+ DEBUG("TEST for FRESCAN messages (NODE: %d)\n", LOCAL_NODE);
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 10;
+ init_params.rx_channel_max_prio = NULL;
+
+ recv_params.net = 0;
+ recv_params.channel = 5;
+ recv_params.flags = FRESCAN_SYNC;
+
+ send_params.net = 0;
+ send_params.to = 1;
+ send_params.channel = 5;
+ send_params.flags = FRESCAN_FP | FRESCAN_ASYNC;;
+ send_params.prio = 3;
+
+ DEBUG("Calling frescan_init\n");
+
+ ret = frescan_init(&init_params);
+ assert(ret == 0);
+
+ ret = frescan_bwres_robjs_init(FRESCAN_BWRES_ROBJS_MX_CEILING);
+ assert(ret == 0);
+
+ ret = frescan_bwres_requests_init(FRESCAN_BWRES_REQ_MX_CEILING);
+ assert(ret == 0);
+
+ if (LOCAL_NODE == 0) {
+ DEBUG("Preparing a GN request\n");
+
+ ret = frescan_bwres_requests_alloc(&req);
+ assert(ret == 0);
+
+ ret = frescan_bwres_requests_get_data(req, &req_in);
+ assert(ret == 0);
+
+ req_in->net = NETWORK;
+ req_in->type = FRESCAN_BWRES_REQ_GN;
+ req_in->req = req;
+ req_in->request_node = LOCAL_NODE;
+
+ for(i=0;i<FRESCAN_BWRES_MAX_GROUP_OPS;i++) {
+ time_measure_hwtime_set_timestamp(BEGIN_MEASURE);
+
+ req_in->contracts_to_neg = &req_in->contracts_to_neg_data;
+
+ req_in->contracts_to_neg->size = i + 1;
+ for(j=0; j<req_in->contracts_to_neg->size; j++) {
+ create_contract(&req_in->contracts_to_neg->contracts[j]);
+ }
+
+ req_in->contracts_to_reneg = &req_in->contracts_to_reneg_data;
+ req_in->contracts_to_reneg->size = 0;
+
+ req_in->ss_to_reneg = &req_in->ss_to_reneg_data;
+ req_in->ss_to_reneg->size = 0;
+
+ req_in->ss_to_cancel = &req_in->ss_to_cancel_data;
+ req_in->ss_to_cancel->size = 0;
+
+ req_in->ss_new = &req_in->ss_new_data;
+ req_in->ss_new->size = 0;
+
+ ret = frescan_bwres_robjs_alloc(&req_in->robj, FRESCAN_BWRES_MX_PRIO);
+ assert(ret == 0);
+
+ ret = frescan_request_to_gn_message(req_in, msg, &size);
+ assert(ret == 0);
+
+ ret = frescan_bwres_robjs_free(req_in->robj);
+ assert(ret == 0);
+
+ frescan_bwres_requests_free(req);
+
+ ret = frescan_send(&send_params, msg, size);
+ assert(ret == 0);
+
+ DEBUG("Receiving reply\n");
+
+ ret = frescan_recv(&recv_params,
+ msg,
+ sizeof(msg),
+ &recv_bytes,
+ &from,
+ &prio);
+ assert(ret == 0);
+
+ DEBUG("Reply received, sleep\n");
+
+ time_measure_hwtime_set_timestamp(END_MEASURE);
+
+ sleep(2);
+ }
+
+ ret = time_measure_hwtime_write_membuffer(BEGIN_MEASURE);
+ assert(ret == 0);
+
+ ret = time_measure_hwtime_write_membuffer(END_MEASURE);
+ assert(ret == 0);
+
+ while (logger_manual_call() > 0);
+ } else {
+ while(1) {
+ DEBUG("Blocking to receive the GN request\n");
+
+ ret = frescan_recv(&recv_params,
+ msg,
+ sizeof(msg),
+ &recv_bytes,
+ &from,
+ &prio);
+ assert(ret == 0);
+
+ ret = frescan_bwres_requests_alloc(&req);
+ assert(ret == 0);
+
+ ret = frescan_bwres_requests_get_data(req, &req_out);
+ assert(ret == 0);
+
+ req_out->type = *((uint8_t *)msg);
+ msg_to_parse = msg + sizeof(uint8_t);
+ recv_bytes = recv_bytes - sizeof(uint8_t);
+
+ ret = frescan_gn_message_to_request(msg_to_parse,
+ req_out,
+ recv_bytes);
+ assert(ret == 0);
+
+ DEBUG("PARSING the GN request\n");
+
+ assert(req_out->type == FRESCAN_BWRES_REQ_GN);
+
+ DEBUG("req: %d\n", req_out->req);
+
+ DEBUG("num new contracts: %d\n", req_out->contracts_to_neg->size);
+
+ DEBUG("send reply\n");
+ send_params.to = from;
+ ret = frescan_send(&send_params, msg, recv_bytes);
+ assert(ret == 0);
+ }
+ }
+
+ DEBUG("TEST OK\n");
+
+ while (1) sleep(1);
+
+ return 0;
+}
+
+/**
+ * FRESCAN_BWRES_REQ_GN (COPY AND PASTE FROM frescan_bwres_messages.c)
+ */
+
+static int frescan_request_to_gn_message
+ (const frescan_bwres_request_data_t *data,
+ uint8_t *msg,
+ size_t *size)
+{
+ int ret, i;
+ uint8_t *msg_begin, *msg_tmp;
+ size_t bytes_written;
+
+ msg_begin = msg;
+
+ // type: FRESCAN_GN_MESSAGE
+ *((uint8_t *)msg) = (uint8_t)FRESCAN_BWRES_REQ_GN;
+ bytes_written = sizeof(uint8_t);
+ msg = msg + bytes_written;
+
+ // req
+ *((frescan_bwres_request_id_t *)msg) = data->req;
+ bytes_written = sizeof(frescan_bwres_request_id_t);
+ msg = msg + bytes_written;
+
+ DEBUG("GN message req:%u\n", data->req);
+
+ // NEG-GROUP
+ DEBUG("NEG-GROUP num contracts:%d\n", data->contracts_to_neg->size);
+
+ *((uint8_t *)msg) = (uint8_t)data->contracts_to_neg->size;
+ bytes_written = sizeof(uint8_t);
+ msg = msg + bytes_written;
+
+ for (i=0; i<data->contracts_to_neg->size; i++) {
+ // reserve 2 bytes for the size of the marshalled contract
+ msg_tmp = msg;
+ msg = msg + sizeof(uint16_t);
+ // marshal the contract
+ ret = frsh_contract_marshal
+ (&data->contracts_to_neg->contracts[i],
+ msg,
+ FRESCAN_BWRES_MX_MSG_SIZE - (msg - msg_begin),
+ &bytes_written);
+ assert(ret == 0);
+
+ // write the size and update the message pointer msg
+ *((uint16_t *)msg_tmp) = (uint16_t)bytes_written;
+ msg = msg + bytes_written;
+
+ DEBUG("contract[%d].size:%u\n", i, bytes_written);
+ }
+
+ // RENEG-GROUP
+ DEBUG("RENEG-GROUP num contracts:%d\n",data->contracts_to_reneg->size);
+
+ *((uint8_t *)msg) = (uint8_t)data->contracts_to_reneg->size;
+ bytes_written = sizeof(uint8_t);
+ msg = msg + bytes_written;
+
+ for (i=0; i<data->contracts_to_reneg->size; i++) {
+ // write the ss
+ *((uint16_t *)msg) = (uint16_t)data->ss_to_reneg->ss[i];
+ bytes_written = sizeof(uint16_t);
+ msg = msg + bytes_written;
+ // reserve 2 bytes for the size of the marshalled contract
+ msg_tmp = msg;
+ msg = msg + sizeof(uint16_t);
+ // marshal the contract
+ ret = frsh_contract_marshal
+ (&data->contracts_to_reneg->contracts[i],
+ msg,
+ FRESCAN_BWRES_MX_MSG_SIZE - (msg - msg_begin),
+ &bytes_written);
+ assert(ret == 0);
+
+ // write the size and update the message pointer msg
+ *((uint16_t *)msg_tmp) = (uint16_t)bytes_written;
+ msg = msg + bytes_written;
+
+ DEBUG("contract[%d].size:%u ss[%d]:%u\n",
+ i, bytes_written, i, data->ss_to_reneg->ss[i]);
+ }
+
+ // CANCEL-GROUP
+ DEBUG("CANCEL-GROUP num ss:%d\n", data->ss_to_cancel->size);
+
+ *((uint8_t *)msg) = (uint8_t)data->ss_to_cancel->size;
+ bytes_written = sizeof(uint8_t);
+ msg = msg + bytes_written;
+
+ for (i=0; i<data->ss_to_cancel->size; i++) {
+ // write the ss
+ *((uint16_t *)msg) = (uint16_t)data->ss_to_cancel->ss[i];
+ bytes_written = sizeof(uint16_t);
+ msg = msg + bytes_written;
+
+ DEBUG("ss[%d]:%u\n", i, data->ss_to_cancel->ss[i]);
+ }
+
+ *size = msg - msg_begin;
+
+ DEBUG("size:%u\n", *size);
+
+ return 0;
+}
+
+static int frescan_gn_message_to_request(const uint8_t *msg_to_parse,
+ frescan_bwres_request_data_t *data,
+ size_t size)
+{
+ int ret, i;
+ uint8_t *msg;
+ size_t bytes_read, contract_size;
+
+ msg = (uint8_t *)msg_to_parse;
+
+ data->contracts_to_neg = &data->contracts_to_neg_data;
+ data->contracts_to_reneg = &data->contracts_to_reneg_data;
+ data->ss_to_reneg = &data->ss_to_reneg_data;
+ data->ss_to_cancel = &data->ss_to_cancel_data;
+ data->ss_new = &data->ss_new_data;
+
+ // req
+ data->req = *((frescan_bwres_request_id_t *)msg);
+ bytes_read = sizeof(frescan_bwres_request_id_t);
+ msg = msg + bytes_read;
+
+ DEBUG("GN message req:%u\n", data->req);
+
+ // NEG-GROUP
+ data->contracts_to_neg->size = *((uint8_t *)msg);
+ bytes_read = sizeof(uint8_t);
+ msg = msg + bytes_read;
+
+ DEBUG("NEG-GROUP num contracts:%u\n", data->contracts_to_neg->size);
+
+ for (i=0; i<data->contracts_to_neg->size; i++) {
+ contract_size = *((uint16_t *)msg);
+ bytes_read = sizeof(uint16_t);
+ msg = msg + bytes_read;
+
+ // unmarshal the contract
+ ret = frsh_contract_unmarshal
+ (&data->contracts_to_neg->contracts[i],
+ msg,
+ contract_size);
+ assert(ret == 0);
+
+ bytes_read = contract_size;
+ msg = msg + bytes_read;
+
+ DEBUG("contract[%d].size:%u\n", i, contract_size);
+ }
+
+ // RENEG-GROUP
+ data->contracts_to_reneg->size = *((uint8_t *)msg);
+ bytes_read = sizeof(uint8_t);
+ msg = msg + bytes_read;
+
+ DEBUG("RENEG-GROUP num contracts:%u\n",data->contracts_to_reneg->size);
+
+ for (i=0; i<data->contracts_to_reneg->size; i++) {
+ data->ss_to_reneg->ss[i] = *((uint16_t *)msg);
+ bytes_read = sizeof(uint16_t);
+ msg = msg + bytes_read;
+
+ contract_size = *((uint16_t *)msg);
+ bytes_read = sizeof(uint16_t);
+ msg = msg + bytes_read;
+
+ // unmarshal the contract
+ ret = frsh_contract_unmarshal
+ (&data->contracts_to_reneg->contracts[i],
+ msg,
+ contract_size);
+ assert(ret == 0);
+
+ bytes_read = contract_size;
+ msg = msg + bytes_read;
+
+ DEBUG("contract[%d].size:%u ss[%d]:%u\n",
+ i, contract_size, i, data->ss_to_reneg->ss[i]);
+ }
+
+ // CANCEL-GROUP
+ data->ss_to_cancel->size = *((uint8_t *)msg);
+ bytes_read = sizeof(uint8_t);
+ msg = msg + bytes_read;
+
+ DEBUG("CANCEL-GROUP num ss:%u\n", data->ss_to_cancel->size);
+
+ for (i=0; i<data->ss_to_cancel->size; i++) {
+ // write the ss
+ data->ss_to_cancel->ss[i] = *((uint16_t *)msg);
+ bytes_read = sizeof(uint16_t);
+ msg = msg + bytes_read;
+
+ DEBUG("ss[%d]:%u\n", i, data->ss_to_cancel->ss[i]);
+ }
+
+ return 0;
+}
+
+extern int frescan_fna_network_bytes_to_budget
+ (const frsh_resource_id_t resource_id,
+ const size_t nbytes,
+ frsh_rel_time_t *budget);
+
+static void create_contract(frsh_contract_t *contract)
+{
+ int ret;
+ frsh_rel_time_t budget_min, period_max;
+
+ DEBUG("Creating contract\n");
+
+ ret = frsh_contract_init(contract);
+ assert(ret == 0);
+
+ ret = frescan_fna_network_bytes_to_budget (NETWORK, 10, &budget_min);
+ assert(ret == 0);
+
+ period_max = frsh_msec_to_rel_time(3369); // 3,369 secs
+
+ ret = frsh_contract_set_basic_params
+ (contract,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ assert(ret == 0);
+
+ DEBUG("Setting preemption level manually to the contract\n");
+ ret = frsh_contract_set_preemption_level(contract, 7);
+ assert(ret == 0);
+}
+
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+
+#include "frsh.h"
+
+#include "frescan.h"
+#include "frescan_bwres.h"
+#include "frescan_servers.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+#define LOCAL_NODE 0
+
+extern int frescan_fna_network_bytes_to_budget
+ (const frsh_resource_id_t resource_id,
+ const size_t nbytes,
+ frsh_rel_time_t *budget);
+
+int main ()
+{
+ int ret;
+ frescan_init_params_t init_params;
+ frescan_ss_t ss;
+ frsh_contract_t contract;
+ bool accepted;
+ frescan_server_params_t server_params;
+ frsh_rel_time_t budget_min, period_max;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 10;
+ init_params.rx_channel_max_prio = NULL;
+
+ printf("Initializing FRESCAN\n");
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("Initializing BWRES\n");
+ ret = frescan_bwres_init(NETWORK);
+ if (ret != 0) PUT_ERROR ("could not init BWRES");
+
+ printf("Creating contract\n");
+
+ ret = frsh_contract_init(&contract);
+ if (ret != 0) PUT_ERROR ("could not init contract");
+
+ ret = frescan_fna_network_bytes_to_budget (NETWORK, 10, &budget_min);
+ if (ret != 0) PUT_ERROR ("could not transform bytes to budget");
+
+ period_max = frsh_msec_to_rel_time(3369); // 3,369 secs
+
+ ret = frsh_contract_set_basic_params
+ (&contract,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ if (ret != 0) PUT_ERROR ("could not set basic params");
+
+#if !FRSH_AUTOMATIC_PRIO_ASSIGN_ENABLE
+ printf("Setting preemption level manually to the contract\n");
+ ret = frsh_contract_set_preemption_level(&contract, 7);
+ if (ret != 0) PUT_ERROR ("could not set preemption level");
+#endif
+
+ printf("Negotiating contract\n");
+
+ ret = frescan_bwres_negotiate(NETWORK, &contract, &ss, &accepted);
+ if (ret != 0) PUT_ERROR ("could not negotiate");
+
+ if (accepted) {
+ printf("The contract was accepted, ss:%u\n", ss);
+ ret = frescan_servers_get_data(NETWORK, &server_params, ss);
+ if (ret != 0) PUT_ERROR ("could not get servers data");
+
+ printf("B:%u, T=(%u,%u), P:%u\n",
+ server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+ } else {
+ printf("The contract was not accepted\n");
+ }
+
+ while (1) {
+ sleep(1);
+ }
+
+ return 0;
+}
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+#include <assert.h>
+
+#include "frsh.h"
+
+#include "frescan.h"
+#include "frescan_bwres.h"
+#include "frescan_servers.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+#define LOCAL_NODE 0
+
+// #define ENABLE_LOGGING
+#ifdef ENABLE_LOGGING
+#include <drivers/console_switcher.h>
+#include <misc/logger.h>
+#include <assert.h>
+#define LOG_DEVICE LOG_ETHERNET
+#endif
+
+extern int frescan_fna_network_bytes_to_budget
+ (const frsh_resource_id_t resource_id,
+ const size_t nbytes,
+ frsh_rel_time_t *budget);
+
+int main ()
+{
+ int ret;
+ frescan_init_params_t init_params;
+ frescan_ss_t ss;
+ frsh_contract_t contract;
+ frescan_server_params_t server_params;
+ bool accepted;
+ frsh_rel_time_t budget_min, period_max;
+
+#ifdef ENABLE_LOGGING
+ ret = logger_init(LOG_DEVICE);
+ assert(ret == 0);
+
+ printf("Changing to membuffer console\n");
+ MEMBUFFER_CONSOLE_INIT();
+#endif
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 10;
+ init_params.rx_channel_max_prio = NULL;
+
+ printf("Initializing FRESCAN\n");
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("Initializing BWRES\n");
+ ret = frescan_bwres_init(NETWORK);
+ if (ret != 0) PUT_ERROR ("could not init BWRES");
+
+
+ ret = frsh_contract_init(&contract);
+ assert(ret == 0);
+
+ ret = frsh_network_bytes_to_budget(FRSH_NETWORK_ID_DEFAULT,
+ 8*10,
+ &budget_min);
+ assert(ret == 0);
+
+ period_max.tv_sec = 1; period_max.tv_nsec = 0;
+
+ ret = frsh_contract_set_basic_params(&contract,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ assert(ret == 0);
+
+ ret = frsh_contract_set_preemption_level(&contract, 5);
+ assert(ret == 0);
+
+ ret = frescan_bwres_negotiate(NETWORK, &contract, &ss, &accepted);
+ if (ret != 0) PUT_ERROR ("could not negotiate succesfully");
+
+ ret = frescan_bwres_negotiate(NETWORK, &contract, &ss, &accepted);
+ if (ret != 0) PUT_ERROR ("could not negotiate succesfully");
+
+
+ ret = frsh_contract_init(&contract);
+ if (ret != 0) PUT_ERROR ("could not init contract");
+
+ ret = frescan_fna_network_bytes_to_budget (NETWORK, 8*1, &budget_min);
+ if (ret != 0) PUT_ERROR ("could not transform bytes to budget");
+
+ period_max = frsh_msec_to_rel_time(2);
+
+ ret = frsh_contract_set_basic_params
+ (&contract,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ if (ret != 0) PUT_ERROR ("could not set basic params");
+
+ ret = frsh_contract_set_preemption_level(&contract, 8);
+ if (ret != 0) PUT_ERROR ("could not set preemption level");
+
+ printf("Negotiating a contract\n");
+ ret = frescan_bwres_negotiate(NETWORK, &contract, &ss, &accepted);
+ if (ret != 0) PUT_ERROR ("could not negotiate succesfully");
+
+ if (accepted) {
+ printf("The contract was accepted, ss:%u\n", ss);
+ ret = frescan_servers_get_data(NETWORK, &server_params, ss);
+ if (ret != 0) PUT_ERROR ("could not get servers data");
+
+ printf("B:%u, T=(%u,%u), P:%u\n",
+ server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+ } else {
+ printf("The contract was not accepted\n");
+ }
+
+ printf("MAIN DONE\n");
+
+#ifdef ENABLE_LOGGING
+ while (logger_manual_call() > 0);
+#endif
+
+ while (1) sleep(1);
+ return 0;
+}
+
+
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+
+#include "frsh.h"
+
+#include "frescan.h"
+#include "frescan_bwres.h"
+#include "frescan_servers.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+#define LOCAL_NODE 1
+
+extern int frescan_fna_network_bytes_to_budget
+ (const frsh_resource_id_t resource_id,
+ const size_t nbytes,
+ frsh_rel_time_t *budget);
+
+int main ()
+{
+ int ret;
+ frescan_init_params_t init_params;
+ frescan_ss_t ss;
+ frsh_contract_t contract;
+ frescan_server_params_t server_params;
+ bool accepted;
+ frsh_rel_time_t budget_min, period_max;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 10;
+ init_params.rx_channel_max_prio = NULL;
+
+ printf("Initializing FRESCAN\n");
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("Initializing BWRES\n");
+ ret = frescan_bwres_init(NETWORK);
+ if (ret != 0) PUT_ERROR ("could not init BWRES");
+
+ ret = frsh_contract_init(&contract);
+ if (ret != 0) PUT_ERROR ("could not init contract");
+
+ ret = frescan_fna_network_bytes_to_budget (NETWORK, 10, &budget_min);
+ if (ret != 0) PUT_ERROR ("could not transform bytes to budget");
+
+ period_max = frsh_msec_to_rel_time(3369); // 3,369 secs
+
+ ret = frsh_contract_set_basic_params
+ (&contract,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ if (ret != 0) PUT_ERROR ("could not set basic params");
+
+#if !FRSH_AUTOMATIC_PRIO_ASSIGN_ENABLE
+ ret = frsh_contract_set_preemption_level(&contract, 5);
+ if (ret != 0) PUT_ERROR ("could not set preemption level");
+#endif
+
+ printf("Negotiating a contract\n");
+ ret = frescan_bwres_negotiate(NETWORK, &contract, &ss, &accepted);
+ if (ret != 0) PUT_ERROR ("could not negotiate succesfully");
+
+ if (accepted) {
+ printf("The contract was accepted, ss:%u\n", ss);
+ ret = frescan_servers_get_data(NETWORK, &server_params, ss);
+ if (ret != 0) PUT_ERROR ("could not get servers data");
+
+ printf("B:%u, T=(%u,%u), P:%u\n",
+ server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+ } else {
+ printf("The contract was not accepted\n");
+ }
+
+ while (1) {
+ sleep(1);
+ }
+
+ return 0;
+}
+
+
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+
+#include "frsh.h"
+
+#include "frescan.h"
+#include "frescan_bwres.h"
+#include "frescan_servers.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+#define LOCAL_NODE 1
+
+// #define ENABLE_LOGGING
+#ifdef ENABLE_LOGGING
+#include <drivers/console_switcher.h>
+#include <misc/logger.h>
+#include <assert.h>
+#define LOG_DEVICE LOG_ETHERNET
+#endif
+
+extern int frescan_fna_network_bytes_to_budget
+ (const frsh_resource_id_t resource_id,
+ const size_t nbytes,
+ frsh_rel_time_t *budget);
+
+int main ()
+{
+ int ret;
+ frescan_init_params_t init_params;
+ frescan_ss_t ss;
+ frsh_contract_t contract;
+ frescan_server_params_t server_params;
+ bool accepted;
+ frsh_rel_time_t budget_min, period_max;
+
+#ifdef ENABLE_LOGGING
+ ret = logger_init(LOG_DEVICE);
+ assert(ret == 0);
+
+ printf("Changing to membuffer console\n");
+ MEMBUFFER_CONSOLE_INIT();
+#endif
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 10;
+ init_params.rx_channel_max_prio = NULL;
+
+ printf("Initializing FRESCAN\n");
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("Initializing BWRES\n");
+ ret = frescan_bwres_init(NETWORK);
+ if (ret != 0) PUT_ERROR ("could not init BWRES");
+
+ ret = frsh_contract_init(&contract);
+ if (ret != 0) PUT_ERROR ("could not init contract");
+
+ ret = frescan_fna_network_bytes_to_budget (NETWORK, 8*5, &budget_min);
+ if (ret != 0) PUT_ERROR ("could not transform bytes to budget");
+
+ period_max = frsh_msec_to_rel_time(1);
+
+ ret = frsh_contract_set_basic_params
+ (&contract,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ if (ret != 0) PUT_ERROR ("could not set basic params");
+
+ ret = frsh_contract_set_preemption_level(&contract, 6);
+ if (ret != 0) PUT_ERROR ("could not set preemption level");
+
+ printf("Negotiating a contract\n");
+ ret = frescan_bwres_negotiate(NETWORK, &contract, &ss, &accepted);
+ if (ret != 0) PUT_ERROR ("could not negotiate succesfully");
+
+ if (accepted) {
+ printf("The contract was accepted, ss:%u\n", ss);
+ ret = frescan_servers_get_data(NETWORK, &server_params, ss);
+ if (ret != 0) PUT_ERROR ("could not get servers data");
+
+ printf("B:%u, T=(%u,%u), P:%u\n",
+ server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+ } else {
+ printf("The contract was not accepted\n");
+ }
+
+ printf("MAIN DONE\n");
+
+#ifdef ENABLE_LOGGING
+ while (logger_manual_call() > 0);
+#endif
+
+ while (1) sleep(1);
+ return 0;
+}
+
+
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+
+#include "frsh.h"
+
+#include "frescan.h"
+#include "frescan_bwres.h"
+#include "frescan_servers.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+#define LOCAL_NODE 1
+
+extern int frescan_fna_network_bytes_to_budget
+ (const frsh_resource_id_t resource_id,
+ const size_t nbytes,
+ frsh_rel_time_t *budget);
+
+int main ()
+{
+ int ret;
+ frescan_init_params_t init_params;
+ frescan_ss_t ss_sc;
+ frsh_contract_t contract_sc;
+ frescan_server_params_t server_params;
+ bool accepted;
+ frsh_rel_time_t budget_min, budget_max, period_max, period_min;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 10;
+ init_params.rx_channel_max_prio = NULL;
+
+ printf("Initializing FRESCAN\n");
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("Initializing BWRES\n");
+ ret = frescan_bwres_init(NETWORK);
+ if (ret != 0) PUT_ERROR ("could not init BWRES");
+
+ printf("Create a contract with spare capacity\n");
+
+ ret = frsh_contract_init(&contract_sc);
+ if (ret != 0) PUT_ERROR ("could not init contract");
+
+ ret = frescan_fna_network_bytes_to_budget (NETWORK, 8*1, &budget_min);
+ if (ret != 0) PUT_ERROR ("could not transform bytes to budget");
+
+ ret = frescan_fna_network_bytes_to_budget (NETWORK, 8*5, &budget_max);
+ if (ret != 0) PUT_ERROR ("could not transform bytes to budget");
+
+ period_max = frsh_msec_to_rel_time(1); // 3,369 secs
+ period_min = period_max;
+
+ ret = frsh_contract_set_basic_params
+ (&contract_sc,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ if (ret != 0) PUT_ERROR ("could not set basic params");
+
+ ret = frsh_contract_set_preemption_level
+ (&contract_sc, FRESCAN_BWRES_NEG_MSG_PRIO + 1);
+ if (ret != 0) PUT_ERROR ("could not set preemption level");
+
+ ret = frsh_contract_set_reclamation_params(&contract_sc,
+ 0,
+ &budget_max,
+ &period_min,
+ FRSH_GR_CONTINUOUS,
+ NULL,
+ 1,
+ 1);
+ if (ret != 0) PUT_ERROR ("could not set reclamation params");
+
+ printf("Negotiating a contract\n");
+ ret = frescan_bwres_negotiate(NETWORK, &contract_sc, &ss_sc, &accepted);
+ if (ret != 0) PUT_ERROR ("could not negotiate succesfully");
+
+ if (accepted) {
+ printf("The contract was accepted, ss_sc:%u\n", ss_sc);
+ ret = frescan_servers_get_data(NETWORK, &server_params, ss_sc);
+ if (ret != 0) PUT_ERROR ("could not get servers data");
+
+ printf("B:%u, T=(%u,%u), P:%u\n",
+ server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+ } else {
+ printf("The contract was not accepted\n");
+ }
+
+ while (1) sleep(1);
+
+ return 0;
+}
+
+
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+
+#include "frsh.h"
+
+#include "frescan.h"
+#include "frescan_bwres.h"
+#include "frescan_servers.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+#define LOCAL_NODE 1
+
+extern int frescan_fna_network_bytes_to_budget
+ (const frsh_resource_id_t resource_id,
+ const size_t nbytes,
+ frsh_rel_time_t *budget);
+
+int main ()
+{
+ int ret;
+ frescan_init_params_t init_params;
+ frescan_ss_t ss_sc, ss_no_sc;
+ frsh_contract_t contract_sc, contract_no_sc;
+ frescan_server_params_t server_params;
+ bool accepted;
+ frsh_rel_time_t budget_min, budget_max, period_max, period_min;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 10;
+ init_params.rx_channel_max_prio = NULL;
+
+ printf("Initializing FRESCAN\n");
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("Initializing BWRES\n");
+ ret = frescan_bwres_init(NETWORK);
+ if (ret != 0) PUT_ERROR ("could not init BWRES");
+
+ printf("Create a contract with spare capacity\n");
+
+ ret = frsh_contract_init(&contract_sc);
+ if (ret != 0) PUT_ERROR ("could not init contract");
+
+ ret = frescan_fna_network_bytes_to_budget (NETWORK, 8*1, &budget_min);
+ if (ret != 0) PUT_ERROR ("could not transform bytes to budget");
+
+ ret = frescan_fna_network_bytes_to_budget (NETWORK, 8*5, &budget_max);
+ if (ret != 0) PUT_ERROR ("could not transform bytes to budget");
+
+ period_max = frsh_msec_to_rel_time(1); // 3,369 secs
+ period_min = period_max;
+
+ ret = frsh_contract_set_basic_params
+ (&contract_sc,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ if (ret != 0) PUT_ERROR ("could not set basic params");
+
+ ret = frsh_contract_set_preemption_level
+ (&contract_sc, FRESCAN_BWRES_NEG_MSG_PRIO + 1);
+ if (ret != 0) PUT_ERROR ("could not set preemption level");
+
+ ret = frsh_contract_set_reclamation_params(&contract_sc,
+ 0,
+ &budget_max,
+ &period_min,
+ FRSH_GR_CONTINUOUS,
+ NULL,
+ 1,
+ 1);
+ if (ret != 0) PUT_ERROR ("could not set reclamation params");
+
+ printf("Negotiating a contract\n");
+ ret = frescan_bwres_negotiate(NETWORK, &contract_sc, &ss_sc, &accepted);
+ if (ret != 0) PUT_ERROR ("could not negotiate succesfully");
+
+ if (accepted) {
+ printf("The contract was accepted, ss_sc:%u\n", ss_sc);
+ ret = frescan_servers_get_data(NETWORK, &server_params, ss_sc);
+ if (ret != 0) PUT_ERROR ("could not get servers data");
+
+ printf("B:%u, T=(%u,%u), P:%u\n",
+ server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+ } else {
+ printf("The contract was not accepted\n");
+ }
+
+ printf("Create a contract without spare capacity\n");
+
+ ret = frsh_contract_init(&contract_no_sc);
+ if (ret != 0) PUT_ERROR ("could not init contract");
+
+ ret = frescan_fna_network_bytes_to_budget (NETWORK, 8*2, &budget_min);
+ if (ret != 0) PUT_ERROR ("could not transform bytes to budget");
+
+ ret = frsh_contract_set_basic_params
+ (&contract_no_sc,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ if (ret != 0) PUT_ERROR ("could not set basic params");
+
+ ret = frsh_contract_set_preemption_level
+ (&contract_no_sc, FRESCAN_BWRES_NEG_MSG_PRIO + 2);
+ if (ret != 0) PUT_ERROR ("could not set preemption level");
+
+ printf("Negotiating non sc contract\n");
+ ret = frescan_bwres_negotiate(NETWORK, &contract_no_sc,
+ &ss_no_sc, &accepted);
+ if (ret != 0) PUT_ERROR ("could not negotiate succesfully");
+
+ if (accepted) {
+ printf("The contract was accepted, ss_no_sc:%u\n", ss_no_sc);
+ ret = frescan_servers_get_data(NETWORK,
+ &server_params, ss_no_sc);
+ if (ret != 0) PUT_ERROR ("could not get servers data");
+
+ printf("B:%u, T=(%u,%u), P:%u\n",
+ server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+ } else {
+ printf("The contract was not accepted\n");
+ }
+
+ printf("Get params from sc vres\n");
+
+ ret = frescan_servers_get_data(NETWORK,
+ &server_params, ss_sc);
+ if (ret != 0) PUT_ERROR ("could not get servers data");
+
+ printf("B:%u, T=(%u,%u), P:%u\n",
+ server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+
+ printf("MAIN DONE\n");
+ while (1) sleep(1);
+
+ return 0;
+}
+
+
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+
+#include "frsh.h"
+
+#include "frescan.h"
+#include "frescan_bwres.h"
+#include "frescan_servers.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+#define LOCAL_NODE 0
+
+int main ()
+{
+ int ret;
+ frescan_init_params_t init_params;
+ frescan_ss_t ss;
+ frsh_contract_t contract;
+ bool accepted;
+ frescan_server_params_t server_params;
+ frsh_rel_time_t budget_min, period_max;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 10;
+ init_params.rx_channel_max_prio = NULL;
+
+ printf("Initializing FRESCAN\n");
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("Initializing BWRES\n");
+ ret = frescan_bwres_init(NETWORK);
+ if (ret != 0) PUT_ERROR ("could not init BWRES");
+
+ ret = frsh_contract_init(&contract);
+ if (ret != 0) PUT_ERROR ("could not init contract");
+
+ budget_min.tv_sec = 5;
+ period_max = frsh_msec_to_rel_time(3369);
+
+ ret = frsh_contract_set_basic_params
+ (&contract,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ if (ret != 0) PUT_ERROR ("could not set basic params");
+
+#if !FRSH_AUTOMATIC_PRIO_ASSIGN_ENABLE
+ ret = frsh_contract_set_preemption_level(&contract, 7);
+ if (ret != 0) PUT_ERROR ("could not set preemption level");
+#endif
+
+ ret = frescan_bwres_negotiate(NETWORK, &contract, &ss, &accepted);
+ if (ret != 0) PUT_ERROR ("could not negotiate");
+
+ if (accepted) {
+ printf("The contract was accepted, ss:%u\n", ss);
+ ret = frescan_servers_get_data(NETWORK, &server_params, ss);
+ if (ret != 0) PUT_ERROR ("could not get servers data");
+
+ printf("B:%u, T=(%u,%u), P:%u\n",
+ server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+ } else {
+ printf("The contract was not accepted\n");
+ }
+
+ printf("Renegotiate the contract in 2 seconds\n");
+ sleep(2);
+
+ budget_min.tv_sec = 7;
+ period_max = frsh_msec_to_rel_time(2450);
+
+ ret = frsh_contract_set_basic_params
+ (&contract,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ if (ret != 0) PUT_ERROR ("could not set basic params");
+
+#if !FRSH_AUTOMATIC_PRIO_ASSIGN_ENABLE
+ ret = frsh_contract_set_preemption_level(&contract, 8);
+ if (ret != 0) PUT_ERROR ("could not set preemption level");
+#endif
+
+ ret = frescan_bwres_renegotiate(NETWORK, &contract, ss, &accepted);
+ if (ret != 0) PUT_ERROR ("could not renegotiate");
+
+ if (accepted) {
+ printf("The contract renegotiation was accepted, ss:%u\n", ss);
+ ret = frescan_servers_get_data(NETWORK, &server_params, ss);
+ if (ret != 0) PUT_ERROR ("could not get servers data");
+
+ printf("B:%u, T=(%u,%u), P:%u\n",
+ server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+ } else {
+ printf("The contract was not accepted\n");
+ }
+
+
+ while (1) {
+ sleep(1);
+ }
+
+ return 0;
+}
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+
+#include "frsh.h"
+
+#include "frescan.h"
+#include "frescan_bwres.h"
+#include "frescan_servers.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+#define LOCAL_NODE 1
+
+int main ()
+{
+ int ret;
+ frescan_init_params_t init_params;
+ frescan_ss_t ss;
+ frsh_contract_t contract;
+ frescan_server_params_t server_params;
+ bool accepted;
+ frsh_rel_time_t budget_min, period_max;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 10;
+ init_params.rx_channel_max_prio = NULL;
+
+ printf("Initializing FRESCAN\n");
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("Initializing BWRES\n");
+ ret = frescan_bwres_init(NETWORK);
+ if (ret != 0) PUT_ERROR ("could not init BWRES");
+
+ ret = frsh_contract_init(&contract);
+ if (ret != 0) PUT_ERROR ("could not init contract");
+
+ budget_min.tv_sec = 5;
+ period_max = frsh_msec_to_rel_time(3369);
+
+ ret = frsh_contract_set_basic_params
+ (&contract,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ if (ret != 0) PUT_ERROR ("could not set basic params");
+
+#if !FRSH_AUTOMATIC_PRIO_ASSIGN_ENABLE
+ ret = frsh_contract_set_preemption_level(&contract, 5);
+ if (ret != 0) PUT_ERROR ("could not set preemption level");
+#endif
+
+ printf("Negotiating a contract\n");
+ ret = frescan_bwres_negotiate(NETWORK, &contract, &ss, &accepted);
+ if (ret != 0) PUT_ERROR ("could not negotiate succesfully");
+
+ if (accepted) {
+ printf("The contract was accepted, ss:%u\n", ss);
+ ret = frescan_servers_get_data(NETWORK, &server_params, ss);
+ if (ret != 0) PUT_ERROR ("could not get servers data");
+
+ printf("B:%u, T=(%u,%u), P:%u\n",
+ server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+ } else {
+ printf("The contract was not accepted\n");
+ }
+
+ printf("Renegotiate the contract in 2 seconds\n");
+ sleep(2);
+
+ budget_min.tv_sec = 2;
+ period_max = frsh_msec_to_rel_time(6430);
+
+ ret = frsh_contract_set_basic_params
+ (&contract,
+ &budget_min,
+ &period_max,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ if (ret != 0) PUT_ERROR ("could not set basic params");
+
+#if !FRSH_AUTOMATIC_PRIO_ASSIGN_ENABLE
+ ret = frsh_contract_set_preemption_level(&contract, 2);
+ if (ret != 0) PUT_ERROR ("could not set preemption level");
+#endif
+
+ ret = frescan_bwres_renegotiate(NETWORK, &contract, ss, &accepted);
+ if (ret != 0) PUT_ERROR ("could not renegotiate");
+
+ if (accepted) {
+ printf("The contract renegotiation was accepted, ss:%u\n", ss);
+ ret = frescan_servers_get_data(NETWORK, &server_params, ss);
+ if (ret != 0) PUT_ERROR ("could not get servers data");
+
+ printf("B:%u, T=(%u,%u), P:%u\n",
+ server_params.budget,
+ server_params.period.tv_sec,
+ server_params.period.tv_nsec,
+ server_params.prio);
+ } else {
+ printf("The contract was not accepted\n");
+ }
+
+ while (1) {
+ sleep(1);
+ }
+
+ return 0;
+}
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+/*!
+ * @file test_frescan_bwres_robjs_timedwait.c
+ *
+ * @brief test for the basic behaviour of timedwait
+ *
+ * @version 0.01
+ *
+ * @date 1-Apr-2008
+ *
+ * @author
+ * Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @comments
+ *
+ * This file contains a basic test for the frescan_reply_objects module.
+ * The main thread allocates a reply object, creates a thread and waits
+ * on the reply object until the thread signals it. Then it waits again, but
+ * as the thread only signals the reply one time, this tima a timeout will be
+ * produced.
+ *
+ * @license
+ *
+ * See the COPYING file in the FNA's root directory
+ *
+ */
+
+#include <stdio.h> /* for printf */
+#include <assert.h> /* for assert */
+#include <unistd.h> /* for sleep */
+#include "fosa_threads_and_signals.h" /* for fosa_thread_xxx */
+#include "fosa_clocks_and_timers.h" /* for fosa_clock_get_time */
+#include "frescan_bwres_robjs.h"
+
+#define CEILING 10
+
+static void *thread_code(void *arg);
+
+int main()
+{
+ int err;
+ frescan_bwres_robj_id_t id;
+ fosa_thread_attr_t th_attr;
+ fosa_thread_id_t tid;
+ struct timespec now;
+
+ printf("TEST REPLY OBJECTS\n");
+
+ err = fosa_thread_set_prio(fosa_thread_self(), CEILING - 2);
+ assert(err == 0);
+
+ err = frescan_bwres_robjs_init(CEILING);
+ assert(err == 0);
+
+ err = frescan_bwres_robjs_alloc(&id, CEILING);
+ assert(err == 0);
+
+ err = fosa_thread_attr_init(&th_attr);
+ assert(err == 0);
+
+ err = fosa_thread_attr_set_prio(&th_attr, CEILING - 1);
+ assert(err == 0);
+
+ err = fosa_thread_create (&tid, &th_attr, thread_code, (void *) id);
+ assert(err == 0);
+
+ err = fosa_thread_attr_destroy(&th_attr);
+ assert(err == 0);
+
+ err = fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &now);
+ assert(err == 0);
+
+ printf("wait: %d sec %d nsec\n", now.tv_sec, now.tv_nsec);
+
+ now.tv_sec = now.tv_sec + 2;
+ err = frescan_bwres_robjs_timedwait(id, &now);
+ assert (err == 0);
+
+ err = fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &now);
+ assert(err == 0);
+
+ printf("wait again: %d sec %d nsec\n", now.tv_sec, now.tv_nsec);
+
+ now.tv_sec = now.tv_sec + 2;
+ err = frescan_bwres_robjs_timedwait(id, &now);
+ assert (err == FRESCAN_ETIMEDOUT);
+
+ printf("timeout!: %d sec %d nsec\n", now.tv_sec, now.tv_nsec);
+
+ err = frescan_bwres_robjs_free(id);
+ assert(err == 0);
+
+ printf("TEST [OK!]\n");
+
+ return 0;
+}
+
+static void *thread_code(void *arg)
+{
+ int err;
+ frescan_bwres_robj_id_t reply = (frescan_bwres_robj_id_t)arg;
+
+ printf("Thread signaling\n");
+ err = frescan_bwres_robjs_signal(reply);
+ assert(err == 0);
+
+ printf("Thread terminating\n");
+ return NULL;
+}
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+/*!
+ * @file test_frescan_bwres_robjs_wait.c
+ *
+ * @brief test for the basic behaviour of reply objects
+ *
+ * @version 0.01
+ *
+ * @date 1-Apr-2008
+ *
+ * @author
+ * Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @comments
+ *
+ * This file contains a basic test for the frescan_bwres_robjs module.
+ * The main thread allocates a reply object, creates a thread and waits
+ * on the reply object until the thread signals it.
+ *
+ * @license
+ *
+ * See the COPYING file in the FNA's root directory
+ *
+ */
+
+#include <stdio.h> /* for printf */
+#include <assert.h> /* for assert */
+#include <unistd.h> /* for sleep */
+#include "fosa_threads_and_signals.h" /* for fosa_thread_xxx */
+#include "frescan_bwres_robjs.h"
+
+#define CEILING 10
+
+static void *thread_code(void *arg);
+
+int main()
+{
+ int err;
+ frescan_bwres_robj_id_t id;
+ fosa_thread_attr_t th_attr;
+ fosa_thread_id_t tid;
+
+ printf("TEST REPLY OBJECTS\n");
+
+ err = fosa_thread_set_prio(fosa_thread_self(), CEILING - 1);
+ assert(err == 0);
+
+ err = frescan_bwres_robjs_init(CEILING);
+ assert(err == 0);
+
+ err = frescan_bwres_robjs_alloc(&id, CEILING);
+ assert(err == 0);
+
+ err = fosa_thread_attr_init(&th_attr);
+ assert(err == 0);
+
+ err = fosa_thread_attr_set_prio(&th_attr, CEILING - 1);
+ assert(err == 0);
+
+ err = fosa_thread_create (&tid, &th_attr, thread_code, (void *) id);
+ assert(err == 0);
+
+ err = fosa_thread_attr_destroy(&th_attr);
+ assert(err == 0);
+
+ err = frescan_bwres_robjs_wait(id);
+ assert(err == 0);
+ printf("signal received\n");
+
+ err = frescan_bwres_robjs_free(id);
+ assert(err == 0);
+
+ printf("TEST [OK!]\n");
+
+ return 0;
+}
+
+static void *thread_code(void *arg)
+{
+ int err;
+ frescan_bwres_robj_id_t reply = (frescan_bwres_robj_id_t)arg;
+
+ printf("Thread executing\n");
+ sleep(2);
+
+ printf("Thread signaling\n");
+ err = frescan_bwres_robjs_signal(reply);
+ assert(err == 0);
+
+ printf("Thread terminating\n");
+ return NULL;
+}
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+
+#include "frescan.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+
+// #define SENDER
+// #define ENABLE_LOGGING
+
+#ifdef SENDER
+
+#define LOCAL_NODE 1
+
+#ifdef ENABLE_LOGGING
+
+#include <drivers/console_switcher.h>
+#include <misc/logger.h>
+#include <assert.h>
+#define LOG_DEVICE LOG_ETHERNET
+
+#endif
+
+static void pause(){
+ char key;
+ printf(" press Enter...");
+ key = getchar();
+}
+
+int main ()
+{
+ int i, ret;
+ frescan_send_params_t params;
+ char msg[200];
+ int written;
+ frescan_init_params_t init_params;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+#ifdef ENABLE_LOGGING
+
+ ret = logger_init(LOG_DEVICE);
+ assert(ret == 0);
+
+ printf("Changing to membuffer console\n");
+ MEMBUFFER_CONSOLE_INIT();
+
+#endif
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("FRESCAN initialized (local node: %u)\n", LOCAL_NODE);
+
+ params.net = NETWORK;
+ params.to = 0;
+ params.channel = 0;
+ params.flags = FRESCAN_FP | FRESCAN_ASYNC;
+ params.prio = 7;
+
+ while(1) {
+ pause();
+ for (i=0; i<=2; i++) {
+ written = snprintf(msg, sizeof(msg), "his number is... %d", i);
+ ret = frescan_send(¶ms, (uint8_t *)msg, written);
+ if (ret != 0) PUT_ERROR ("could not send message\n");
+ printf("SENT: %d\n", i);
+ }
+#ifdef ENABLE_LOGGING
+ while (logger_manual_call() > 0);
+#endif
+ }
+
+ return 0;
+}
+
+#else
+
+#define LOCAL_NODE 0
+
+int main ()
+{
+ int ret;
+ frescan_recv_params_t params;
+ uint8_t msg[3000];
+ size_t recv_bytes;
+ frescan_node_t from;
+ frescan_init_params_t init_params;
+ frescan_prio_t prio;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("FRESCAN initialized (local node: %u)\n", LOCAL_NODE);
+
+ params.net = NETWORK;
+ params.channel = 0;
+ params.flags = FRESCAN_SYNC;
+
+ while (1) {
+ printf("RECEIVING...\n");
+ ret = frescan_recv(¶ms, (uint8_t *)msg, sizeof(msg),
+ &recv_bytes, &from, &prio);
+ if (ret != 0) PUT_ERROR ("could not send message");
+
+ msg[recv_bytes] = '\0';
+ printf("RECEIVED: %s with prio:%u from:%u\n", msg, prio, from);
+
+// for (i=0; i<recv_bytes; i++) {
+// printf("msg[%d] = 0x%X;\n", i, msg[i]);
+// }
+ }
+
+ return 0;
+}
+
+#endif
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <time.h>
+#include "frescan.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+
+#define SENDER
+// #define ENABLE_LOGGING
+#define ENABLE_PARALLEL_PORT_TRACER
+
+#ifdef ENABLE_PARALLEL_PORT_TRACER
+#include <sys/pio.h>
+#define PP_BASE_REG 0x378
+#define PP_DATA_REG 0 // Data port offset
+#endif
+
+#if 0
+#include <stdio.h>
+#define DEBUG(x,args...) printf("%s: " x, __func__ , ##args)
+#else
+#define DEBUG(x,args...)
+#endif
+
+#ifdef SENDER
+
+#define LOCAL_NODE 1
+
+#ifdef ENABLE_LOGGING
+
+#include <drivers/console_switcher.h>
+#include <misc/logger.h>
+#include <assert.h>
+#define LOG_DEVICE LOG_ETHERNET
+
+#endif
+
+int main ()
+{
+ int i, ret;
+ frescan_send_params_t params;
+ char msg[200];
+ int written;
+ frescan_init_params_t init_params;
+ struct timespec my_period, next_activation;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+#ifdef ENABLE_LOGGING
+ ret = logger_init(LOG_DEVICE);
+ assert(ret == 0);
+
+ DEBUG("Changing to membuffer console\n");
+ MEMBUFFER_CONSOLE_INIT();
+#endif
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ DEBUG("FRESCAN initialized (local node: %u)\n", LOCAL_NODE);
+
+ params.net = NETWORK;
+ params.to = 0;
+ params.channel = 0;
+ params.flags = FRESCAN_FP | FRESCAN_ASYNC;
+ params.prio = 7;
+
+ my_period.tv_sec = 0;
+ my_period.tv_nsec = 100000000;
+
+ outb_p (PP_BASE_REG + PP_DATA_REG, 0x00);
+
+ for(i=0; 1; i++) {
+ incr_timespec (next_activation, my_period); // the fosa one
+ clock_nanosleep(CLOCK_MONOTONIC,
+ TIMER_ABSTIME,
+ &next_activation, NULL);
+
+ written = snprintf(msg, sizeof(msg), "his number is... %d", i);
+#ifdef ENABLE_PARALLEL_PORT_TRACER
+ outb_p (PP_BASE_REG + PP_DATA_REG, 0xFF);
+#endif
+ ret = frescan_send(¶ms, (uint8_t *)msg, 32);
+ if (ret != 0) PUT_ERROR ("could not send message\n");
+
+#ifdef ENABLE_PARALLEL_PORT_TRACER
+ outb_p (PP_BASE_REG + PP_DATA_REG, 0x00);
+#endif
+ DEBUG("SENT: %d\n", i);
+#ifdef ENABLE_LOGGING
+ while (logger_manual_call() > 0);
+#endif
+ }
+
+ return 0;
+}
+
+#else
+
+#define LOCAL_NODE 0
+
+int main ()
+{
+ int ret;
+ frescan_recv_params_t params;
+ uint8_t msg[3000];
+ size_t recv_bytes;
+ frescan_node_t from;
+ frescan_init_params_t init_params;
+ frescan_prio_t prio;
+ struct timespec pulse_width = {0, 100000};
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ DEBUG("FRESCAN initialized (local node: %u)\n", LOCAL_NODE);
+
+ params.net = NETWORK;
+ params.channel = 0;
+ params.flags = FRESCAN_SYNC;
+
+ outb_p (PP_BASE_REG + PP_DATA_REG, 0x00);
+
+ while (1) {
+ DEBUG("RECEIVING...\n");
+ ret = frescan_recv(¶ms, (uint8_t *)msg, sizeof(msg),
+ &recv_bytes, &from, &prio);
+ if (ret != 0) PUT_ERROR ("could not send message");
+#ifdef ENABLE_PARALLEL_PORT_TRACER
+ outb_p (PP_BASE_REG + PP_DATA_REG, 0xFF);
+ nanosleep(&pulse_width, NULL);
+ outb_p (PP_BASE_REG + PP_DATA_REG, 0x00);
+#endif
+ msg[recv_bytes] = '\0';
+ DEBUG("RECEIVED: %s with prio:%u from:%u\n", msg, prio, from);
+ }
+
+ return 0;
+}
+
+#endif
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+#include <assert.h>
+
+#include "frescan.h"
+#include "frescan_servers.h"
+#include "frescan_debug.h"
+
+#define NETWORK 0
+#define LOG_DEVICE LOG_ETHERNET
+
+#define NUM_MSG_BYTES 8 // 8 32 64 512 1488
+#define ENABLE_DEBUG false
+#define NUM_MEASURES 100
+
+#define LOCAL_NODE 0 // 0 1
+
+#include <misc/time_measurement_hwtime.h>
+#include <misc/logger.h>
+
+static const trace_point_id_t BEGIN = 0;
+static const trace_point_id_t END = 1;
+
+int main ()
+{
+ int i, ret;
+ frescan_send_params_t send_params;
+ frescan_recv_params_t recv_params;
+ char msg[1500]; // big enough for all the messages
+ frescan_init_params_t init_params;
+ frescan_node_t me;
+ size_t recv_bytes;
+ frescan_node_t from;
+ frescan_prio_t prio;
+
+ me = LOCAL_NODE;
+
+ DEBUG(ENABLE_DEBUG, ">> Initializing FRESCAN (me:%u)\n", me);
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) FRESCAN_ERROR ("could not init FRESCAN");
+
+ DEBUG(ENABLE_DEBUG, ">> Enter in loop for sending packets\n");
+
+ send_params.net = NETWORK;
+ send_params.channel = 0;
+ send_params.flags = FRESCAN_FP | FRESCAN_ASYNC;
+ send_params.prio = 9;
+ send_params.to = (me == 0)? 1 : 0;
+
+ recv_params.net = NETWORK;
+ recv_params.channel = 0;
+ recv_params.flags = FRESCAN_SYNC;
+
+ if (me == 0) {
+ DEBUG(ENABLE_DEBUG, ">> Init logger and timer measurements\n");
+
+ ret = logger_init(LOG_DEVICE);
+ assert(ret == 0);
+
+ ret = time_measure_hwtime_init(BEGIN, "frescan_begin");
+ assert(ret == 0);
+
+ ret = time_measure_hwtime_init(END, "frescan_end");
+ assert(ret == 0);
+
+ DEBUG(ENABLE_DEBUG, ">> Enter in loop for send-recv packets\n");
+
+ for (i=0; i<NUM_MEASURES; i++) {
+ time_measure_hwtime_set_timestamp(BEGIN);
+
+ ret = frescan_send(&send_params,
+ (uint8_t *)msg,
+ NUM_MSG_BYTES);
+ if (ret != 0) FRESCAN_ERROR ("could not send message\n");
+
+ ret = frescan_recv(&recv_params,
+ (uint8_t *)msg,
+ sizeof(msg),
+ &recv_bytes,
+ &from,
+ &prio);
+ if (ret != 0) FRESCAN_ERROR ("could not receive message");
+
+ time_measure_hwtime_set_timestamp(END);
+
+ DEBUG(ENABLE_DEBUG, ">> received %d bytes\n", recv_bytes);
+ }
+
+ ret = time_measure_hwtime_write_membuffer(BEGIN);
+ assert(ret == 0);
+
+ ret = time_measure_hwtime_write_membuffer(END);
+ assert(ret == 0);
+
+ while (logger_manual_call() > 0);
+
+ } else {
+ DEBUG(ENABLE_DEBUG, ">> Enter in loop for recv-send packets\n");
+
+ while(1) {
+ ret = frescan_recv(&recv_params,
+ (uint8_t *)msg,
+ sizeof(msg),
+ &recv_bytes,
+ &from,
+ &prio);
+ if (ret != 0) FRESCAN_ERROR ("could not receive message");
+
+ ret = frescan_send(&send_params,
+ (uint8_t *)msg,
+ recv_bytes);
+ if (ret != 0) FRESCAN_ERROR ("could not send message\n");
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+
+#include "frescan.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+#define LOCAL_NODE 1
+
+int main ()
+{
+ int ret;
+ frescan_init_params_t init_params;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("FRESCAN initialized\n");
+
+ while (1) {
+ sleep(1);
+ }
+
+ return 0;
+}
+
+
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+#include <stdint.h> // uint32_t
+
+#include "frescan_queues.h"
+#include "frescan_packets.h"
+#include "frescan_debug.h"
+#include <drivers/can.h>
+#include <misc/linux_list.h>
+
+#define DEBUG_ENABLE 1
+
+// static void pause(){
+// char key;
+// printf(" press Enter...");
+// key = getchar();
+// }
+
+int main ()
+{
+ int i, ret;
+ frescan_queues_t queues;
+ frescan_packet_t *packet, *head;
+ struct can_frame_t *frame;
+ frescan_prio_queue_t *pqueue;
+ frescan_prio_t prio;
+ bool blocking;
+ frescan_init_params_t init_params;
+
+ DEBUG(DEBUG_ENABLE, "init frames and packets pool\n");
+
+ // ret = can_framespool_init();
+ // if (ret != 0) FRESCAN_ERROR ("could not init frames pool\n");
+
+ ret = frescan_packets_init();
+ if (ret != 0) FRESCAN_ERROR ("could not init packet pool\n");
+
+ DEBUG(DEBUG_ENABLE, "init queues\n");
+
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ ret = frescan_queues_init(&queues, &init_params);
+ if (ret != 0) FRESCAN_ERROR("could not initialize the queues\n");
+
+ head = NULL;
+
+ DEBUG(DEBUG_ENABLE, "create queue of 5 packets\n");
+
+ for (i=0; i<5; i++) {
+ frame = can_framespool_alloc();
+ if (frame == NULL) FRESCAN_ERROR ("frames pool is exhausted\n");
+
+ frame->is_extended_format = 1;
+ frame->is_rtr = 0;
+ frame->id = 0x696969;
+ frame->dlc = 8;
+ frame->data[0] = 69;
+ frame->data[7] = 69;
+
+ packet = frescan_packets_alloc();
+ if (packet == NULL) FRESCAN_ERROR ("could not alloc packet\n");
+
+ packet->frame = frame;
+
+ if (head == NULL) {
+ DEBUG(DEBUG_ENABLE, "head was null\n");
+ head = frescan_packets_alloc();
+ if (head == NULL) FRESCAN_ERROR ("could not alloc packet\n");
+ INIT_LIST_HEAD(&head->msg_list);
+ }
+
+ list_add_tail(&packet->msg_list, &head->msg_list);
+ }
+
+ DEBUG(DEBUG_ENABLE, "enqueue head in priority queue\n");
+
+ pqueue = queues.rx_channel_queues[0];
+ ret = frescan_pqueue_enqueue(pqueue, head, 7);
+ if (ret != 0) FRESCAN_ERROR ("could not enqueue packet\n");
+
+ blocking = true;
+
+ DEBUG(DEBUG_ENABLE, "dequeue head from priority queue\n");
+
+ ret = frescan_pqueue_dequeue(pqueue, &head, &prio, blocking);
+ if (ret != 0) FRESCAN_ERROR ("could not dequeue packet\n");
+
+ if (head == NULL) {
+ if (blocking == false) {
+ FRESCAN_ERROR ("blocking false packet null\n");
+ } else {
+ FRESCAN_ERROR ("blocking true, and packet = null\n");
+ }
+ }
+
+ DEBUG(DEBUG_ENABLE, "traverse the list of packets\n");
+
+ list_for_each_entry(packet, &head->msg_list, msg_list) {
+ DEBUG(DEBUG_ENABLE,
+ "ID Packet, dlc: %u, frame pool pos: %u\n",
+ packet->frame->dlc, packet->frame->pool_pos);
+
+ ret = can_framespool_free(packet->frame);
+ if (ret != 0) FRESCAN_ERROR("could not free frame\n");
+
+ ret = frescan_packets_free(packet);
+ if (ret != 0) FRESCAN_ERROR("could not free packet\n");
+ }
+
+ DEBUG(DEBUG_ENABLE, "free head\n");
+
+ ret = frescan_packets_free(head);
+ if (ret != 0) {
+ FRESCAN_ERROR("could not free head packet\n");
+ return -1;
+ }
+
+ return 0;
+}
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+// mgcc test_frescan_servers_send_basic.c -L. -lfrescan -o mprogram_wifi2
+// mgcc test_frescan_servers_send_basic.c -DSENDER -L. -lfrescan -o mprogram_wifi1
+
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+
+#include "frescan.h"
+#include "frescan_servers.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+
+#define SENDER
+// #define ENABLE_LOGGING
+
+#ifdef SENDER
+
+#define LOCAL_NODE 0
+
+#ifdef ENABLE_LOGGING
+
+#include <drivers/console_switcher.h>
+#include <misc/logger.h>
+#include <assert.h>
+#define LOG_DEVICE LOG_ETHERNET
+
+#endif
+
+static void pause(){
+ char key;
+ printf(" press Enter...");
+ key = getchar();
+}
+
+int main ()
+{
+ int i, ret;
+ frescan_send_params_t params;
+ char msg[200];
+ int written;
+ frescan_init_params_t init_params;
+ frescan_server_params_t server_params, server_params_read;
+ frescan_budget_t current_budget;
+
+#ifdef ENABLE_LOGGING
+ ret = logger_init(LOG_DEVICE);
+ assert(ret == 0);
+ printf("Changing to membuffer console\n");
+ MEMBUFFER_CONSOLE_INIT();
+#endif
+
+ printf(">> Initializing FRESCAN\n");
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf(">> Creating a Server\n");
+
+ server_params.budget = 3;
+ server_params.period.tv_sec = 3;
+ server_params.period.tv_nsec = 0;
+ server_params.prio = 4;
+
+ ret = frescan_servers_create(NETWORK,
+ &server_params,
+ ¶ms.ss);
+ if (ret != 0) PUT_ERROR ("could not create server");
+
+ printf(">> Getting data from Server\n");
+
+ ret = frescan_servers_get_data(NETWORK,
+ &server_params_read,
+ params.ss);
+ if (ret != 0) PUT_ERROR ("could not get data from server");
+
+ printf("params: C = %d\n T = (%d, %d) P = %d\n",
+ server_params_read.budget,
+ server_params_read.period.tv_sec,
+ server_params_read.period.tv_nsec,
+ server_params_read.prio);
+
+ printf(">> Getting current_budget from Server\n");
+
+ ret = frescan_servers_get_current_budget(NETWORK,
+ params.ss,
+ ¤t_budget);
+ if (ret != 0) PUT_ERROR ("could not get current_budget");
+
+ printf("current_budget = %d\n", current_budget);
+
+ printf(">> Enter in loop for sending packets\n");
+
+ params.net = NETWORK;
+ params.to = 1;
+ params.channel = 0;
+ params.flags = FRESCAN_SS | FRESCAN_ASYNC;
+
+ while(1) {
+ pause();
+ for (i=0; i<=2; i++) {
+ written = snprintf(msg, sizeof(msg),
+ "his number is: %d", i);
+
+ ret = frescan_send(¶ms, (uint8_t *)msg, written);
+ if (ret != 0) PUT_ERROR ("could not send message\n");
+ printf("SENT: %d\n", i);
+
+ ret = frescan_servers_get_current_budget
+ (NETWORK, params.ss, ¤t_budget);
+ if (ret != 0) PUT_ERROR ("could not get current_budget");
+ printf("current_budget = %d\n", current_budget);
+ }
+ pause();
+ ret = frescan_servers_get_current_budget
+ (NETWORK, params.ss, ¤t_budget);
+ if (ret != 0) PUT_ERROR ("could not get current_budget");
+ printf("current_budget = %d\n", current_budget);
+
+#ifdef ENABLE_LOGGING
+ while (logger_manual_call() > 0);
+#endif
+}
+
+ return 0;
+}
+
+#else
+
+#define LOCAL_NODE 1
+
+int main ()
+{
+ int ret;
+ frescan_recv_params_t params;
+ uint8_t msg[3000];
+ size_t recv_bytes;
+ frescan_node_t from;
+ frescan_init_params_t init_params;
+ frescan_prio_t prio;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("FRESCAN initialized\n");
+
+ params.net = NETWORK;
+ params.channel = 0;
+ params.flags = FRESCAN_SYNC;
+
+ while (1) {
+ printf("RECEIVING...\n");
+ ret = frescan_recv(¶ms, (uint8_t *)msg, sizeof(msg),
+ &recv_bytes, &from, &prio);
+ if (ret != 0) PUT_ERROR ("could not send message");
+
+ msg[recv_bytes] = '\0';
+ printf("RECEIVED: %s with prio:%u\n", msg, prio);
+
+// for (i=0; i<recv_bytes; i++) {
+// printf("msg[%d] = 0x%X;\n", i, msg[i]);
+// }
+ }
+
+ return 0;
+}
+
+#endif
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+// mgcc test_frescan_servers_send_basic.c -L. -lfrescan -o mprogram_wifi2
+// mgcc test_frescan_servers_send_basic.c -DSENDER -L. -lfrescan -o mprogram_wifi1
+
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+
+#include "frescan.h"
+#include "frescan_servers.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+
+#define SENDER
+// #define ENABLE_LOGGING
+
+#ifdef SENDER
+
+#define LOCAL_NODE 0
+
+#ifdef ENABLE_LOGGING
+
+#include <drivers/console_switcher.h>
+#include <misc/logger.h>
+#include <assert.h>
+#define LOG_DEVICE LOG_ETHERNET
+
+#endif
+
+static void pause(){
+ char key;
+ printf(" press Enter...");
+ key = getchar();
+}
+
+int main ()
+{
+ int i, ret;
+ frescan_send_params_t params;
+ char msg[200];
+ int written;
+ frescan_init_params_t init_params;
+ frescan_server_params_t server_params;
+
+#ifdef ENABLE_LOGGING
+ ret = logger_init(LOG_DEVICE);
+ assert(ret == 0);
+ printf("Changing to membuffer console\n");
+ MEMBUFFER_CONSOLE_INIT();
+#endif
+
+ printf(">> Initializing FRESCAN\n");
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf(">> Creating a Server\n");
+
+ server_params.budget = 3;
+ server_params.period.tv_sec = 3;
+ server_params.period.tv_nsec = 0;
+ server_params.prio = 4;
+
+ ret = frescan_servers_create(NETWORK,
+ &server_params,
+ ¶ms.ss);
+ if (ret != 0) PUT_ERROR ("could not create server");
+
+ printf(">> Destroy the Server\n");
+
+ ret = frescan_servers_destroy(NETWORK, params.ss);
+ if (ret != 0) PUT_ERROR ("could not destroy server");
+
+ printf(">> Creating a Server\n");
+
+ server_params.budget = 3;
+ server_params.period.tv_sec = 3;
+ server_params.period.tv_nsec = 0;
+ server_params.prio = 7;
+
+ ret = frescan_servers_create(NETWORK,
+ &server_params,
+ ¶ms.ss);
+ if (ret != 0) PUT_ERROR ("could not create server");
+
+ printf(">> Enter in loop for sending packets\n");
+
+ params.net = NETWORK;
+ params.to = 1;
+ params.channel = 0;
+ params.flags = FRESCAN_SS | FRESCAN_ASYNC;
+
+ while(1) {
+ pause();
+ for (i=0; i<=2; i++) {
+ written = snprintf(msg, sizeof(msg), "his number is: %d", i);
+ ret = frescan_send(¶ms, (uint8_t *)msg, written);
+ if (ret != 0) PUT_ERROR ("could not send message\n");
+ printf("SENT: %d\n", i);
+ }
+#ifdef ENABLE_LOGGING
+ while (logger_manual_call() > 0);
+#endif
+ }
+
+ return 0;
+}
+
+#else
+
+#define LOCAL_NODE 1
+
+int main ()
+{
+ int ret;
+ frescan_recv_params_t params;
+ uint8_t msg[3000];
+ size_t recv_bytes;
+ frescan_node_t from;
+ frescan_init_params_t init_params;
+ frescan_prio_t prio;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("FRESCAN initialized\n");
+
+ params.net = NETWORK;
+ params.channel = 0;
+ params.flags = FRESCAN_SYNC;
+
+ while (1) {
+ printf("RECEIVING...\n");
+ ret = frescan_recv(¶ms, (uint8_t *)msg, sizeof(msg),
+ &recv_bytes, &from, &prio);
+ if (ret != 0) PUT_ERROR ("could not send message");
+
+ msg[recv_bytes] = '\0';
+ printf("RECEIVED: %s with prio:%u\n", msg, prio);
+
+// for (i=0; i<recv_bytes; i++) {
+// printf("msg[%d] = 0x%X;\n", i, msg[i]);
+// }
+ }
+
+ return 0;
+}
+
+#endif
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+// mgcc test_frescan_servers_send_basic.c -L. -lfrescan -o mprogram_wifi2
+// mgcc test_frescan_servers_send_basic.c -DSENDER -L. -lfrescan -o mprogram_wifi1
+
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+
+#include "frescan.h"
+#include "frescan_servers.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+
+#define SENDER
+// #define ENABLE_LOGGING
+
+#ifdef SENDER
+
+#define LOCAL_NODE 0
+
+#ifdef ENABLE_LOGGING
+
+#include <drivers/console_switcher.h>
+#include <misc/logger.h>
+#include <assert.h>
+#define LOG_DEVICE LOG_ETHERNET
+
+#endif
+
+static void pause(){
+ char key;
+ printf(" press Enter...");
+ key = getchar();
+}
+
+int main ()
+{
+ int i, ret;
+ frescan_send_params_t params;
+ char msg[200];
+ int written;
+ frescan_init_params_t init_params;
+ frescan_server_params_t server_params, server_params_read;
+ frescan_budget_t current_budget;
+
+#ifdef ENABLE_LOGGING
+ ret = logger_init(LOG_DEVICE);
+ assert(ret == 0);
+ printf("Changing to membuffer console\n");
+ MEMBUFFER_CONSOLE_INIT();
+#endif
+
+ printf(">> Initializing FRESCAN\n");
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf(">> Creating a Server\n");
+
+ server_params.budget = 6;
+ server_params.period.tv_sec = 3;
+ server_params.period.tv_nsec = 0;
+ server_params.prio = 4;
+
+ ret = frescan_servers_create(NETWORK,
+ &server_params,
+ ¶ms.ss);
+ if (ret != 0) PUT_ERROR ("could not create server");
+
+ printf(">> Getting data from Server\n");
+
+ ret = frescan_servers_get_data(NETWORK,
+ &server_params_read,
+ params.ss);
+ if (ret != 0) PUT_ERROR ("could not get data from server");
+
+ printf("params: C = %d\n T = (%d, %d) P = %d\n",
+ server_params_read.budget,
+ server_params_read.period.tv_sec,
+ server_params_read.period.tv_nsec,
+ server_params_read.prio);
+
+ printf(">> Getting current_budget from Server\n");
+
+ ret = frescan_servers_get_current_budget(NETWORK,
+ params.ss,
+ ¤t_budget);
+ if (ret != 0) PUT_ERROR ("could not get current_budget");
+
+ printf("current_budget = %d\n", current_budget);
+
+ printf(">> Setting perceived\n");
+
+ server_params.budget = 4;
+ server_params.period.tv_sec = 2;
+ server_params.period.tv_nsec = 0;
+ server_params.prio = 8;
+
+ ret = frescan_servers_set_perceived(NETWORK,
+ &server_params,
+ params.ss);
+ if (ret != 0) PUT_ERROR ("could not set perceived");
+
+ printf(">> Getting data from Server\n");
+
+ ret = frescan_servers_get_data(NETWORK,
+ &server_params_read,
+ params.ss);
+ if (ret != 0) PUT_ERROR ("could not get data from server");
+
+ printf("params: C = %d\n T = (%d, %d) P = %d\n",
+ server_params_read.budget,
+ server_params_read.period.tv_sec,
+ server_params_read.period.tv_nsec,
+ server_params_read.prio);
+
+ ret = frescan_servers_get_current_budget(NETWORK,
+ params.ss,
+ ¤t_budget);
+ if (ret != 0) PUT_ERROR ("could not get current_budget");
+
+ printf("current_budget = %d\n", current_budget);
+
+ printf(">> Commit params to Server\n");
+
+ ret = frescan_servers_commit_perceived(NETWORK, params.ss);
+ if (ret != 0) PUT_ERROR ("could not commit params");
+
+ ret = frescan_servers_get_current_budget(NETWORK,
+ params.ss,
+ ¤t_budget);
+ if (ret != 0) PUT_ERROR ("could not get current_budget");
+
+ printf("current_budget = %d\n", current_budget);
+
+ printf(">> Enter in loop for sending packets\n");
+
+ params.net = NETWORK;
+ params.to = 1;
+ params.channel = 0;
+ params.flags = FRESCAN_SS | FRESCAN_ASYNC;
+
+ while(1) {
+ pause();
+ for (i=0; i<=2; i++) {
+ written = snprintf(msg, sizeof(msg),
+ "his number is: %d", i);
+
+ ret = frescan_send(¶ms, (uint8_t *)msg, written);
+ if (ret != 0) PUT_ERROR ("could not send message\n");
+ printf("SENT: %d\n", i);
+
+ ret = frescan_servers_get_current_budget
+ (NETWORK, params.ss, ¤t_budget);
+ if (ret != 0) PUT_ERROR ("could not get current_budget");
+ printf("current_budget = %d\n", current_budget);
+ }
+ pause();
+ ret = frescan_servers_get_current_budget
+ (NETWORK, params.ss, ¤t_budget);
+ if (ret != 0) PUT_ERROR ("could not get current_budget");
+ printf("current_budget = %d\n", current_budget);
+
+#ifdef ENABLE_LOGGING
+ while (logger_manual_call() > 0);
+#endif
+}
+
+ return 0;
+}
+
+#else
+
+#define LOCAL_NODE 1
+
+int main ()
+{
+ int ret;
+ frescan_recv_params_t params;
+ uint8_t msg[3000];
+ size_t recv_bytes;
+ frescan_node_t from;
+ frescan_init_params_t init_params;
+ frescan_prio_t prio;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("FRESCAN initialized\n");
+
+ params.net = NETWORK;
+ params.channel = 0;
+ params.flags = FRESCAN_SYNC;
+
+ while (1) {
+ printf("RECEIVING...\n");
+ ret = frescan_recv(¶ms, (uint8_t *)msg, sizeof(msg),
+ &recv_bytes, &from, &prio);
+ if (ret != 0) PUT_ERROR ("could not send message");
+
+ msg[recv_bytes] = '\0';
+ printf("RECEIVED: %s with prio:%u\n", msg, prio);
+
+// for (i=0; i<recv_bytes; i++) {
+// printf("msg[%d] = 0x%X;\n", i, msg[i]);
+// }
+ }
+
+ return 0;
+}
+
+#endif
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+// mgcc test_frescan_servers_send_basic.c -L. -lfrescan -o mprogram_wifi2
+// mgcc test_frescan_servers_send_basic.c -DSENDER -L. -lfrescan -o mprogram_wifi1
+
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+
+#include "frescan.h"
+#include "frescan_servers.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+
+#define SENDER
+// #define ENABLE_LOGGING
+
+#ifdef SENDER
+
+#define LOCAL_NODE 0
+
+#ifdef ENABLE_LOGGING
+
+#include <drivers/console_switcher.h>
+#include <misc/logger.h>
+#include <assert.h>
+#define LOG_DEVICE LOG_ETHERNET
+
+#endif
+
+static void pause(){
+ char key;
+ printf(" press Enter...");
+ key = getchar();
+}
+
+int main ()
+{
+ int i, ret;
+ frescan_send_params_t params;
+ char msg[200];
+ int written;
+ frescan_init_params_t init_params;
+ frescan_server_params_t server_params;
+
+#ifdef ENABLE_LOGGING
+ ret = logger_init(LOG_DEVICE);
+ assert(ret == 0);
+ printf("Changing to membuffer console\n");
+ MEMBUFFER_CONSOLE_INIT();
+#endif
+
+ printf(">> Initializing FRESCAN\n");
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf(">> Creating a Server\n");
+
+ server_params.budget = 3;
+ server_params.period.tv_sec = 3;
+ server_params.period.tv_nsec = 0;
+ server_params.prio = 4;
+
+ ret = frescan_servers_create(NETWORK,
+ &server_params,
+ ¶ms.ss);
+ if (ret != 0) PUT_ERROR ("could not create server");
+
+ printf(">> Enter in loop for sending packets\n");
+
+ params.net = NETWORK;
+ params.to = 1;
+ params.channel = 0;
+ params.flags = FRESCAN_SS | FRESCAN_ASYNC;
+
+ while(1) {
+ pause();
+ for (i=0; i<=2; i++) {
+ written = snprintf(msg, sizeof(msg), "his number is: %d", i);
+ ret = frescan_send(¶ms, (uint8_t *)msg, written);
+ if (ret != 0) PUT_ERROR ("could not send message\n");
+ printf("SENT: %d\n", i);
+}
+#ifdef ENABLE_LOGGING
+ while (logger_manual_call() > 0);
+#endif
+}
+
+ return 0;
+}
+
+#else
+
+#define LOCAL_NODE 1
+
+int main ()
+{
+ int ret;
+ frescan_recv_params_t params;
+ uint8_t msg[3000];
+ size_t recv_bytes;
+ frescan_node_t from;
+ frescan_init_params_t init_params;
+ frescan_prio_t prio;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("FRESCAN initialized\n");
+
+ params.net = NETWORK;
+ params.channel = 0;
+ params.flags = FRESCAN_SYNC;
+
+ while (1) {
+ printf("RECEIVING...\n");
+ ret = frescan_recv(¶ms, (uint8_t *)msg, sizeof(msg),
+ &recv_bytes, &from, &prio);
+ if (ret != 0) PUT_ERROR ("could not send message");
+
+ msg[recv_bytes] = '\0';
+ printf("RECEIVED: %s with prio:%u\n", msg, prio);
+
+// for (i=0; i<recv_bytes; i++) {
+// printf("msg[%d] = 0x%X;\n", i, msg[i]);
+// }
+ }
+
+ return 0;
+}
+
+#endif
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+#include <assert.h>
+
+#include <drivers/console_switcher.h>
+#include <misc/logger.h>
+
+#include "frescan.h"
+#include "frescan_servers.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+// #define SENDER
+
+#ifdef SENDER
+
+#define LOCAL_NODE 0
+
+static void pause(){
+ char key;
+ printf(" press Enter...");
+ key = getchar();
+}
+
+int main ()
+{
+ int i, ret;
+ frescan_send_params_t params;
+ char msg[200];
+ frescan_init_params_t init_params;
+ frescan_server_params_t server_params;
+
+ ret = logger_init(LOG_ETHERNET);
+ assert(ret == 0);
+
+// MEMBUFFER_CONSOLE_INIT();
+
+ printf(">> Initializing FRESCAN\n");
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf(">> Creating a Server\n");
+
+ server_params.budget = 4;
+ server_params.period.tv_sec = 3;
+ server_params.period.tv_nsec = 0;
+ server_params.prio = 5;
+
+ ret = frescan_servers_create(NETWORK,
+ &server_params,
+ ¶ms.ss);
+ if (ret != 0) PUT_ERROR ("could not create server");
+
+ printf(">> Enter in loop for sending packets\n");
+
+ params.net = NETWORK;
+ params.to = 1;
+ params.channel = 2;
+ params.flags = FRESCAN_SS | FRESCAN_ASYNC;
+
+ while(1) {
+ pause();
+ for (i=0; i<2; i++) {
+ *((uint8_t *)msg) = (uint8_t)i;
+ ret = frescan_send(¶ms, (uint8_t *)msg, 3);
+ if (ret != 0) PUT_ERROR ("could not send message\n");
+ while (logger_manual_call() > 0);
+ printf("SENT\n");
+ }
+ }
+
+ return 0;
+}
+
+#else
+
+#define LOCAL_NODE 1
+
+int main ()
+{
+ int ret;
+ frescan_recv_params_t params;
+ uint8_t msg[3000];
+ size_t recv_bytes;
+ frescan_node_t from;
+ frescan_init_params_t init_params;
+ frescan_prio_t prio;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("FRESCAN initialized\n");
+
+ params.net = NETWORK;
+ params.channel = 2;
+ params.flags = FRESCAN_SYNC;
+
+ while (1) {
+ printf("RECEIVING...\n");
+ ret = frescan_recv(¶ms, (uint8_t *)msg, sizeof(msg),
+ &recv_bytes, &from, &prio);
+ if (ret != 0) PUT_ERROR ("could not send message");
+
+ printf("RECEIVED msg %u with prio:%u\n", msg[0], prio);
+
+// for (i=0; i<recv_bytes; i++) {
+// printf("msg[%d] = 0x%X;\n", i, msg[i]);
+// }
+ }
+
+ return 0;
+}
+
+#endif
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+#include <assert.h>
+
+#include "frescan.h"
+#include "frescan_servers.h"
+#include "frescan_debug.h"
+
+#define NETWORK 0
+#define LOG_DEVICE LOG_ETHERNET
+
+#define NUM_MSG_BYTES 512 // 8 32 64 512 1488
+#define ENABLE_DEBUG false
+#define NUM_MEASURES 100
+
+#define LOCAL_NODE 0 // 0 1
+
+#include <misc/time_measurement_hwtime.h>
+#include <misc/logger.h>
+
+static const trace_point_id_t BEGIN = 0;
+static const trace_point_id_t END = 1;
+
+#define DISABLE_MEASURES
+
+int main ()
+{
+ int i, ret;
+ frescan_send_params_t send_params;
+ frescan_recv_params_t recv_params;
+ char msg[1500]; // big enough for all the messages
+ frescan_init_params_t init_params;
+ frescan_server_params_t server_params;
+ frescan_node_t me;
+ size_t recv_bytes;
+ frescan_node_t from;
+ frescan_prio_t prio;
+
+ me = LOCAL_NODE;
+
+ DEBUG(ENABLE_DEBUG, ">> Initializing FRESCAN (me:%u)\n", me);
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) FRESCAN_ERROR ("could not init FRESCAN");
+
+ DEBUG(ENABLE_DEBUG, ">> Creating a Server\n");
+
+ server_params.budget = NUM_MSG_BYTES / 8;
+ server_params.period.tv_sec = 0;
+ server_params.period.tv_nsec = 500000000;
+ server_params.prio = 4;
+
+ ret = frescan_servers_create(NETWORK,
+ &server_params,
+ &send_params.ss);
+ if (ret != 0) FRESCAN_ERROR ("could not create server");
+
+ DEBUG(ENABLE_DEBUG, ">> Enter in loop for sending packets\n");
+
+ send_params.net = NETWORK;
+ send_params.channel = 0;
+ send_params.flags = FRESCAN_SS | FRESCAN_ASYNC;
+ send_params.to = (me == 0)? 1 : 0;
+
+ recv_params.net = NETWORK;
+ recv_params.channel = 0;
+ recv_params.flags = FRESCAN_SYNC;
+
+ if (me == 0) {
+ DEBUG(ENABLE_DEBUG, ">> Init logger and timer measurements\n");
+
+#ifndef DISABLE_MEASURES
+ ret = logger_init(LOG_DEVICE);
+ assert(ret == 0);
+
+ ret = time_measure_hwtime_init(BEGIN, "frescan_begin");
+ assert(ret == 0);
+
+ ret = time_measure_hwtime_init(END, "frescan_end");
+ assert(ret == 0);
+#endif
+ DEBUG(ENABLE_DEBUG, ">> Enter in loop for send-recv packets\n");
+
+ for (i=0; i<NUM_MEASURES; i++) {
+#ifndef DISABLE_MEASURES
+ time_measure_hwtime_set_timestamp(BEGIN);
+#endif
+ ret = frescan_send(&send_params,
+ (uint8_t *)msg,
+ NUM_MSG_BYTES);
+ if (ret != 0) FRESCAN_ERROR ("could not send message\n");
+
+ ret = frescan_recv(&recv_params,
+ (uint8_t *)msg,
+ sizeof(msg),
+ &recv_bytes,
+ &from,
+ &prio);
+ if (ret != 0) FRESCAN_ERROR ("could not receive message");
+#ifndef DISABLE_MEASURES
+ time_measure_hwtime_set_timestamp(END);
+#endif
+ DEBUG(ENABLE_DEBUG, ">> received %d bytes\n", recv_bytes);
+ sleep(1);
+ }
+#ifndef DISABLE_MEASURES
+ ret = time_measure_hwtime_write_membuffer(BEGIN);
+ assert(ret == 0);
+
+ ret = time_measure_hwtime_write_membuffer(END);
+ assert(ret == 0);
+
+ while (logger_manual_call() > 0);
+#endif
+ } else {
+ DEBUG(ENABLE_DEBUG, ">> Enter in loop for recv-send packets\n");
+
+ while(1) {
+ ret = frescan_recv(&recv_params,
+ (uint8_t *)msg,
+ sizeof(msg),
+ &recv_bytes,
+ &from,
+ &prio);
+ if (ret != 0) FRESCAN_ERROR ("could not receive message");
+
+ ret = frescan_send(&send_params,
+ (uint8_t *)msg,
+ recv_bytes);
+ if (ret != 0) FRESCAN_ERROR ("could not send message\n");
+ }
+ }
+
+ sleep(100);
+
+ return 0;
+}
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+// mgcc test_frescan_servers_send_basic.c -L. -lfrescan -o mprogram_wifi2
+// mgcc test_frescan_servers_send_basic.c -DSENDER -L. -lfrescan -o mprogram_wifi1
+
+#include <stdio.h> // perror
+#include <stdlib.h> // exit
+#include <unistd.h> // sleep
+
+#include "frescan.h"
+#include "frescan_servers.h"
+
+#define PUT_ERROR(s) {perror (s); exit (-1);}
+
+#define NETWORK 0
+
+#define SENDER
+// #define ENABLE_LOGGING
+
+#ifdef SENDER
+
+#define LOCAL_NODE 0
+
+#ifdef ENABLE_LOGGING
+
+#include <drivers/console_switcher.h>
+#include <misc/logger.h>
+#include <assert.h>
+#define LOG_DEVICE LOG_ETHERNET
+
+#endif
+
+static void pause(){
+ char key;
+ printf(" press Enter...");
+ key = getchar();
+}
+
+int main ()
+{
+ int i, ret;
+ frescan_send_params_t params;
+ char msg[200];
+ int written;
+ frescan_init_params_t init_params;
+ frescan_server_params_t server_params;
+
+#ifdef ENABLE_LOGGING
+ ret = logger_init(LOG_DEVICE);
+ assert(ret == 0);
+ printf("Changing to membuffer console\n");
+ MEMBUFFER_CONSOLE_INIT();
+#endif
+
+ printf(">> Initializing FRESCAN\n");
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf(">> Creating a Server\n");
+
+ server_params.budget = 8;
+ server_params.period.tv_sec = 3;
+ server_params.period.tv_nsec = 0;
+ server_params.prio = 6;
+
+ ret = frescan_servers_create(NETWORK,
+ &server_params,
+ ¶ms.ss);
+ if (ret != 0) PUT_ERROR ("could not create server");
+
+ server_params.budget = 3;
+ server_params.period.tv_sec = 2;
+ server_params.period.tv_nsec = 0;
+ server_params.prio = 4;
+
+ ret = frescan_servers_update(NETWORK,
+ &server_params,
+ params.ss);
+ if (ret != 0) PUT_ERROR ("could not update server");
+
+ printf(">> Enter in loop for sending packets\n");
+
+ params.net = NETWORK;
+ params.to = 1;
+ params.channel = 0;
+ params.flags = FRESCAN_SS | FRESCAN_ASYNC;
+
+ while(1) {
+ pause();
+ for (i=0; i<=2; i++) {
+ written = snprintf(msg, sizeof(msg), "his number is: %d", i);
+ ret = frescan_send(¶ms, (uint8_t *)msg, written);
+ if (ret != 0) PUT_ERROR ("could not send message\n");
+ printf("SENT: %d\n", i);
+}
+#ifdef ENABLE_LOGGING
+ while (logger_manual_call() > 0);
+#endif
+}
+
+ return 0;
+}
+
+#else
+
+#define LOCAL_NODE 1
+
+int main ()
+{
+ int ret;
+ frescan_recv_params_t params;
+ uint8_t msg[3000];
+ size_t recv_bytes;
+ frescan_node_t from;
+ frescan_init_params_t init_params;
+ frescan_prio_t prio;
+
+ init_params.net = NETWORK;
+ init_params.node = LOCAL_NODE;
+ init_params.tx_fp_max_prio = 10;
+ init_params.rx_num_of_channels = 5;
+ init_params.rx_channel_max_prio = NULL;
+
+ ret = frescan_init(&init_params);
+ if (ret != 0) PUT_ERROR ("could not init FRESCAN");
+
+ printf("FRESCAN initialized\n");
+
+ params.net = NETWORK;
+ params.channel = 0;
+ params.flags = FRESCAN_SYNC;
+
+ while (1) {
+ printf("RECEIVING...\n");
+ ret = frescan_recv(¶ms, (uint8_t *)msg, sizeof(msg),
+ &recv_bytes, &from, &prio);
+ if (ret != 0) PUT_ERROR ("could not send message");
+
+ msg[recv_bytes] = '\0';
+ printf("RECEIVED: %s with prio:%u\n", msg, prio);
+
+// for (i=0; i<recv_bytes; i++) {
+// printf("msg[%d] = 0x%X;\n", i, msg[i]);
+// }
+ }
+
+ return 0;
+}
+
+#endif
--- /dev/null
+.PHONY: tests
+include ../../config.mk
+include ../../rules.mk
+
+EXES := $(patsubst %.c,%.exe,$(wildcard *.c))
+
+tests: $(EXES)
+
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+/*
+ * test_c_rtep_fna.c
+ *
+ * Goal:
+ *
+ * The goal of this program is to test the RTEP implementation of the functions
+ * defined at fna.h without passing through the FRSH interface.
+ *
+ * Algorithm:
+ *
+ * We have two nodes, a sender and a receiver. The sender negotiates a contract,
+ * send info to the receiver, then renegotiates the contract and finally it
+ * cancels the contract.
+ *
+ */
+
+#include <assert.h> // for assert
+#include <stdio.h> // for printf
+#include <time.h> // for timespec
+
+#include "frsh.h" // for frsh_contract_set_xxx, FRSH_NETWORK_ID_DEFAULT, frsh_network_address_t, frsh_stream_id_t
+
+#include "fna.h" // for fna_vres_id_t
+#include "frsh_fna.h" // for frsh_rtep_*
+#include "rtep_fna.h" // for rtep_fna_operations
+
+#include "rtep.h" // for rtep_station_id_t, rtep_channel_t
+
+int main ()
+{
+ int err;
+ rtep_station_id_t me, normal_station, multicast_station;
+ frsh_network_address_t frsh_address;
+ char multicast_name[] = "broadcast";
+ size_t max_size, max_multicast_size, budget_bytes, nbytes;
+ struct timespec budget_timespec, period_max;
+ frsh_contract_t frsh_contract;
+ fna_vres_id_t vres;
+ fna_endpoint_data_t endpoint;
+ const int MSG_BUFFER_MX = 10;
+ char msg_buffer[MSG_BUFFER_MX];
+ int msg_size;
+ int msg_counter;
+
+ printf("--------------------------------------------------\n");
+ printf("1.- fna_init\n");
+ printf("--------------------------------------------------\n");
+ err = rtep_fna_operations.fna_init(FRSH_NETWORK_ID_DEFAULT);
+ assert(err == 0);
+
+ printf("--------------------------------------------------\n");
+ printf("2.- fna_network_get_max_message_size\n");
+ printf("--------------------------------------------------\n");
+ // get broadcast address for FRESCOR
+ multicast_station = rtep_get_station_id_by_name
+ ((uint8_t *)multicast_name, sizeof(multicast_name)-1);
+
+ err = frsh_rtep_map_network_address
+ (FRSH_RESOURCE_ID_DEFAULT, multicast_station, &frsh_address);
+ assert (err == 0);
+
+ // maximum size per message for a broadcast address
+ err=rtep_fna_operations.fna_network_get_max_message_size
+ (FRSH_RESOURCE_ID_DEFAULT, frsh_address, &max_multicast_size);
+ printf("Max multicast message size: %d\n", max_multicast_size);
+ assert (err == 0);
+ assert (max_multicast_size == MULTICAST_MTU);
+
+ // now the same with a normal address (i.e: 2)
+ normal_station = 2;
+ err=frsh_rtep_map_network_address
+ (FRSH_RESOURCE_ID_DEFAULT, normal_station, &frsh_address);
+ assert (err == 0);
+
+ // maximum size per message for a normal address
+ err=rtep_fna_operations.fna_network_get_max_message_size
+ (FRSH_RESOURCE_ID_DEFAULT, frsh_address, &max_size);
+ printf("Max message size: %d\n", max_size);
+ assert (err == 0);
+ assert (max_size == MAX_RTEP_MTU);
+
+ printf("--------------------------------------------------\n");
+ printf("3.- fna_network_budget_to_bytes\n");
+ printf("--------------------------------------------------\n");
+ nbytes = 1700;
+ err=rtep_fna_operations.fna_network_bytes_to_budget
+ (FRSH_RESOURCE_ID_DEFAULT, nbytes, &budget_timespec);
+ assert (err == 0);
+
+ err=rtep_fna_operations.fna_network_budget_to_bytes
+ (FRSH_RESOURCE_ID_DEFAULT, &budget_timespec, &budget_bytes);
+ assert (err == 0);
+ printf("%d user bytes -> %d budget bytes\n", nbytes, budget_bytes);
+
+ printf("--------------------------------------------------\n");
+ printf("4.- fna_network_get_min_effective_budget\n");
+ printf("--------------------------------------------------\n");
+ err=rtep_fna_operations.fna_network_get_min_eff_budget
+ (FRSH_RESOURCE_ID_DEFAULT, &budget_timespec);
+ assert (err == 0);
+
+ err=rtep_fna_operations.fna_network_budget_to_bytes
+ (FRSH_RESOURCE_ID_DEFAULT, &budget_timespec, &budget_bytes);
+ assert (err == 0);
+ printf("Minimum effective budget: %d\n", budget_bytes);
+
+ // send or receive
+ me = rtep_get_station_id();
+
+ if (me == 1) {
+
+ printf("--------------------------------------------------\n");
+ printf("5.- fna_contract_negotiate\n");
+ printf("--------------------------------------------------\n");
+
+ period_max.tv_sec = 3;
+ period_max.tv_nsec = 0;
+
+ // Create the contract
+ frsh_contract.workload = FRSH_WT_INDETERMINATE;
+ frsh_contract.granularity = FRSH_DEFAULT_GRANULARITY;
+ frsh_contract.weight = FRSH_DEFAULT_WEIGHT;
+ frsh_contract.importance = FRSH_DEFAULT_IMPORTANCE;
+ frsh_contract.resource_id = FRSH_RESOURCE_ID_DEFAULT;
+ frsh_contract.resource_type = FRSH_RT_NETWORK;
+
+ frsh_contract.budget_min = budget_timespec;
+ frsh_contract.period_max = period_max;
+ frsh_contract.d_equals_t = true;
+ frsh_contract.preemption_level = 4;
+
+ // Negotiate the contract
+ err = rtep_fna_operations.fna_contract_negotiate
+ (FRSH_RESOURCE_ID_DEFAULT, &frsh_contract, &vres);
+ assert (err == 0);
+ printf("Contract accepted\n");
+
+ // Bind the vres to an endpoint
+ endpoint.endpoint_type = FRSH_SEND_ENDPOINT_TYPE;
+ endpoint.vres = vres;
+ endpoint.is_bound = true;
+ endpoint.destination = 2; // only for send_endpoints
+ endpoint.resource_id = FRSH_RESOURCE_ID_DEFAULT;
+ endpoint.stream_id = 7;
+
+ msg_counter = 0;
+
+ while(1) {
+ sleep(4);
+ printf("sending message\n");
+
+ msg_counter = msg_counter + 1;
+ msg_size = snprintf(msg_buffer, MSG_BUFFER_MX-1, "MSG %d", msg_counter);
+
+ err = rtep_fna_operations.fna_send_async
+ (&endpoint, msg_buffer, msg_size);
+ assert (err == 0);
+ }
+ } else {
+ size_t received_bytes;
+ frsh_network_address_t from;
+
+ endpoint.endpoint_type = FRSH_RECEIVE_ENDPOINT_TYPE;
+ endpoint.is_bound = false;
+ endpoint.resource_id = FRSH_RESOURCE_ID_DEFAULT;
+ endpoint.stream_id = 7;
+
+ while(1) {
+ printf("blocking to receive\n");
+ err = rtep_fna_operations.fna_receive_sync
+ (&endpoint, msg_buffer, MSG_BUFFER_MX, &received_bytes, &from);
+ assert (err == 0);
+
+ msg_buffer[received_bytes] = '\0';
+
+ printf("msg received: %s\n", msg_buffer);
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+/*
+ * test_c_rtep_fna.c
+ *
+ * Goal:
+ *
+ * The goal of this program is to test the RTEP implementation of the functions
+ * defined at fna.h without passing through the FRSH interface.
+ *
+ * Algorithm:
+ *
+ * We have two nodes, a sender and a receiver. The sender negotiates a contract,
+ * send info to the receiver, then renegotiates the contract and finally it
+ * cancels the contract.
+ *
+ */
+
+#include <assert.h> // for assert
+#include <time.h> // for timespec
+
+#include "frsh.h" // for frsh_contract_set_xxx, FRSH_NETWORK_ID_DEFAULT, frsh_network_address_t, frsh_stream_id_t
+
+#include "fna.h" // for fna_vres_id_t
+#include "frsh_fna.h" // for frsh_rtep_*
+#include "rtep_fna.h" // for rtep_fna_operations
+
+#include "rtep.h" // for rtep_station_id_t, rtep_channel_t
+
+#include <misc/time_measurement_hwtime.h>
+#include <misc/logger.h>
+static const trace_point_id_t BEGIN_CONTRACT_NEG = 0;
+static const trace_point_id_t END_CONTRACT_NEG = 1;
+
+#if 0
+#include <stdio.h>
+#define DEBUG(x,args...) printf("%s: " x, __func__ , ##args)
+#else
+#define DEBUG(x,args...)
+#endif
+
+#define MX_MEASURES 40
+
+int main ()
+{
+ int err, i;
+ rtep_station_id_t me, normal_station, multicast_station;
+ frsh_network_address_t frsh_address;
+ char multicast_name[] = "broadcast";
+ size_t max_size, max_multicast_size, budget_bytes, nbytes;
+ struct timespec budget_timespec, period_max;
+ frsh_contract_t frsh_contract;
+ fna_vres_id_t vres;
+ fna_endpoint_data_t endpoint;
+ const int MSG_BUFFER_MX = 10;
+ char msg_buffer[MSG_BUFFER_MX];
+ int msg_size;
+ int msg_counter;
+
+ err = logger_init(LOG_ETHERNET);
+ assert(err == 0);
+
+ err = time_measure_hwtime_init(BEGIN_CONTRACT_NEG, "contract_begin");
+ assert(err == 0);
+
+ err = time_measure_hwtime_init(END_CONTRACT_NEG, "contract_end");
+ assert(err == 0);
+
+ DEBUG("--------------------------------------------------\n");
+ DEBUG("1.- fna_init\n");
+ DEBUG("--------------------------------------------------\n");
+ err = rtep_fna_operations.fna_init(FRSH_NETWORK_ID_DEFAULT);
+ assert(err == 0);
+
+ DEBUG("--------------------------------------------------\n");
+ DEBUG("2.- fna_network_get_max_message_size\n");
+ DEBUG("--------------------------------------------------\n");
+ // get broadcast address for FRESCOR
+ multicast_station = rtep_get_station_id_by_name
+ ((uint8_t *)multicast_name, sizeof(multicast_name)-1);
+
+ err = frsh_rtep_map_network_address
+ (FRSH_RESOURCE_ID_DEFAULT, multicast_station, &frsh_address);
+ assert (err == 0);
+
+ // maximum size per message for a broadcast address
+ err=rtep_fna_operations.fna_network_get_max_message_size
+ (FRSH_RESOURCE_ID_DEFAULT, frsh_address, &max_multicast_size);
+ DEBUG("Max multicast message size: %d\n", max_multicast_size);
+ assert (err == 0);
+ assert (max_multicast_size == MULTICAST_MTU);
+
+ // now the same with a normal address (i.e: 2)
+ normal_station = 2;
+ err=frsh_rtep_map_network_address
+ (FRSH_RESOURCE_ID_DEFAULT, normal_station, &frsh_address);
+ assert (err == 0);
+
+ // maximum size per message for a normal address
+ err=rtep_fna_operations.fna_network_get_max_message_size
+ (FRSH_RESOURCE_ID_DEFAULT, frsh_address, &max_size);
+ DEBUG("Max message size: %d\n", max_size);
+ assert (err == 0);
+ assert (max_size == MAX_RTEP_MTU);
+
+ DEBUG("--------------------------------------------------\n");
+ DEBUG("3.- fna_network_budget_to_bytes\n");
+ DEBUG("--------------------------------------------------\n");
+ nbytes = 1700;
+ err=rtep_fna_operations.fna_network_bytes_to_budget
+ (FRSH_RESOURCE_ID_DEFAULT, nbytes, &budget_timespec);
+ assert (err == 0);
+
+ err=rtep_fna_operations.fna_network_budget_to_bytes
+ (FRSH_RESOURCE_ID_DEFAULT, &budget_timespec, &budget_bytes);
+ assert (err == 0);
+ DEBUG("%d user bytes -> %d budget bytes\n", nbytes, budget_bytes);
+
+ DEBUG("--------------------------------------------------\n");
+ DEBUG("4.- fna_network_get_min_effective_budget\n");
+ DEBUG("--------------------------------------------------\n");
+ err=rtep_fna_operations.fna_network_get_min_eff_budget
+ (FRSH_RESOURCE_ID_DEFAULT, &budget_timespec);
+ assert (err == 0);
+
+ err=rtep_fna_operations.fna_network_budget_to_bytes
+ (FRSH_RESOURCE_ID_DEFAULT, &budget_timespec, &budget_bytes);
+ assert (err == 0);
+ DEBUG("Minimum effective budget: %d\n", budget_bytes);
+
+ // send or receive
+ me = rtep_get_station_id();
+
+ if (me == 1) {
+
+ DEBUG("--------------------------------------------------\n");
+ DEBUG("5.- fna_contract_negotiate\n");
+ DEBUG("--------------------------------------------------\n");
+
+ period_max.tv_sec = 3;
+ period_max.tv_nsec = 0;
+
+ // Create the contract
+ frsh_contract.workload = FRSH_WT_INDETERMINATE;
+ frsh_contract.granularity = FRSH_DEFAULT_GRANULARITY;
+ frsh_contract.weight = FRSH_DEFAULT_WEIGHT;
+ frsh_contract.importance = FRSH_DEFAULT_IMPORTANCE;
+ frsh_contract.resource_id = FRSH_RESOURCE_ID_DEFAULT;
+ frsh_contract.resource_type = FRSH_RT_NETWORK;
+
+ frsh_contract.budget_min = budget_timespec;
+ frsh_contract.period_max = period_max;
+ frsh_contract.d_equals_t = true;
+ frsh_contract.preemption_level = 4;
+
+ // Negotiate the contract
+ for (i=0; i<MX_MEASURES; i++) {
+ time_measure_hwtime_set_timestamp(BEGIN_CONTRACT_NEG);
+
+ err = rtep_fna_operations.fna_contract_negotiate
+ (FRSH_RESOURCE_ID_DEFAULT, &frsh_contract, &vres);
+ assert (err == 0);
+
+ time_measure_hwtime_set_timestamp(END_CONTRACT_NEG);
+ }
+
+ printf("Contract accepted\n");
+
+ err = time_measure_hwtime_write_membuffer(BEGIN_CONTRACT_NEG);
+ assert(err == 0);
+
+ err = time_measure_hwtime_write_membuffer(END_CONTRACT_NEG);
+ assert(err == 0);
+
+ while (logger_manual_call() > 0);
+
+ // Bind the vres to an endpoint
+ endpoint.endpoint_type = FRSH_SEND_ENDPOINT_TYPE;
+ endpoint.vres = vres;
+ endpoint.is_bound = true;
+ endpoint.destination = 2; // only for send_endpoints
+ endpoint.resource_id = FRSH_RESOURCE_ID_DEFAULT;
+ endpoint.stream_id = 7;
+
+ msg_counter = 0;
+
+ while(1) {
+ sleep(4);
+ DEBUG("sending message\n");
+
+ msg_counter = msg_counter + 1;
+ msg_size = snprintf(msg_buffer, MSG_BUFFER_MX-1, "MSG %d", msg_counter);
+
+ err = rtep_fna_operations.fna_send_async
+ (&endpoint, msg_buffer, msg_size);
+ assert (err == 0);
+ }
+ } else {
+ size_t received_bytes;
+ frsh_network_address_t from;
+
+ endpoint.endpoint_type = FRSH_RECEIVE_ENDPOINT_TYPE;
+ endpoint.is_bound = false;
+ endpoint.resource_id = FRSH_RESOURCE_ID_DEFAULT;
+ endpoint.stream_id = 7;
+
+ while(1) {
+ DEBUG("blocking to receive\n");
+ err = rtep_fna_operations.fna_receive_sync
+ (&endpoint, msg_buffer, MSG_BUFFER_MX, &received_bytes, &from);
+ assert (err == 0);
+
+ msg_buffer[received_bytes] = '\0';
+
+ DEBUG("msg received: %s\n", msg_buffer);
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+/*
+ * test_c_rtep_fna.c
+ *
+ * Goal:
+ *
+ * The goal of this program is to test the RTEP implementation of the functions
+ * defined at fna.h without passing through the FRSH interface.
+ *
+ * Algorithm:
+ *
+ * We have two nodes, a sender and a receiver. The sender negotiates a contract,
+ * send info to the receiver, then renegotiates the contract and finally it
+ * cancels the contract.
+ *
+ */
+
+#include <assert.h> // for assert
+#include <stdio.h> // for printf
+#include <time.h> // for timespec
+
+#include "frsh.h" // for frsh_contract_set_xxx, FRSH_RESOURCE_ID_DEFAULT, frsh_network_address_t, frsh_stream_id_t
+
+#include "fna.h" // for fna_vres_id_t
+#include "frsh_fna.h" // for frsh_rtep_*
+#include "rtep_fna.h" // for rtep_fna_operations
+
+#include "rtep.h" // for rtep_station_id_t, rtep_channel_t
+
+#include "fosa_threads_and_signals.h"
+
+int main ()
+{
+ int err;
+ rtep_station_id_t me, normal_station, multicast_station;
+ frsh_network_address_t frsh_address;
+ char multicast_name[] = "broadcast";
+ size_t max_size, max_multicast_size, budget_bytes, nbytes;
+ struct timespec budget_timespec, period_max;
+ frsh_contract_t frsh_contract;
+ fna_vres_id_t vres;
+ fna_endpoint_data_t endpoint;
+ const int MSG_BUFFER_MX = 10;
+ char msg_buffer[MSG_BUFFER_MX];
+ int msg_size;
+ int msg_counter;
+
+ printf("--------------------------------------------------\n");
+ printf("1.- fna_init\n");
+ printf("--------------------------------------------------\n");
+ err = frsh_init();
+// err = rtep_fna_operations.fna_init(FRSH_RESOURCE_ID_DEFAULT);
+ assert(err == 0);
+
+ printf("--------------------------------------------------\n");
+ printf("2.- fna_network_get_max_message_size\n");
+ printf("--------------------------------------------------\n");
+ // get broadcast address for FRESCOR
+ multicast_station = rtep_get_station_id_by_name
+ ((uint8_t *)multicast_name, sizeof(multicast_name)-1);
+
+ err = frsh_rtep_map_network_address
+ (FRSH_RESOURCE_ID_DEFAULT, multicast_station, &frsh_address);
+ assert (err == 0);
+
+ // maximum size per message for a broadcast address
+ err=rtep_fna_operations.fna_network_get_max_message_size
+ (FRSH_RESOURCE_ID_DEFAULT, frsh_address, &max_multicast_size);
+ printf("Max multicast message size: %d\n", max_multicast_size);
+ assert (err == 0);
+ assert (max_multicast_size == MULTICAST_MTU);
+
+ // now the same with a normal address (i.e: 2)
+ normal_station = 2;
+ err=frsh_rtep_map_network_address
+ (FRSH_RESOURCE_ID_DEFAULT, normal_station, &frsh_address);
+ assert (err == 0);
+
+ // maximum size per message for a normal address
+ err=rtep_fna_operations.fna_network_get_max_message_size
+ (FRSH_RESOURCE_ID_DEFAULT, frsh_address, &max_size);
+ printf("Max message size: %d\n", max_size);
+ assert (err == 0);
+ assert (max_size == MAX_RTEP_MTU);
+
+ printf("--------------------------------------------------\n");
+ printf("3.- fna_network_budget_to_bytes\n");
+ printf("--------------------------------------------------\n");
+ nbytes = 1700;
+ err=rtep_fna_operations.fna_network_bytes_to_budget
+ (FRSH_RESOURCE_ID_DEFAULT, nbytes, &budget_timespec);
+ assert (err == 0);
+
+ err=rtep_fna_operations.fna_network_budget_to_bytes
+ (FRSH_RESOURCE_ID_DEFAULT, &budget_timespec, &budget_bytes);
+ assert (err == 0);
+ printf("%d user bytes -> %d budget bytes\n", nbytes, budget_bytes);
+
+ printf("--------------------------------------------------\n");
+ printf("4.- fna_network_get_min_effective_budget\n");
+ printf("--------------------------------------------------\n");
+ err=rtep_fna_operations.fna_network_get_min_eff_budget
+ (FRSH_RESOURCE_ID_DEFAULT, &budget_timespec);
+ assert (err == 0);
+
+ err=rtep_fna_operations.fna_network_budget_to_bytes
+ (FRSH_RESOURCE_ID_DEFAULT, &budget_timespec, &budget_bytes);
+ assert (err == 0);
+ printf("Minimum effective budget: %d\n", budget_bytes);
+
+ // send or receive
+ me = rtep_get_station_id();
+
+ if (me == 1) {
+
+ printf("--------------------------------------------------\n");
+ printf("5.- fna_contract_negotiate\n");
+ printf("--------------------------------------------------\n");
+
+ period_max.tv_sec = 3;
+ period_max.tv_nsec = 0;
+
+ // Create the contract
+ frsh_contract.workload = FRSH_WT_INDETERMINATE;
+ frsh_contract.granularity = FRSH_DEFAULT_GRANULARITY;
+ frsh_contract.weight = FRSH_DEFAULT_WEIGHT;
+ frsh_contract.importance = FRSH_DEFAULT_IMPORTANCE;
+ frsh_contract.resource_id = FRSH_RESOURCE_ID_DEFAULT;
+ frsh_contract.resource_type = FRSH_RT_NETWORK;
+
+ frsh_contract.budget_min = budget_timespec;
+ frsh_contract.period_max = period_max;
+ frsh_contract.d_equals_t = true;
+ frsh_contract.preemption_level = 4;
+
+ // Negotiate the contract
+ err = rtep_fna_operations.fna_contract_negotiate
+ (FRSH_RESOURCE_ID_DEFAULT, &frsh_contract, &vres);
+ assert (err == 0);
+ printf("Contract accepted\n");
+
+ // Bind the vres to an endpoint
+ endpoint.endpoint_type = FRSH_SEND_ENDPOINT_TYPE;
+ endpoint.vres = vres;
+ endpoint.is_bound = true;
+ endpoint.destination = 2; // only for send_endpoints
+ endpoint.resource_id = FRSH_RESOURCE_ID_DEFAULT;
+ endpoint.stream_id = 7;
+
+ msg_counter = 0;
+
+ while(1) {
+ sleep(4);
+ printf("sending message\n");
+
+ msg_counter = msg_counter + 1;
+ msg_size = snprintf(msg_buffer, MSG_BUFFER_MX-1, "MSG %d", msg_counter);
+
+ err = rtep_fna_operations.fna_send_async
+ (&endpoint, msg_buffer, msg_size);
+ assert (err == 0);
+ }
+ } else {
+ size_t received_bytes;
+ frsh_network_address_t from;
+
+ endpoint.endpoint_type = FRSH_RECEIVE_ENDPOINT_TYPE;
+ endpoint.is_bound = false;
+ endpoint.resource_id = FRSH_RESOURCE_ID_DEFAULT;
+ endpoint.stream_id = 7;
+
+ while(1) {
+ printf("blocking to receive\n");
+ err = rtep_fna_operations.fna_receive_sync
+ (&endpoint, msg_buffer, MSG_BUFFER_MX, &received_bytes, &from);
+ assert (err == 0);
+
+ msg_buffer[received_bytes] = '\0';
+
+ printf("msg received: %s\n", msg_buffer);
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+/*
+ * test_c_rtep_frsh_fna.c
+ *
+ * Goal:
+ *
+ * The goal of this program is to test the RTEP functions defined at frsh_fna.h
+ * which is the public part of frsh_fna.h. The interface of this public part
+ * is dependent of the underlying network protocol. We are not trying here to
+ * make a very intense test but a simple and basic one to check the correct
+ * behaviour of the functions.
+ *
+ * Algorithm:
+ *
+ * First we check the conversions between frsh and rtep addresses and streams.
+ * Then, we check the renegotiation functions for the period of the internal
+ * negotiation messages. And finally, we check the renegotiation functions for
+ * the internal service thread.
+ *
+ */
+
+#include <assert.h> // for assert
+#include <stdio.h> // for printf
+#include <stdbool.h> // for bool
+
+#include "frsh.h" // for FRSH_RESOURCE_ID_DEFAULT, frsh_network_address_t, frsh_stream_id_t
+
+#include "rtep_fna.h" // for rtep_fna_operations.fna_init
+#include "rtep.h" // for rtep_station_id_t, rtep_channel_t
+#include "frsh_fna.h" // for frsh_rtep_*
+
+int main ()
+{
+ int err;
+ rtep_station_id_t rtep_station = 3;
+ frsh_network_address_t frsh_address;
+ rtep_channel_t in_stream = 7;
+ frsh_stream_id_t out_stream;
+ struct timespec neg_period = {2,0};
+ struct timespec get_period = {0,0};
+// struct timespec rtep_serv_thread_budget = {1,0};
+// struct timespec rtep_serv_thread_period = {5,0};
+// bool serv_thread_renegotiation_accepted = false;
+// struct timespec current_serv_thread_budget = {0,0};
+// struct timespec current_serv_thread_period = {0,0};
+
+ printf("1.- fna_init\n");
+ err=rtep_fna_operations.fna_init(FRSH_RESOURCE_ID_DEFAULT);
+ assert(err == 0);
+
+ printf("2.- frsh_rtep_map_network_address\n");
+ err=frsh_rtep_map_network_address
+ (FRSH_RESOURCE_ID_DEFAULT, rtep_station, &frsh_address);
+ assert(err == 0);
+ printf("rtep_address:%d -> frsh_address:%d\n", rtep_station, frsh_address);
+ assert(rtep_station == frsh_address);
+
+ printf("3.- frsh_rtep_map_stream_id\n");
+ err=frsh_rtep_map_stream_id
+ (FRSH_RESOURCE_ID_DEFAULT, in_stream, &out_stream);
+ assert(err == 0);
+ printf("rtep_channel:%d -> frsh_stream:%d\n", in_stream, out_stream);
+ assert(in_stream == out_stream);
+
+ printf("4.- frsh_rtep_negotiation_messages_vres_renegotiate period\n");
+ err=frsh_rtep_negotiation_messages_vres_get_period
+ (FRSH_RESOURCE_ID_DEFAULT, &get_period);
+ assert(err == 0);
+ printf("period before renegotiation: sec=%d nsec=%d\n",
+ get_period.tv_sec, get_period.tv_nsec);
+
+ err=frsh_rtep_negotiation_messages_vres_renegotiate
+ (FRSH_RESOURCE_ID_DEFAULT, &neg_period);
+ if (err == 0) {
+ printf("renegotiation accepted (period negotiated: sec=%d nsec=%d)\n",
+ neg_period.tv_sec, neg_period.tv_nsec);
+ } else {
+ printf("renegotiation not accepted\n");
+ }
+ assert (err == 0);
+
+ err=frsh_rtep_negotiation_messages_vres_get_period
+ (FRSH_RESOURCE_ID_DEFAULT, &get_period);
+ assert(err == 0);
+ printf("period after renegotiation: sec=%d nsec=%d\n",
+ get_period.tv_sec, get_period.tv_nsec);
+
+// TODO: uncomment step 5 when internal thread has a frescor contract
+// printf("5.- frsh_rtep_service_thread_vres_renegotiate\n");
+//
+// err=frsh_rtep_service_thread_vres_get_budget_and_period
+// (FRSH_RESOURCE_ID_DEFAULT,
+// ¤t_serv_thread_budget,
+// ¤t_serv_thread_period);
+// assert(err == 0);
+// printf("service thread budget (before renegotiation): sec=%d nsec=%d\n",
+// current_serv_thread_budget.tv_sec,
+// current_serv_thread_budget.tv_nsec);
+// printf("service thread period (before renegotiation): sec=%d nsec=%d\n",
+// current_serv_thread_period.tv_sec,
+// current_serv_thread_period.tv_nsec);
+//
+// err=frsh_rtep_service_thread_vres_renegotiate
+// (FRSH_RESOURCE_ID_DEFAULT,
+// &rtep_serv_thread_budget,
+// &rtep_serv_thread_period,
+// &serv_thread_renegotiation_accepted);
+// assert(err == 0);
+//
+// if (serv_thread_renegotiation_accepted) {
+// printf("service_thread renegotiation accepted\n");
+// } else {
+// printf("service_thread renegotiation not accepted\n");
+// }
+// assert (err == 0);
+//
+// err=frsh_rtep_service_thread_vres_get_budget_and_period
+// (FRSH_RESOURCE_ID_DEFAULT,
+// ¤t_serv_thread_budget,
+// ¤t_serv_thread_period);
+// assert(err == 0);
+// printf("service thread budget (after renegotiation): sec=%d nsec=%d\n",
+// current_serv_thread_budget.tv_sec,
+// current_serv_thread_budget.tv_nsec);
+// printf("service thread period (after renegotiation): sec=%d nsec=%d\n",
+// current_serv_thread_period.tv_sec,
+// current_serv_thread_period.tv_nsec);
+
+ printf("\nEND of the TEST\n");
+ return 0;
+}
--- /dev/null
+include ../../config.mk
+include ../../rules.mk
+
+CFLAGS += -I$(FNA_PATH)/src_unix/
+LDFLAGS += -L$(FNA_PATH)/lib -lunixfna -L$(FRSH_PATH)/lib -lfrsh -L$(FOSA_PATH)/lib -lfosa_$(PLATFORM) -lm -lfna
+
+test_unix_address.exe: test_unix_address.c
+ $(CC) $< $(CFLAGS)
\ No newline at end of file
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h>
+#include <frsh.h>
+#include <string.h>
+#include <stdlib.h>
+
+int to_unix_path(const frsh_network_address_t addr,
+ const frsh_stream_id_t stream,
+ char *str,
+ size_t mx_size)
+{
+ return snprintf(str, mx_size, "/tmp/unix_fna-%d-%d", addr, stream);
+}
+
+int to_addr_stream(frsh_network_address_t *addr,
+ frsh_stream_id_t *stream,
+ char *str,
+ size_t size)
+{
+ char *token;
+ char *search = "-";
+
+ token = strtok(str, search);
+ token = strtok(NULL, search);
+ *addr = atoi(token);
+ token = strtok(NULL, search);
+ *stream = atoi(token);
+
+ return 0;
+}
+
+int main()
+{
+ int err;
+ char myaddress[] = "/tmp/unix_fna-45-4";
+ frsh_network_address_t addr;
+ frsh_stream_id_t stream;
+ char str[100];
+
+ printf("TEST for unix path\n");
+
+ err = to_addr_stream(&addr, &stream, myaddress, sizeof(myaddress));
+ printf("to_addr_stream: addr=%d, stream=%d, err=%d\n", addr, stream, err);
+
+ err = to_unix_path(0, 1, str, sizeof(str));
+ printf("to_unix_path: %s\n", str);
+
+ return 0;
+}
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h>
+#include <stdlib.h> /* atoi */
+#include <unistd.h> /* sleep */
+#include <assert.h>
+#include <string.h> /* memset */
+
+#include "frsh.h" // for FRSH_CPU_ID_DEFAULT
+
+#include "fna.h" // for fna_vres_id_t
+#include "unix_fna.h" // for unix_fna_operations
+
+#define THE_SENDER_ADDR 0
+#define THE_RECEIVER_ADDR 1
+#define THE_STREAM_ID 3
+void sender(void);
+void receiver(void);
+
+int main ()
+{
+ int err;
+
+ err = unix_fna_operations.fna_init(FRSH_NETWORK_ID_DEFAULT);
+ assert(err == 0);
+
+ printf("I am %d\n", FRSH_CPU_ID_DEFAULT);
+
+ switch(FRSH_CPU_ID_DEFAULT) {
+ case 0:
+ sender();
+ break;
+ case 1:
+ receiver();
+ break;
+ default:
+ printf("wrong node number\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+void sender(void)
+{
+ int err, i;
+ frsh_contract_t contract;
+ fna_endpoint_data_t endpoint;
+ char buffer[100];
+ size_t size;
+
+ printf("I am the sender\n");
+
+ err = unix_fna_operations.fna_contract_negotiate
+ (FRSH_NETWORK_ID_DEFAULT,
+ &contract,
+ &endpoint.vres);
+ assert(err == 0);
+
+ endpoint.endpoint_type = FRSH_SEND_ENDPOINT_TYPE;
+ endpoint.is_bound = true;
+ endpoint.destination = THE_RECEIVER_ADDR;
+ endpoint.resource_id = FRSH_NETWORK_ID_DEFAULT;
+ endpoint.stream_id = THE_STREAM_ID;
+
+ for(i=0; i<10; i++) {
+ sleep(1);
+ size = snprintf(buffer, sizeof(buffer), "hello world %d", i);
+
+ err = unix_fna_operations.fna_send_async(&endpoint,
+ buffer,
+ size);
+ assert (err == 0);
+
+ printf("sender : sent %s\n", buffer);
+ }
+
+ printf("Sender done\n");
+}
+
+void receiver(void)
+{
+ int err, i;
+ fna_endpoint_data_t endpoint;
+ frsh_network_address_t from;
+ char buffer[100];
+ size_t received_bytes;
+
+ printf("I am the receiver\n");
+
+ endpoint.endpoint_type = FRSH_RECEIVE_ENDPOINT_TYPE;
+ endpoint.is_bound = false;
+ endpoint.resource_id = FRSH_NETWORK_ID_DEFAULT;
+ endpoint.stream_id = THE_STREAM_ID;
+
+ err = unix_fna_operations.fna_receive_endpoint_created(&endpoint);
+ assert (err == 0);
+
+ for(i=0; i<10; i++) {
+ err = unix_fna_operations.fna_receive_sync(&endpoint,
+ buffer,
+ 100,
+ &received_bytes,
+ &from);
+ assert (err == 0);
+
+ buffer[received_bytes] = '\0';
+
+ printf("receiver : received %s from %d\n", buffer, from);
+ }
+
+ printf("Receiver done\n");
+}
--- /dev/null
+export PLATFORM=MARTE_OS
+rm -f /tmp/unix_fna*
+
+cd
+cd frescor
+make clean
+cp frsh/include/frsh_configuration_parameters.h_cpu1 frsh/include/frsh_configuration_parameters.h
+make all
+
+cd fna/tests/tests_unix_fna
+make test_unix_fna_send_receive.exe
+cp mprogram /home/dsl/export/test_unix_fna_send_receive_cpu1.exe
+
+cd
+cd frescor
+make clean
+cp frsh/include/frsh_configuration_parameters.h_cpu2 frsh/include/frsh_configuration_parameters.h
+make all
+
+cd fna/tests/tests_unix_fna
+make test_unix_fna_send_receive.exe
+cp mprogram /home/dsl/export/test_unix_fna_send_receive_cpu2.exe
+
+cd /home/dsl/export
+./test_unix_fna_send_receive_cpu2.exe &
+./test_unix_fna_send_receive_cpu1.exe
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FNA (Frescor Network Adaptation)
+//
+// FNA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FNA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FNA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FNA header files in a file,
+// instantiating FNA generics or templates, or linking other files
+// with FNA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <stdio.h>
+#include <stdlib.h> /* atoi */
+#include <unistd.h> /* sleep */
+#include <assert.h>
+#include <string.h> /* memset */
+
+#include <sys/socket.h>
+#include <sys/un.h> /* struct sockaddr_un */
+
+#define SENDER_PATH "/tmp/sender_addr"
+#define RECEIVER_PATH "/tmp/receiver_addr"
+
+void sender(void);
+void receiver(void);
+
+int main (int argc, char **argv)
+{
+ if (argc != 2) {
+ printf("please provide the node to execute:\n");
+ printf(" $./mprogram 0 (sender)\n");
+ printf(" $./mprogram 1 (receiver)\n");
+ return -1;
+ }
+
+ switch(atoi(argv[1])) {
+ case 0:
+ sender();
+ break;
+ case 1:
+ receiver();
+ break;
+ default:
+ printf("wrong node number\n");
+ return -1;
+ }
+
+ unlink(SENDER_PATH);
+ unlink(RECEIVER_PATH);
+
+ return 0;
+}
+
+void sender(void)
+{
+ int sock, err, i;
+ struct sockaddr_un sender_addr, receiver_addr;
+ char buffer[100];
+ size_t size;
+ ssize_t sent_bytes;
+
+ printf("I am the sender\n");
+
+ sock = socket(AF_UNIX, SOCK_DGRAM, 0);
+ assert(sock >= 0);
+
+ memset(&sender_addr, 0, sizeof(sender_addr));
+ sender_addr.sun_family = AF_UNIX;
+ strcpy(sender_addr.sun_path, SENDER_PATH);
+
+ err = bind(sock, (struct sockaddr *)&sender_addr, sizeof(sender_addr));
+ assert(err >= 0);
+
+ memset(&receiver_addr, 0, sizeof(receiver_addr));
+ receiver_addr.sun_family = AF_UNIX;
+ strcpy(receiver_addr.sun_path, RECEIVER_PATH);
+
+ for(i=0; i<10; i++) {
+ sleep(1);
+ size = snprintf(buffer, sizeof(buffer), "hello world %d", i);
+ sent_bytes = sendto(sock,
+ buffer,
+ size,
+ 0,
+ (struct sockaddr *) &receiver_addr,
+ sizeof(receiver_addr));
+
+ assert(sent_bytes >= 0);
+
+ printf("sender : sent %s\n", buffer);
+ }
+
+ close(sock);
+ printf("Sender done\n");
+}
+
+void receiver(void)
+{
+ int sock, err, i;
+ struct sockaddr_un sender_addr, receiver_addr;
+ char buffer[100];
+ ssize_t received_bytes;
+ socklen_t from_len;
+
+ printf("I am the receiver\n");
+
+ sock = socket(AF_UNIX, SOCK_DGRAM, 0);
+ assert(sock >= 0);
+
+ memset(&receiver_addr, 0, sizeof(receiver_addr));
+ receiver_addr.sun_family = AF_UNIX;
+ strcpy(receiver_addr.sun_path, RECEIVER_PATH);
+
+ err = bind(sock, (struct sockaddr *)&receiver_addr, sizeof(receiver_addr));
+ assert(err >= 0);
+
+ for(i=0; i<10; i++) {
+ from_len = sizeof(sender_addr);
+ received_bytes = recvfrom(sock,
+ buffer,
+ sizeof(buffer),
+ 0,
+ (struct sockaddr *)&sender_addr,
+ &from_len);
+
+ assert(received_bytes >= 0);
+
+ buffer[received_bytes] = '\0';
+ printf("receiver : received %s\n", buffer);
+ }
+
+ close(sock);
+ printf("receiver done\n");
+}
--- /dev/null
+_build/
+_compiled/
+*~
+config.omk-default
+cscope.*
+config.omk
+sources.txt
+TAGS
+*.kdevelop*
+.emacs*
+*.kdevses
--- /dev/null
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
--- /dev/null
+# Doxyfile 1.5.6
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = "FORB (Frescor Object Request Broker)"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = doc
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek,
+# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish,
+# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish,
+# and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen to replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = YES
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page. This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = src
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH = .
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code. Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to FRAME, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature. Other possible values
+# for this tag are: HIERARCHIES, which will generate the Groups, Directories,
+# and Class Hiererachy pages using a tree view instead of an ordered list;
+# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which
+# disables this behavior completely. For backwards compatibility with previous
+# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE
+# respectively.
+
+GENERATE_TREEVIEW = NONE
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = NO
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = YES
+
+# By default doxygen will write a font called FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME = FreeSans
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is enabled by default, which results in a transparent
+# background. Warning: Depending on the platform used, enabling this option
+# may lead to badly anti-aliased labels on the edges of a graph (i.e. they
+# become hard to read).
+
+DOT_TRANSPARENT = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+SUBDIRS = tests-idl src
+EXTRA_RULES_SUBDIRS = forb-idl
--- /dev/null
+Compilation
+===========
+
+1. Download FRESCOR SVN repositories fosa and omk-build
+
+2. Download ulut (from
+ http://sourceforge.net/project/showfiles.php?group_id=118937&package_id=130840)
+
+3. Create symbolic links to forb, fosa and ulut sources inside
+ omk-build/aquosa:
+
+ cd omk-build/aquosa
+ ln -s some-path/fosa .
+ ln -s some-path/ulut .
+ ln -s path-to-this-directory/forb .
+
+3. Configure the sources:
+ make default-config
+
+5. Compile it:
+ make
+
--- /dev/null
+* Add forb_init() parameters: argc, argv and orb_id
+
+* More flexible handling of log messages (dynamic registration,
+ parsing of command line parameters).
+
+* Add FNA as transport protocol (probably with some reliable protocol
+ on top of FNA)
+
+* Add routing layer
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+bin_PROGRAMS = orbit-idl-2
+
+orbit_backends_dir = $(libdir)/orbit-2.0/idl-backends
+
+INCLUDES = \
+ -I$(top_builddir) \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/include \
+ -DORBIT_BACKENDS_DIR="\"$(orbit_backends_dir)\"" \
+ -DVERSION=\"$(ORBIT_VERSION)\" \
+ -DORBIT2_INTERNAL_API \
+ $(WARN_CFLAGS) \
+ $(DISABLE_DEPRECATED_CFLAGS) \
+ $(ORBIT_IDL_CFLAGS)
+
+orbit_idl_2_LDADD = \
+ $(ORBIT_IDL_LIBS) \
+ $(LIBM)
+
+orbit_idl_2_SOURCES = \
+ orbit-idl-main.c \
+ orbit-idl-driver.c \
+ orbit-idl-backend.c \
+ orbit-idl-backend.h \
+ orbit-idl-utils.c \
+ orbit-idl2.h \
+ orbit-idl3-types.h \
+ orbit-idl-c-backend.h \
+ orbit-idl-c-backend.c \
+ orbit-idl-c-stubs.c \
+ orbit-idl-c-skels.c \
+ orbit-idl-c-headers.c \
+ orbit-idl-c-common.c \
+ orbit-idl-c-imodule.c \
+ orbit-idl-c-skelimpl.c \
+ orbit-idl-c-utils.c \
+ orbit-idl-c-typecode.c \
+ orbit-idl-c-deps.c \
+ orbit-idl2.h
+
+orbitidlincludedir = $(includedir)/orbit-2.0/orbit-idl
+orbitidlinclude_HEADERS = orbit-idl-backend.h
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = ORBit-idl-2.0.pc
--- /dev/null
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = orbit-idl-2$(EXEEXT)
+subdir = src/idl-compiler
+DIST_COMMON = $(orbitidlinclude_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(srcdir)/ORBit-idl-2.0.pc.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = ORBit-idl-2.0.pc
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgconfigdir)" \
+ "$(DESTDIR)$(orbitidlincludedir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_orbit_idl_2_OBJECTS = orbit-idl-main.$(OBJEXT) \
+ orbit-idl-driver.$(OBJEXT) orbit-idl-backend.$(OBJEXT) \
+ orbit-idl-utils.$(OBJEXT) orbit-idl-c-backend.$(OBJEXT) \
+ orbit-idl-c-stubs.$(OBJEXT) orbit-idl-c-skels.$(OBJEXT) \
+ orbit-idl-c-headers.$(OBJEXT) orbit-idl-c-common.$(OBJEXT) \
+ orbit-idl-c-imodule.$(OBJEXT) orbit-idl-c-skelimpl.$(OBJEXT) \
+ orbit-idl-c-utils.$(OBJEXT) orbit-idl-c-typecode.$(OBJEXT) \
+ orbit-idl-c-deps.$(OBJEXT)
+orbit_idl_2_OBJECTS = $(am_orbit_idl_2_OBJECTS)
+am__DEPENDENCIES_1 =
+orbit_idl_2_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(orbit_idl_2_SOURCES)
+DIST_SOURCES = $(orbit_idl_2_SOURCES)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+pkgconfigDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(pkgconfig_DATA)
+orbitidlincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(orbitidlinclude_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkglibdir = @pkglibdir@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISABLE_DEPRECATED_CFLAGS = @DISABLE_DEPRECATED_CFLAGS@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GLIB_REQUIRED = @GLIB_REQUIRED@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBIDL_REQUIRED = @LIBIDL_REQUIRED@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINC_CFLAGS = @LINC_CFLAGS@
+LINC_LIBS = @LINC_LIBS@
+LN_S = @LN_S@
+LOCAL_LINC_CFLAGS = @LOCAL_LINC_CFLAGS@
+LOCAL_LINC_LIBS = @LOCAL_LINC_LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+LT_VERSION = @LT_VERSION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MINGW_LDFLAGS = @MINGW_LDFLAGS@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+ORBIT_ALIGNOF_CORBA_BOOLEAN = @ORBIT_ALIGNOF_CORBA_BOOLEAN@
+ORBIT_ALIGNOF_CORBA_CHAR = @ORBIT_ALIGNOF_CORBA_CHAR@
+ORBIT_ALIGNOF_CORBA_DOUBLE = @ORBIT_ALIGNOF_CORBA_DOUBLE@
+ORBIT_ALIGNOF_CORBA_FLOAT = @ORBIT_ALIGNOF_CORBA_FLOAT@
+ORBIT_ALIGNOF_CORBA_LONG = @ORBIT_ALIGNOF_CORBA_LONG@
+ORBIT_ALIGNOF_CORBA_LONG_DOUBLE = @ORBIT_ALIGNOF_CORBA_LONG_DOUBLE@
+ORBIT_ALIGNOF_CORBA_LONG_LONG = @ORBIT_ALIGNOF_CORBA_LONG_LONG@
+ORBIT_ALIGNOF_CORBA_OCTET = @ORBIT_ALIGNOF_CORBA_OCTET@
+ORBIT_ALIGNOF_CORBA_POINTER = @ORBIT_ALIGNOF_CORBA_POINTER@
+ORBIT_ALIGNOF_CORBA_SHORT = @ORBIT_ALIGNOF_CORBA_SHORT@
+ORBIT_ALIGNOF_CORBA_STRUCT = @ORBIT_ALIGNOF_CORBA_STRUCT@
+ORBIT_ALIGNOF_CORBA_WCHAR = @ORBIT_ALIGNOF_CORBA_WCHAR@
+ORBIT_CFLAGS = @ORBIT_CFLAGS@
+ORBIT_IDL_CFLAGS = @ORBIT_IDL_CFLAGS@
+ORBIT_IDL_LIBS = @ORBIT_IDL_LIBS@
+ORBIT_LIBS = @ORBIT_LIBS@
+ORBIT_MAJOR_VERSION = @ORBIT_MAJOR_VERSION@
+ORBIT_MICRO_VERSION = @ORBIT_MICRO_VERSION@
+ORBIT_MINOR_VERSION = @ORBIT_MINOR_VERSION@
+ORBIT_NAME_CFLAGS = @ORBIT_NAME_CFLAGS@
+ORBIT_NAME_LIBS = @ORBIT_NAME_LIBS@
+ORBIT_SERIAL = @ORBIT_SERIAL@
+ORBIT_VERSION = @ORBIT_VERSION@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+orbit_backends_dir = $(libdir)/orbit-2.0/idl-backends
+INCLUDES = \
+ -I$(top_builddir) \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/include \
+ -DORBIT_BACKENDS_DIR="\"$(orbit_backends_dir)\"" \
+ -DVERSION=\"$(ORBIT_VERSION)\" \
+ -DORBIT2_INTERNAL_API \
+ $(WARN_CFLAGS) \
+ $(DISABLE_DEPRECATED_CFLAGS) \
+ $(ORBIT_IDL_CFLAGS)
+
+orbit_idl_2_LDADD = \
+ $(ORBIT_IDL_LIBS) \
+ $(LIBM)
+
+orbit_idl_2_SOURCES = \
+ orbit-idl-main.c \
+ orbit-idl-driver.c \
+ orbit-idl-backend.c \
+ orbit-idl-backend.h \
+ orbit-idl-utils.c \
+ orbit-idl2.h \
+ orbit-idl3-types.h \
+ orbit-idl-c-backend.h \
+ orbit-idl-c-backend.c \
+ orbit-idl-c-stubs.c \
+ orbit-idl-c-skels.c \
+ orbit-idl-c-headers.c \
+ orbit-idl-c-common.c \
+ orbit-idl-c-imodule.c \
+ orbit-idl-c-skelimpl.c \
+ orbit-idl-c-utils.c \
+ orbit-idl-c-typecode.c \
+ orbit-idl-c-deps.c \
+ orbit-idl2.h
+
+orbitidlincludedir = $(includedir)/orbit-2.0/orbit-idl
+orbitidlinclude_HEADERS = orbit-idl-backend.h
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = ORBit-idl-2.0.pc
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/idl-compiler/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/idl-compiler/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+ORBit-idl-2.0.pc: $(top_builddir)/config.status $(srcdir)/ORBit-idl-2.0.pc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+orbit-idl-2$(EXEEXT): $(orbit_idl_2_OBJECTS) $(orbit_idl_2_DEPENDENCIES)
+ @rm -f orbit-idl-2$(EXEEXT)
+ $(LINK) $(orbit_idl_2_OBJECTS) $(orbit_idl_2_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-backend.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-backend.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-deps.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-headers.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-imodule.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-skelimpl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-skels.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-stubs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-typecode.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-c-utils.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-driver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orbit-idl-utils.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-pkgconfigDATA: $(pkgconfig_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
+ @list='$(pkgconfig_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(pkgconfigDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgconfigdir)/$$f'"; \
+ $(pkgconfigDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgconfigdir)/$$f"; \
+ done
+
+uninstall-pkgconfigDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgconfig_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(pkgconfigdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pkgconfigdir)/$$f"; \
+ done
+install-orbitidlincludeHEADERS: $(orbitidlinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(orbitidlincludedir)" || $(MKDIR_P) "$(DESTDIR)$(orbitidlincludedir)"
+ @list='$(orbitidlinclude_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(orbitidlincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(orbitidlincludedir)/$$f'"; \
+ $(orbitidlincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(orbitidlincludedir)/$$f"; \
+ done
+
+uninstall-orbitidlincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(orbitidlinclude_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(orbitidlincludedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(orbitidlincludedir)/$$f"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(DATA) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(orbitidlincludedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-orbitidlincludeHEADERS install-pkgconfigDATA
+
+install-dvi: install-dvi-am
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-orbitidlincludeHEADERS \
+ uninstall-pkgconfigDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic clean-libtool ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-binPROGRAMS install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-orbitidlincludeHEADERS install-pdf install-pdf-am \
+ install-pkgconfigDATA install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-orbitidlincludeHEADERS uninstall-pkgconfigDATA
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+bin_PROGRAMS = forb-idl
+
+#GLIB_FLAGS := $(shell pkg-config --cflags glib-2.0)
+IDL_FLAGS := $(shell pkg-config --cflags libIDL-2.0)
+CFLAGS += $(IDL_FLAGS) -DFORB_BACKENDS_DIR=\"/orbit-backend-dir\" -DVERSION=\"0.1\"
+CFLAGS := $(filter-out -fmudflapth,$(CFLAGS))
+LDFLAGS := $(filter-out -fmudflapth,$(LDFLAGS))
+LDFLAGS := $(filter-out -lmudflapth,$(LDFLAGS))
+
+forb-idl_SOURCES = forb-idl-backend.c forb-idl-backend.h \
+ forb-idl-c-backend.c forb-idl-c-backend.h \
+ forb-idl-c-common.c forb-idl-c-deps.c \
+ forb-idl-c-headers.c forb-idl-c-imodule.c \
+ forb-idl-c-skelimpl.c forb-idl-c-skels.c \
+ forb-idl-c-stubs.c forb-idl-c-typecode.c \
+ forb-idl-c-utils.c forb-idl-driver.c \
+ forb-idl-main.c forb-idl-utils.c forb-idl2.h \
+ forb-idl3-types.h
+forb-idl_LIBS = IDL-2 glib-2.0
--- /dev/null
+# Version for Linux/RTLinux builds. #OMK@linux
+#
+# Makefile.rules - OCERA make framework common project rules -*- makefile -*- #OMK@base
+#
+# (C) Copyright 2003 by Pavel Pisa - OCERA team member
+# (C) Copyright 2006 by Michal Sojka - Czech Technical University, FEE, DCE
+#
+# Homepage: http://rtime.felk.cvut.cz/omk/
+#
+# The OMK build system is distributed under the GNU General Public
+# License. See file COPYING for details.
+#
+# input variables
+# V .. if set to 1, full command text is shown else short form is used
+# W .. whole tree - if set to 1, make is always called from the top-level directory
+# SUBDIRS .. list of subdirectories intended for make from actual directory
+# default_CONFIG .. list of default config assignments CONFIG_XXX=y/n ...
+# LN_HEADERS .. if "y", header files are symbolicaly linked instead of copied. #OMK@include
+# #OMK@linux
+# input variables
+# lib_LIBRARIES .. list of the user-space libraries
+# shared_LIBRARIES .. list of the user-space shared libraries
+# kernel_LIBRARIES .. list of the kernel-space libraries
+# rtlinux_LIBRARIES.. list of the RT-Linux kernel-space libraries
+# include_HEADERS .. list of the user-space public header files
+# nobase_include_HEADERS .. public headers copied even with directory part
+# renamed_include_HEADERS .. public headers copied to the different target name
+# kernel_HEADERS .. list of the kernel-space public header files
+# rtlinux_HEADERS .. list of the RT-Linux kernel-space public header files
+# bin_PROGRAMS .. list of the require binary programs
+# utils_PROGRAMS .. list of the development utility programs
+# test_PROGRAMS .. list of the testing programs
+# kernel_MODULES .. list of the kernel side modules/applications
+# rtlinux_MODULES .. list of RT-Linux the kernel side modules/applications
+# xxx_SOURCES .. list of specific target sources
+# xxx_LIBS .. list of specific target libraries
+# INCLUDES .. additional include directories and defines for user-space
+# kernel_INCLUDES .. additional include directories and defines for kernel-space
+# rtlinux_INCLUDES .. additional include directories and defines for RT-Linux
+# OMIT_KERNEL_PASSES if defined, all kernel passes are omited
+#
+# LINUX_DIR .. location of Linux kernel sources
+# RTL_DIR .. location of RT-Linux sources
+# CFLAGS .. C compiler flags
+# CXXFLAGS .. C++ compiler flags
+# CPPFLAGS .. C preprocessor flags
+# LDFLAGS .. linker flags for programs linking
+# LOCAL_CONFIG_H .. name of local config.h file generated from values #OMK@config_h
+# of options defined in the current directory
+# config_include_HEADERS .. names of global config files (possibly
+# with subdirectories)
+# xxx_DEFINES .. list of config directives to be included in
+# config header file of the name <somedir>/xxx.h
+# DOXYGEN .. if non-empty, generated headers includes Doxygen's @file
+# command, so it is possible to document config
+# variables.
+# QT_SUBDIRS .. subdirectories where to build QT applications using qmake #OMK@qt
+# QTDIR .. where QT resides
+OMK_RULES_TYPE=linux #OMK@__type
+ #OMK@base
+# We need to ensure definition of sources directory first
+ifndef SOURCES_DIR
+# Only shell built-in pwd understands -L
+SOURCES_DIR := $(shell ( pwd -L ) )
+endif
+
+# If we are not called by OMK leaf Makefile...
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(abspath $(dir $(filter %Makefile.rules,$(MAKEFILE_LIST))))
+endif
+
+# OUTPUT_DIR is the place where _compiled, _build and possible other
+# files/directories are created. By default is the same as
+# $(MAKERULES_DIR).
+ifndef OUTPUT_DIR
+OUTPUT_DIR := $(MAKERULES_DIR)
+endif
+
+.PHONY: all default check-make-ver omkize
+
+ifdef W
+ ifeq ("$(origin W)", "command line")
+ OMK_WHOLE_TREE:=$(W)
+ endif
+endif
+ifndef OMK_WHOLE_TREE
+ OMK_WHOLE_TREE:=0
+endif
+
+ifneq ($(OMK_WHOLE_TREE),1)
+all: check-make-ver default
+ @echo "Compilation finished"
+else
+# Run make in the top-level directory
+all:
+ @$(MAKE) -C $(MAKERULES_DIR) OMK_SERIALIZE_INCLUDED=n SOURCES_DIR=$(MAKERULES_DIR) RELATIVE_DIR="" $(MAKECMDGOALS) W=0
+endif
+
+ifdef OMK_TESTSROOT
+# Usage: $(call canttest,<error message>)
+define canttest
+ ( echo "$(1)" > $(OUTPUT_DIR)/_canttest; echo "$(1)"; exit 1 )
+endef
+else
+define canttest
+ echo "$(1)"
+endef
+endif
+
+#=========================
+# Include the config file
+
+# FIXME: I think CONFIG_FILE_OK variable is useless. We have three
+# config files and it is not clearly defined to which file is this
+# variable related.
+ifneq ($(CONFIG_FILE_OK),y)
+ifndef CONFIG_FILE
+CONFIG_FILE := $(OUTPUT_DIR)/config.omk
+endif
+ifneq ($(wildcard $(CONFIG_FILE)-default),)
+-include $(CONFIG_FILE)-default
+else
+ifneq ($(MAKECMDGOALS),default-config)
+$(warning Please, run "make default-config" first)
+endif
+endif
+
+-include $(OUTPUT_DIR)/config.target
+
+ifneq ($(wildcard $(CONFIG_FILE)),)
+-include $(CONFIG_FILE)
+CONFIG_FILE_OK = y
+endif
+endif #$(CONFIG_FILE_OK)
+
+
+CONFIG_FILES ?= $(wildcard $(CONFIG_FILE)-default) $(wildcard $(OUTPUT_DIR)/config.target) $(wildcard $(CONFIG_FILE))
+
+
+export SOURCES_DIR MAKERULES_DIR RELATIVE_DIR
+export CONFIG_FILE CONFIG_FILES OMK_SERIALIZE_INCLUDED OMK_VERBOSE OMK_SILENT
+# OMK_SERIALIZE_INCLUDED has to be exported to submakes because passes
+# must to be serialized only in the toplevel make.
+
+ifndef RELATIVE_DIR
+RELATIVE_DIR := $(SOURCES_DIR:$(OUTPUT_DIR)%=%)
+endif
+#$(warning === RELATIVE_DIR = "$(RELATIVE_DIR)" ===)
+override RELATIVE_DIR := $(RELATIVE_DIR:/%=%)
+override RELATIVE_DIR := $(RELATIVE_DIR:\\%=%)
+#$(warning RELATIVE_DIR = "$(RELATIVE_DIR)")
+override BACK2TOP_DIR := $(shell echo $(RELATIVE_DIR)/ | sed -e 's_//_/_g' -e 's_/\./_/_g' -e 's_^\./__g' -e 's_\([^/][^/]*\)_.._g' -e 's_/$$__')
+#$(warning BACK2TOP_DIR = "$(BACK2TOP_DIR)")
+
+#$(warning SOURCES_DIR = "$(SOURCES_DIR)")
+#$(warning MAKERULES_DIR = "$(OUTPUT_DIR)")
+#$(warning RELATIVE_DIR = "$(RELATIVE_DIR)")
+
+# We have to use RELATIVE_PREFIX because of mingw
+override RELATIVE_PREFIX := $(RELATIVE_DIR)/
+override RELATIVE_PREFIX := $(RELATIVE_PREFIX:/%=%)
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+# Define srcdir for Automake compatibility
+srcdir = $(SOURCES_DIR)
+
+# Defines for quiet compilation
+ifdef V
+ ifeq ("$(origin V)", "command line")
+ OMK_VERBOSE = $(V)
+ endif
+endif
+ifndef OMK_VERBOSE
+ OMK_VERBOSE = 0
+endif
+ifneq ($(OMK_VERBOSE),0)
+ Q =
+else
+ Q = @
+endif
+ifneq ($(findstring s,$(MAKEFLAGS)),)
+ QUIET_CMD_ECHO = true
+ OMK_SILENT = 1
+else
+ QUIET_CMD_ECHO = echo
+endif
+
+MAKEFILE_OMK=Makefile.omk
+# All subdirectories (even linked ones) containing Makefile.omk
+# Usage in Makefile.omk: SUBDIRS = $(ALL_OMK_SUBDIRS)
+ALL_OMK_SUBDIRS = $(patsubst %/$(MAKEFILE_OMK),%,$(patsubst $(SOURCES_DIR)/%,%,$(wildcard $(SOURCES_DIR)/*/$(MAKEFILE_OMK))))
+
+# ===================================================================
+# We have set up all important variables, so we can check and include
+# real OCERA style Makefile.omk now
+ifndef OMK_INCLUDED
+include $(SOURCES_DIR)/$(MAKEFILE_OMK)
+ifeq ($(AUTOMATIC_SUBDIRS),y)
+SUBDIRS?=$(ALL_OMK_SUBDIRS)
+endif
+OMK_INCLUDED := 1
+endif
+
+check-make-ver:
+ @GOOD_MAKE_VERSION=`echo $(MAKE_VERSION) | sed -n -e 's/^[4-9]\..*\|^3\.9[0-9].*\|^3\.8[1-9].*/y/p'` ; \
+ if [ x$$GOOD_MAKE_VERSION != xy ] ; then \
+ echo "Your make program version is too old and does not support OMK system." ; \
+ echo "Please update to make program 3.81beta1 or newer." ; exit 1 ; \
+ fi
+
+distclean dist-clean:
+ @$(QUIET_CMD_ECHO) " RM $(COMPILED_DIR_NAME) $(BUILD_DIR_NAME)"
+ @rm -fr $(OUTPUT_DIR)/$(COMPILED_DIR_NAME) $(OUTPUT_DIR)/$(BUILD_DIR_NAME)
+
+# Common OMK templates
+# ====================
+
+# Syntax: $(call mkdir,<dir name>)
+define mkdir_def
+ [ -d $(1) ] || mkdir -p $(1) || exit 1
+endef
+
+ifneq ($(OMK_VERBOSE),2)
+NO_PRINT_DIRECTORY := --no-print-directory
+endif
+
+ifeq ($(USE_LEAF_MAKEFILES),n)
+export USE_LEAF_MAKEFILES
+SUBDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+SOURCESDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+else
+SUBDIR_MAKEFILE=$(SOURCES_DIR)/$(3)/Makefile
+SOURCESDIR_MAKEFILE=$(SOURCES_DIR)/Makefile
+endif
+
+pass = $(strip $(1))
+
+# Call a pass in a subdirectory
+# Usage: $(call omk_pass_subdir_template,<pass name>,<build dir>,<subdir>)
+define omk_pass_subdir_template
+.PHONY: $(pass)-$(3)-subdir
+$(pass)-submakes: $(pass)-$(3)-subdir
+$(pass)-$(3)-subdir:
+ @$(call mkdir_def,$(2)/$(3))
+ +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(3) $(NO_PRINT_DIRECTORY) \
+ RELATIVE_DIR=$(RELATIVE_PREFIX)$(3) -C $(2)/$(3) \
+ -f $(SUBDIR_MAKEFILE) $(pass)-submakes
+# In subdirectories we can call submakes directly since passes are
+# already searialized on the toplevel make.
+endef
+
+ifdef OMK_TESTSROOT
+check-target = $(1:%=%-check)
+endif
+
+# Call a pass in a subdirectory
+# Usage: $(call extra_rules_subdir_template,<subdir>)
+define extra_rules_subdir_template
+extra-rules-subdirs: extra-rules-$(1)
+extra-rules-$(1):
+ +@$(MAKE) OMK_SERIALIZE_INCLUDED=n MAKERULES_DIR=$(SOURCES_DIR)/$(1) OUTPUT_DIR=$(OUTPUT_DIR) \
+ SOURCES_DIR=$(SOURCES_DIR)/$(1) RELATIVE_DIR=$(RELATIVE_PREFIX)$(1) -C $(SOURCES_DIR)/$(1)
+endef
+
+.PHONY: extra-rules-subdirs
+extra-rules-subdirs:
+
+$(foreach subdir,$(EXTRA_RULES_SUBDIRS),$(eval $(call extra_rules_subdir_template,$(subdir))))
+
+# Usage: $(call omk_pass_template,<pass name>,<build dir>,[<local make flags>],[<local enable condition>])
+define omk_pass_template
+.PHONY: $(pass) $(pass)-local $(pass)-check $(pass)-submakes
+$(foreach subdir,$(SUBDIRS),$(eval $(call omk_pass_subdir_template,$(pass),$(2),$(subdir))))
+$(pass):
+# Submakes have to be called this way and not as dependecies for pass
+# serialization to work
+ +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR) $(NO_PRINT_DIRECTORY) \
+ RELATIVE_DIR=$(RELATIVE_DIR) \
+ -f $(SOURCESDIR_MAKEFILE) $(pass)-submakes
+$(pass)-submakes:
+ @true # Do not emit "nothing to be done" messages
+
+ifneq ($(4)$($(pass)_HOOKS),)
+$(pass)-submakes: $(pass)-this-dir
+$(pass)-this-dir: $(foreach subdir,$(SUBDIRS),$(pass)-$(subdir)-subdir)
+ +@echo "make[omk]: $(pass) in $(RELATIVE_DIR)"
+ @$(call mkdir_def,$(2))
+ +@$(MAKE) $(NO_PRINT_DIRECTORY) SOURCES_DIR=$(SOURCES_DIR) RELATIVE_DIR=$(RELATIVE_DIR) -C $(2) \
+ -f $(SOURCESDIR_MAKEFILE) $(3) $(check-target) $(1:%=%-local)
+$(pass)-local: $($(pass)_HOOKS)
+endif
+endef
+
+# =======================
+# DEFAULT CONFIG PASS
+
+default-config:
+ @echo "# Start of OMK config file" > "$(CONFIG_FILE)-default"
+ @echo "# This file should not be altered manually" >> "$(CONFIG_FILE)-default"
+ @echo "# Overrides should be stored in file $(notdir $(CONFIG_FILE))" >> "$(CONFIG_FILE)-default"
+ @echo >> "$(CONFIG_FILE)-default"
+ @$(MAKE) $(NO_PRINT_DIRECTORY) -C $(OUTPUT_DIR) \
+ RELATIVE_DIR="" SOURCES_DIR=$(OUTPUT_DIR) \
+ -f $(OUTPUT_DIR)/Makefile default-config-pass
+
+$(eval $(call omk_pass_template,default-config-pass,$$(LOCAL_BUILD_DIR),,always))
+
+default-config-pass-local:
+# @echo Default config for $(RELATIVE_DIR)
+ @echo "# Config for $(RELATIVE_DIR)" >> "$(CONFIG_FILE)-default"
+ @$(foreach x, $(default_CONFIG), echo '$(x)' | \
+ sed -e 's/^[^=]*=x$$/#\0/' >> "$(CONFIG_FILE)-default" ; )
+
+
+omkize:
+ $(Q)if ! grep -q MAKERULES_DIR Makefile; then \
+ echo "Makefile is not OMK leaf makefile!" >&2; exit 1; \
+ fi
+ $(Q)for i in `find -L . -name Makefile.omk` ; do \
+ d=`dirname $${i}`; \
+ if ! test -f "$${d}/Makefile.rules" && ( ! test -f "$${d}/Makefile" || ! cmp --silent Makefile "$${d}/Makefile" ); then \
+ rm -f "$${d}/Makefile"; \
+ cp -v Makefile "$${d}/Makefile"; \
+ fi \
+ done
+ifeq ($(OMK_VERBOSE),1) #OMK@include
+CPHEADER_FLAGS += -v
+LNHEADER_FLAGS += -v
+endif
+
+ifneq ($(LN_HEADERS),y)
+define cp_cmd
+( echo " CP $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; cp $(CPHEADER_FLAGS) $(1) $(2) )
+endef
+else
+define cp_cmd
+( echo " LN $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; [ -f $(1) ] && ln -sf $(LNHEADER_FLAGS) $(1) $(2) )
+endef
+endif
+
+# TODO: Check modification date of changed header files. If it is
+# newer that in source dir, show a warning.
+
+# Syntax: $(call include-pass-template,<include dir>,<keyword>)
+define include-pass-template
+include-pass-local: include-pass-local-$(2)
+include-pass-local-$(2): $$($(2)_GEN_HEADERS) $$(foreach f,$$(renamed_$(2)_GEN_HEADERS),$$(shell echo '$$(f)' | sed -e 's/^\(.*\)->.*$$$$/\1/'))
+ @$$(foreach f, $$($(2)_HEADERS), cmp --quiet $$(SOURCES_DIR)/$$(f) $(1)/$$(notdir $$(f)) \
+ || $$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(notdir $$(f))) || exit 1 ; )
+ @$$(foreach f, $$($(2)_GEN_HEADERS), cmp --quiet $$(f) $(1)/$$(notdir $$(f)) \
+ || $$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$(f),$(1)/$$(notdir $$(f))) || exit 1 ; ) # FIXME: Use correct build dir, then document it
+ @$$(foreach f, $$(nobase_$(2)_HEADERS), cmp --quiet $$(SOURCES_DIR)/$$(f) $(1)/$$(f) \
+ || ( mkdir -p $(1)/$$(dir $$(f)) && $$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(f)) ) || exit 1 ; )
+ @$$(foreach f, $$(renamed_$(2)_HEADERS), \
+ srcfname=`echo '$$(f)' | sed -e 's/^\(.*\)->.*$$$$/\1/'` ; destfname=`echo '$$(f)' | sed -e 's/^.*->\(.*\)$$$$/\1/'` ; \
+ cmp --quiet $$(SOURCES_DIR)/$$$${srcfname} $(1)/$$$${destfname} \
+ || ( mkdir -p `dirname $(1)/$$$${destfname}` && $$(call cp_cmd,$$(SOURCES_DIR)/$$$${srcfname},$(1)/$$$${destfname}) ) || exit 1 ; )
+ @$$(foreach f, $$(renamed_$(2)_GEN_HEADERS), \
+ srcfname=`echo '$$(f)' | sed -e 's/^\(.*\)->.*$$$$/\1/'` ; destfname=`echo '$$(f)' | sed -e 's/^.*->\(.*\)$$$$/\1/'` ; \
+ cmp --quiet $$$${srcfname} $(1)/$$$${destfname} \
+ || ( mkdir -p `dirname $(1)/$$$${destfname}` && $$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$$${srcfname},$(1)/$$$${destfname}) ) || exit 1 ; )
+endef
+
+# Local Variables:
+# mode:makefile
+# End:
+ #OMK@linux
+# Hack to check RT-Linux rules
+#LINUX_DIR := /home/cvs/ocera/ocera-build/kernel/linux
+#RTL_DIR := /home/cvs/ocera/ocera-build/kernel/rtlinux
+#CONFIG_RTLINUX = y
+#OCERA_DIR := $(shell ( cd -L $(OUTPUT_DIR)/../../.. ; pwd -L ) )
+
+-include $(OUTPUT_DIR)/OCERA_TOP_DIR
+
+BUILD_DIR_NAME = _build
+COMPILED_DIR_NAME = _compiled
+ifndef GROUP_DIR_NAME
+GROUP_DIR_NAME = nogroup
+endif
+
+ifdef OCERA_DIR
+ifeq ($(wildcard $(OCERA_DIR)/ocera.mk),)
+$(warning "ocera.mk" file does not exist. Adapt Makefile.rules for standalone compilation)
+$(warning (comment out definition of OCERA_DIR line and optionally select RTL_DIR) )
+$(error or go to the ocera/ directory and do 'make' to generate the "ocera.mk" file first, please)
+endif
+include $(OCERA_DIR)/ocera.mk
+KERN_INCLUDE_DIR := $(OCERA_KERNEL_INCLUDES_DIR)
+KERN_LIB_DIR := $(OCERA_KERNEL_LIBRARIES_DIR)
+KERN_MODULES_DIR := $(OCERA_MODULES_DIR)
+KERN_BUILD_DIR := $(BUILD_DIR)/kern/$(GROUP_DIR_NAME)
+KERN_MODPOST_DIR := $(BUILD_DIR)/kern-modpost
+USER_INCLUDE_DIR := $(OCERA_USER_INCLUDES_DIR)
+USER_LIB_DIR := $(OCERA_USER_LIBRARIES_DIR)
+USER_UTILS_DIR := $(TARGET_DIR)/usr/bin
+USER_TESTS_DIR := $(TARGET_DIR)/usr/bin
+USER_BIN_DIR := $(TARGET_DIR)/usr/bin
+USER_BUILD_DIR := $(BUILD_DIR)/user/$(GROUP_DIR_NAME)
+#LINUX_DIR := $(OCERA_DIR)/kernel/linux
+#RTL_DIR := $(OCERA_DIR)/kernel/rtlinux
+#CONFIG_FILE := $(OCERA_DIR)/emdebsys/.config
+ifneq ($(wildcard $(CONFIG_FILE)),)
+CONFIG_FILE_OK = y
+endif
+else # OCERA_DIR
+KERN_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include-kern
+KERN_LIB_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib-kern
+KERN_MODULES_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/modules
+KERN_BUILD_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern
+KERN_MODPOST_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern-modpost
+USER_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include
+USER_LIB_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib
+USER_UTILS_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-utils
+USER_TESTS_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-tests
+USER_BIN_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin
+USER_BUILD_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/user
+
+ifndef LINUX_VERSION
+LINUX_VERSION=$(shell uname -r)
+endif
+ifndef LINUX_DIR
+LINUX_DIR=/lib/modules/$(LINUX_VERSION)/build
+endif
+endif # OCERA_DIR
+
+ifeq ($(BUILD_OS),)
+ # Check for target
+ ifeq ($(OS),Windows_NT)
+ BUILD_OS := win32
+ else
+ BUILD_OS := $(shell uname | tr '[A-Z]' '[a-z]' )
+ #$(warning BUILD_OS=$(BUILD_OS))
+ endif
+endif
+
+ifeq ($(TARGET_OS),)
+ TARGET_OS := $(BUILD_OS)
+endif
+
+LOCAL_BUILD_DIR = $(USER_OBJS_DIR)
+
+# Assign default values to CFLAGS variable. If the variable is defined
+# earlier (i.g. in config.omk), it is not overriden here.
+CFLAGS ?= -O2 -Wall
+CXXFLAGS ?= -O2 -Wall
+
+
+CPPFLAGS += -I $(USER_INCLUDE_DIR)
+
+LOADLIBES += -L$(USER_LIB_DIR)
+
+LOADLIBES += $(lib_LOADLIBES:%=-l%)
+
+LIB_CPPFLAGS += $(CPPFLAGS)
+LIB_CFLAGS += $(CFLAGS)
+
+ifeq ($(TARGET_OS),win32)
+ SOLIB_EXT = dll
+else
+ SOLIB_EXT = so
+ SOLIB_PICFLAGS += -fpic
+endif
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+USER_OBJS_DIR = $(USER_BUILD_DIR)/$(RELATIVE_DIR)
+KERN_OBJS_DIR = $(KERN_BUILD_DIR)/$(RELATIVE_DIR)
+
+.PHONY: dep subdirs clean clean-custom cleandepend check-dir
+
+# Some support to serialize some targets for parallel make
+ifneq ($(OMK_SERIALIZE_INCLUDED),y)
+include-pass: check-dir
+library-pass: include-pass
+binary-pass: library-pass
+kernel-lib-pass: include-pass
+kernel-mod-pass: kernel-lib-pass
+kernel-modpost-pass: kernel-mod-pass
+kernel-pass: kernel-mod-pass kernel-modpost-pass
+
+override OMK_SERIALIZE_INCLUDED = y
+MAKEOVERRIDES := $(filter-out OMK_SERIALIZE_INCLUDED=n,$(MAKEOVERRIDES))
+endif
+
+# Checks for OMK tester
+ifdef OMK_TESTSROOT
+default-config-pass-check include-pass-check:
+library-pass-check binary-pass-check:
+ @[ -x "$(shell which $(CC))" ] || $(call canttest,Cannot find compiler: $(CC))
+endif
+
+#=====================================================================
+# User-space rules and templates to compile programs, libraries etc.
+
+ifdef USER_RULE_TEMPLATES
+
+USER_SOURCES2OBJS = .o/.c .o/.cc .o/.cxx .o/.S .o/.o
+
+USER_SOURCES2OBJSLO = .lo/.c .lo/.cc .lo/.cxx .lo/.S .lo/.lo
+
+#%.lo: %.c
+# $(CC) -o $@ $(LCFLAGS) -c $<
+
+c_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+cc_o_COMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+S_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(ASFLAGS) -DOMK_FOR_USER
+
+idl_COMPILE = $(IDL_COMPILER)
+
+# Check GCC version for user build
+ifndef CC_MAJOR_VERSION
+CC_MAJOR_VERSION := $(shell $(CC) -dumpversion | sed -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(CC_MAJOR_VERSION),2)
+CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+
+# Syntax: $(call COMPILE_c_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_c_o_template
+$(2): $(1) $$(GEN_HEADERS)
+ @$(QUIET_CMD_ECHO) " CC $$@"
+ $(Q) if $$(c_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+# Syntax: $(call COMPILE_cc_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_cc_o_template
+$(2): $(1) $$(GEN_HEADERS)
+ @$(QUIET_CMD_ECHO) " CXX $$@"
+ $(Q) if $$(cc_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+# Syntax: $(call COMPILE_S_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_S_o_template
+$(2): $(1) $$(GEN_HEADERS)
+ @$(QUIET_CMD_ECHO) " AS $$@"
+ $(Q) if $$(S_o_COMPILE) -D__ASSEMBLY__ $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+# Syntax: $(call CMETRIC_o_h_template,<object_file>,<target_header>)
+define CMETRIC_o_h_template
+$(2): $(1)
+ @$(QUIET_CMD_ECHO) " CMETRIC $$@"
+ $(Q)if [ -n `dirname $$@` ] ; then \
+ if [ ! -e `dirname $$@` ] ; then \
+ mkdir -p `dirname $$@` ; fi ; fi
+ $(Q)echo >$$@ '/* Automatically generated from $$< */'
+ $(Q)echo >>$$@ '/* Conditionals to control compilation */'
+ $(Q)set -o pipefail ; $(NM) $$< \
+ | sed -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2cond_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+ | sort >>$$@
+ $(Q)echo >>$$@ '/* Defines from the values defined to symbols */'
+ $(Q)set -o pipefail ; $(NM) $$< \
+ | sed -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2def_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+ | sort >>$$@
+endef
+
+
+
+define COMPILE_idl_template
+$(2).c $(2)-stubs.c $(2)-skels.c $(2)-common.c $(2).h: $(1)
+ @$(QUIET_CMD_ECHO) " IDL $$@"
+ $(Q) $$(idl_COMPILE) $(1)
+endef
+
+
+# Syntax: $(call PROGRAM_template,<dir>,<executable-name>,<executable-suffix>,<linker-sript>)
+# FIXME: ???????? asi je tu blbej komentar
+define PROGRAM_template
+
+USER_IDLS += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+USER_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+ $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+USER_OBJS += $$($(1)_OBJS)
+USER_SOURCES += $$($(1)_SOURCES)
+
+$(2)/$(1)$(3): $$($(1)_OBJS)
+ @$(QUIET_CMD_ECHO) " LINK $$@"
+ $(Q) $$(if $$(filter %.cc,$$($(1)_SOURCES:%.cxx=%.cc)),$$(CXX),$$(CC)) \
+ $$($(1)_OBJS) $$($(1)_LIBS:%=-l%) $$(LOADLIBES) $$(LDFLAGS) -Wl,-Map,$(USER_OBJS_DIR)/$(1).exe.map -o $$@
+ @echo "$(2)/$(1)$(3): \\" >$(USER_OBJS_DIR)/$(1).exe.d
+ @sed -n -e 's|^LOAD \(.*\)$$$$| \1 \&|p' $(USER_OBJS_DIR)/$(1).exe.map|tr '&' '\134' >>$(USER_OBJS_DIR)/$(1).exe.d
+ @echo >>$(USER_OBJS_DIR)/$(1).exe.d
+endef
+
+
+# Syntax: $(call LIBRARY_template,<library-name>)
+define LIBRARY_template
+
+USER_IDLS += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+USER_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+ $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+USER_OBJS += $$($(1)_OBJS)
+USER_SOURCES += $$($(1)_SOURCES)
+
+$(USER_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+ @$(QUIET_CMD_ECHO) " AR $$@"
+ $(Q) $(AR) rcs $$@ $$^
+endef
+
+
+# Syntax: $(call SOLIB_template,<library-name>)
+define SOLIB_template
+
+USER_IDLS += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+SOLIB_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJSLO),
+$(1)_OBJSLO += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+ $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJSLO := $$(sort $$($(1)_OBJSLO:%/=%))
+
+SOLIB_OBJS += $$($(1)_OBJSLO)
+SOLIB_SOURCES += $$($(1)_SOURCES)
+
+$(USER_LIB_DIR)/lib$(1).$(SOLIB_EXT): $$($(1)_OBJSLO)
+ @$(QUIET_CMD_ECHO) " LINK $$@"
+ $(Q) $(CC) --shared -Xlinker -soname=lib$(1).$(SOLIB_EXT) -o $$@ $$^ $$(LOADLIBES) $$($(1)_LIBS:%=-l%)
+endef
+
+
+
+library-pass-local: $(addprefix $(USER_INCLUDE_DIR)/,$(cmetric_include_HEADERS)) \
+ $(lib_LIBRARIES:%=$(USER_LIB_DIR)/lib%.a) $(shared_LIBRARIES:%=$(USER_LIB_DIR)/lib%.$(SOLIB_EXT))
+
+binary-pass-local: $(bin_PROGRAMS:%=$(USER_BIN_DIR)/%$(EXE_SUFFIX)) $(utils_PROGRAMS:%=$(USER_UTILS_DIR)/%$(EXE_SUFFIX)) $(test_PROGRAMS:%=$(USER_TESTS_DIR)/%$(EXE_SUFFIX))
+
+# Special rules for CMETRIC generated headers
+
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call COMPILE_c_o_template,\
+ $(SOURCES_DIR)/$($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES),\
+ $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),)))
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call CMETRIC_o_h_template,\
+ $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),\
+ $(addprefix $(USER_INCLUDE_DIR)/,$(cmetrh)))))
+
+GEN_HEADERS+=$(cmetric_include_HEADERS:%=$(USER_INCLUDE_DIR)/%)
+
+GEN_HEADERS+=$(filter %.h,$(USER_IDLS:%.idl=%.h))
+
+# Generate rules for compilation of programs and libraries
+
+$(foreach prog,$(utils_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_UTILS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(test_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_TESTS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(bin_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_BIN_DIR),$(EXE_SUFFIX))))
+
+$(foreach lib,$(lib_LIBRARIES),$(eval $(call LIBRARY_template,$(lib))))
+
+$(foreach lib,$(shared_LIBRARIES),$(eval $(call SOLIB_template,$(lib))))
+
+-include $(USER_OBJS_DIR)/*.d
+
+endif
+
+#=====================================================================
+# Kernel-space rules and templates to compile modules, libraries etc.
+
+ifdef KERN_RULE_TEMPLATES
+
+$(KERN_LIB_DIR)/kernel.mk: $(LINUX_DIR)/.config $(MAKERULES_DIR)/kernelcfg2mk
+ @$(QUIET_CMD_ECHO) " KCFG2MK $$@"
+ $(Q) $(MAKERULES_DIR)/kernelcfg2mk $(LINUX_DIR) $(KERN_LIB_DIR)
+
+ifeq ($(CONFIG_RTLINUX),y)
+include $(RTL_DIR)/rtl.mk
+
+KERN_CC = $(CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(CC) -print-search-dirs | sed -n -e 's/^install: \(.*\)$$/\1/p' )
+INCLUDES := -I $(KERN_INCLUDE_DIR) $(INCLUDE) $(rtlinux_INCLUDES) $(kernel_INCLUDES)
+#-DEXPORT_NO_SYMBOLS
+c_o_kern_COMPILE = $(KERN_CC) -idirafter $(kern_GCCLIB_DIR)/include $(INCLUDES) $(CFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(CXX) $(INCLUDES) $(CXXFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+KERN_EXE_SUFFIX := .o
+KERN_ARCH = $(ARCH)
+KERN_LD = $(LD)
+KERN_AR = $(AR)
+
+else # CONFIG_RTLINUX
+
+include $(KERN_LIB_DIR)/kernel.mk
+
+ifeq ($(LINUX_SRC),)
+LINUX_SRC = $(LINUX_DIR)
+endif
+kernel_INCLUDES += -I $(LINUX_DIR) -idirafter $(LINUX_SRC)/include/linux
+
+ifdef LINUX_CC
+KERN_CC = $(LINUX_CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(LINUX_CC) -print-search-dirs | sed -n -e 's/^install: \(.*\)$$/\1/p' )
+else
+KERN_CC = echo KERN_CC not defined - compilation skipped
+endif
+c_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+S_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_AFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+KERN_EXE_SUFFIX := $(LINUX_MODULE_EXT)
+KERN_LDFLAGS = $(LINUX_LDFLAGS)
+ifdef LINUX_ARCH
+KERN_ARCH = $(LINUX_ARCH)
+else
+KERN_ARCH = echo KERN_ARCH not defined - skipped
+endif
+ifdef LINUX_LD
+KERN_LD = $(LINUX_LD)
+else
+KERN_LD = echo KERN_LD not defined - skipped
+endif
+ifneq ($(LINUX_AR),)
+KERN_AR = $(LINUX_AR)
+else
+KERN_AR = $(AR)
+endif
+ifeq ($(LINUX_QUOTE_MODNAME),y)
+KERN_MQ=\"
+KERN_KBUILD_MODNAME=-D"KBUILD_MODNAME=((THIS_MODULE)?(THIS_MODULE)->name:NULL)"
+endif
+endif # CONFIG_RTLINUX
+
+KERN_LOADLIBES += -L$(KERN_LIB_DIR)
+
+KERN_LOADLIBES += $(rtlinux_LOADLIBES:%=-l%)
+KERN_LOADLIBES += $(kernel_LOADLIBES:%=-l%)
+
+
+
+# Check GCC version for kernel part of build
+ifndef kern_CC_MAJOR_VERSION
+kern_CC_MAJOR_VERSION := $(shell $(KERN_CC) -dumpversion | sed -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(kern_CC_MAJOR_VERSION),2)
+kern_CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+kern_CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+ifeq ($(KERN_EXE_SUFFIX),.ko)
+ifeq ($(wildcard $(LINUX_DIR)/scripts/mod/modpost),)
+KERN_MODPOST = $(LINUX_DIR)/scripts/modpost
+else
+KERN_MODPOST = $(LINUX_DIR)/scripts/mod/modpost
+endif
+KERN_MODULES_LINK_DIR = $(KERN_MODPOST_DIR)
+KERN_LINK_SUFFIX = .o
+else
+KERN_MODULES_LINK_DIR = $(KERN_MODULES_DIR)
+KERN_LINK_SUFFIX = $(KERN_EXE_SUFFIX)
+endif
+
+define COMPILE_c_o_kern_template
+
+$(2): $(1)
+ @$(QUIET_CMD_ECHO) " CC [K] $$@"
+ $(Q) if $$(c_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+ -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+ -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+
+define COMPILE_cc_o_kern_template
+
+$(2): $(1)
+ @$(QUIET_CMD_ECHO) " CXX [K] $$@"
+ $(Q) if $$(cc_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+ -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+ -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+
+define COMPILE_S_o_kern_template
+
+$(2): $(1)
+ @$(QUIET_CMD_ECHO) " AS [K] $$@"
+ $(Q) if $$(S_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+ -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+ -o $$@ -c $$< ; \
+ then mv -f "$$@.d.tmp" "$$@.d" ; \
+ else rm -f "$$@.d.tmp" ; exit 1; \
+ fi
+endef
+
+
+
+define MODULE_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+# this is hack to build "__this_module" structure for 2.6.x kernels
+# modpost is used for that purpose now
+
+#$(1).mod.c:
+# echo "\
+# #include <linux/version.h>@\
+# #include <linux/module.h>@\
+# #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,5))@\
+# #include <linux/vermagic.h>@\
+# #include <linux/compiler.h>@\
+# @\
+# MODULE_INFO(vermagic, VERMAGIC_STRING);@\
+# @\
+# #undef unix@\
+# struct module __this_module@\
+# __attribute__((section(\".gnu.linkonce.this_module\"))) = {@\
+# .name = __stringify(KBUILD_MODNAME),@\
+# .init = init_module,@\
+# #ifdef CONFIG_MODULE_UNLOAD@\
+# .exit = cleanup_module,@\
+# #endif@\
+# };@\
+# #endif@\
+# " | tr @ \\n >$$@
+
+
+#$(eval $(call COMPILE_c_o_kern_template,$(1).mod.c,$(1).mod.o,-DKBUILD_MODNAME=$(1)))
+
+$(2)/$(1)$(KERN_LINK_SUFFIX): $$($(1)_OBJS)
+ @$(QUIET_CMD_ECHO) " LD [K] $$@"
+ $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) -r $$($(1)_OBJS) -L$$(kern_GCCLIB_DIR) $$($(1)_LIBS:%=-l%) $$(KERN_LOADLIBES) -Map $(KERN_OBJS_DIR)/$(1).mod.map -o $$@
+ @echo "$(2)/$(1)$(KERN_LINK_SUFFIX): \\" >$(KERN_OBJS_DIR)/$(1).mod.d
+ @sed -n -e 's/^LOAD \(.*\)$$$$/ \1 \\/p' $(KERN_OBJS_DIR)/$(1).mod.map >>$(KERN_OBJS_DIR)/$(1).mod.d
+ @echo >>$(KERN_OBJS_DIR)/$(1).mod.d
+ @if [ "$(KERN_EXE_SUFFIX)" = ".ko" ] ; then \
+ echo $(1) >>$(KERN_MODPOST_DIR)/module-changes ; \
+ echo $(1) >>$(KERN_MODPOST_DIR)/$(1).mod.stamp ; \
+ fi
+
+endef
+
+
+
+define LIBRARY_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+$(KERN_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+ @$(QUIET_CMD_ECHO) " AR [K] $$@"
+ $(Q) $(KERN_AR) rcs $$@ $$^
+endef
+
+
+ifdef LINUX_DIR
+
+kernel-lib-pass-local: $(kernel_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+kernel-mod-pass-local: $(kernel_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+$(foreach module,$(kernel_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(kernel_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+
+ifeq ($(CONFIG_RTLINUX),y)
+
+kernel-mod-pass-local: $(rtlinux_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+kernel-lib-pass-local: $(rtlinux_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+$(foreach module,$(rtlinux_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(rtlinux_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+ifeq ($(KERN_MODPOST_PASS),y)
+
+MODULES_LIST := $(wildcard *.mod.stamp)
+MODULES_LIST := $(MODULES_LIST:%.mod.stamp=%)
+
+define MODPOST_kern_template
+$(2) : $(1)$(KERN_LINK_SUFFIX) $(1).mod.c
+ @$(QUIET_CMD_ECHO) " LD [M] $$@"
+ $(Q) $$(cc_o_kern_COMPILE) -D"KBUILD_BASENAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+ -D"KBUILD_MODNAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+ -o $(1).mod.o -c $(1).mod.c
+ $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) $(1)$(KERN_LINK_SUFFIX) $(1).mod.o -r -o $$@
+endef
+
+kernel-modpost-versions: $(wildcard $(LINUX_DIR)/Module.symvers)
+ @$(QUIET_CMD_ECHO) " MODPOST $(KERN_MODPOST_DIR)"
+ @echo >$(KERN_MODPOST_DIR)/modpost-running
+ @rm -f $(KERN_MODPOST_DIR)/module-changes
+ $(Q) $(KERN_MODPOST) $(MODULES_LIST:%=%$(KERN_LINK_SUFFIX)) $(^:%=-i %)
+
+$(MODULES_LIST:%=%.mod.c) : kernel-modpost-versions
+
+kernel-modpost-pass-local: $(MODULES_LIST:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX))
+ @rm -f $(KERN_MODPOST_DIR)/modpost-running
+
+$(foreach module,$(MODULES_LIST),$(eval $(call MODPOST_kern_template,$(module),$(module:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX)))))
+
+endif
+
+-include $(KERN_OBJS_DIR)/*.d
+
+endif
+
+#=====================================================================
+
+# Kernel requires its own set of configuration header-files
+ifneq ($(kernel_LIBRARIES)$(rtlinux_LIBRARIES)$(kernel_MODULES)$(rtlinux_MODULES)$(kernel_HEADERS)$(rtlinux_HEADERS)$(kernel_HEADERS)$(rtlinux_HEADERS)$(nobase_kernel_HEADERS)$(nobase_rtlinux_HEADERS)$(renamed_kernel_HEADERS)$(renamed_rtlinux_HEADERS),)
+KERN_CONFIG_HEADERS_REQUIRED = y
+endif
+
+$(eval $(call omk_pass_template, kernel-lib-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_LIBRARIES)$(rtlinux_LIBRARIES)))
+$(eval $(call omk_pass_template, kernel-mod-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_MODULES)$(rtlinux_MODULES)))
+
+kernel-modpost-pass:
+ +@if [ -e "$(KERN_MODPOST_DIR)/module-changes" -o -e "$(KERN_MODPOST_DIR)/modpost-running" ] ; \
+ then \
+ $(MAKE) --no-print-directory -C $(KERN_MODPOST_DIR) \
+ -f $(SOURCES_DIR)/Makefile KERN_RULE_TEMPLATES=y KERN_MODPOST_PASS=y $(@:%=%-local) ; \
+ fi
+
+$(eval $(call omk_pass_template, library-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(lib_LIBRARIES)$(shared_LIBRARIES)))
+$(eval $(call omk_pass_template, binary-pass, $(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(bin_PROGRAMS)$(utils_PROGRAMS)$(test_PROGRAMS)))
+
+$(eval $(call omk_pass_template,clean,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,install,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,include-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,always))
+
+check-dir::
+ @$(call mkdir_def,$(USER_BUILD_DIR))
+ @$(call mkdir_def,$(KERN_BUILD_DIR))
+ @$(call mkdir_def,$(USER_INCLUDE_DIR))
+ @$(call mkdir_def,$(KERN_INCLUDE_DIR))
+ @$(call mkdir_def,$(USER_LIB_DIR))
+ @$(call mkdir_def,$(KERN_LIB_DIR))
+ @$(call mkdir_def,$(USER_BIN_DIR))
+ @$(call mkdir_def,$(USER_UTILS_DIR))
+ @$(call mkdir_def,$(USER_TESTS_DIR))
+ @$(call mkdir_def,$(KERN_MODULES_DIR))
+ @$(call mkdir_def,$(KERN_MODPOST_DIR))
+
+install-local: # TODO
+
+$(eval $(call include-pass-template,$(USER_INCLUDE_DIR),include))
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),kernel))
+ifeq ($(CONFIG_RTLINUX),y)
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),rtlinux))
+endif
+
+
+ifdef USER_RULE_TEMPLATES
+
+# User-space static libraries and applications object files
+
+USER_SOURCES := $(sort $(USER_SOURCES))
+
+USER_GEN_SOURCES := $(sort $(USER_GEN_SOURCES))
+
+#$(warning USER_SOURCES = $(USER_SOURCES))
+
+$(foreach src,$(filter %.c,$(USER_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(USER_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(USER_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+
+$(foreach src,$(filter %.c,$(USER_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.o),)))
+
+# User-space shared libraries object files
+
+SOLIB_SOURCES := $(sort $(SOLIB_SOURCES))
+
+SOLIB_GEN_SOURCES := $(sort $(SOLIB_GEN_SOURCES))
+
+#$(warning SOLIB_SOURCES = $(SOLIB_SOURCES))
+#$(warning SOLIB_GEN_SOURCES = $(SOLIB_GEN_SOURCES))
+
+$(foreach src,$(filter %.c,$(SOLIB_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.cc,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.cxx,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.S,$(SOLIB_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.c,$(SOLIB_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+# IDL compilation
+
+USER_IDLS := $(sort $(USER_IDLS))
+
+$(foreach src,$(filter %.idl,$(USER_IDLS)),$(eval $(call COMPILE_idl_template,$(SOURCES_DIR)/$(src),$(src:%.idl=%))))
+
+endif
+
+ifdef KERN_RULE_TEMPLATES
+
+KERN_SOURCES := $(sort $(KERN_SOURCES))
+
+#$(warning KERN_SOURCES = $(KERN_SOURCES))
+
+$(foreach src,$(filter %.c,$(KERN_SOURCES)),$(eval $(call COMPILE_c_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+endif
+
+clean-local: clean-custom
+ @echo Cleaning in $(KERN_OBJS_DIR) and $(USER_OBJS_DIR)
+ @rm -f $(KERN_OBJS_DIR)/*.o $(USER_OBJS_DIR)/*.[och] $(USER_OBJS_DIR)/*.lo\
+ $(KERN_OBJS_DIR)/*.d $(USER_OBJS_DIR)/*.d \
+ $(KERN_OBJS_DIR)/*.map $(USER_OBJS_DIR)/*.map \
+ $(KERN_OBJS_DIR)/*.mod.c \
+ $(kernel_MODULES:%=$(KERN_MODPOST_DIR)/%.*) \
+ $(LOCAL_CONFIG_H:%=$(KERN_OBJS_DIR)/%) \
+ $(LOCAL_CONFIG_H:%=$(USER_OBJS_DIR)/%)
+ @if [ -e $(KERN_LIB_DIR)/kernel.mk ] ; then \
+ touch -t 200001010101 $(KERN_LIB_DIR)/kernel.mk ; \
+ fi
+
+include-pass-submakes: extra-rules-subdirs
+
+# We must go to EXTRA_RULES_SUBDIRS beofre going to any other
+# directory, since the executables compiled in EXTRA_RULES_SUBDIRS
+# might be needed there.
+include-pass-this-dir $(foreach subdir,$(SUBDIRS),include-pass-$(subdir)-subdir): extra-rules-subdirs
+
+default: include-pass library-pass binary-pass
+ifndef OMIT_KERNEL_PASSES
+# Also make kernel passes if not disabled
+default: kernel-lib-pass kernel-pass
+endif
+
+# Local Variables:
+# mode:makefile
+# End:
+ #OMK@config_h
+# Syntax: $(call BUILD_CONFIG_H_template,<stamp_dir>,<header_file_path>,<list_of_options_to_export>,<header_barrier>)
+define BUILD_CONFIG_H_template
+
+$(addprefix $(1)/,$(notdir $(addsuffix .stamp,$(2)))) : $(CONFIG_FILES)
+ @$(QUIET_CMD_ECHO) " CONFGEN $$(@:%.stamp=%)"
+ @if [ ! -d `dirname $(2).tmp` ] ; then \
+ mkdir -p `dirname $(2).tmp` ; fi
+ @echo "/* Automatically generated from */" > "$(2).tmp"
+ @echo "/* config files: $$(^:$(OUTPUT_DIR)/%=%) */" >> "$(2).tmp"
+ $(if $(DOXYGEN),@echo "/** @file */" >> "$(2).tmp")
+ @echo "#ifndef $(4)" >> "$(2).tmp"
+ @echo "#define $(4)" >> "$(2).tmp"
+ @( $(foreach x, $(shell echo '$($(3))' | tr 'x\t ' 'x\n\n' | sed -e 's/^\([^ =]*\)\(=[^ ]\+\|\)$$/\1/' ), \
+ echo '$(x).$($(x))' ; ) echo ; ) | \
+ sed -e '/^[^.]*\.n$$$$/d' -e '/^[^.]*\.$$$$/d' -e 's/^\([^.]*\)\.[ym]$$$$/\1.1/' | \
+ sed -n -e 's/^\([^.]*\)\.\(.*\)$$$$/#define \1 \2/p' \
+ >> "$(2).tmp"
+ @echo "#endif /*$(4)*/" >> "$(2).tmp"
+ @touch "$$@"
+ @if cmp --quiet "$(2).tmp" "$(2)" ; then rm "$(2).tmp"; \
+ else mv "$(2).tmp" "$(2)" ; \
+ echo "Updated configuration $(2)" ; fi
+
+endef
+
+ifdef LOCAL_CONFIG_H
+
+# This must be declared after the default cflags are assigned!
+# Override is used to override command line assignemnt.
+override CFLAGS += -I.
+$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(USER_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+
+endif
+
+# Special rules for configuration exported headers
+
+#FIXME: The directory for headers should not be specified here.
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(addprefix $(USER_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+config_h_stamp_files = $(addprefix $(USER_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(config_h_stamp_files)
+
+ifneq ($(KERN_CONFIG_HEADERS_REQUIRED),)
+
+ifdef LOCAL_CONFIG_H
+$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(KERN_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+endif
+
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(addprefix $(KERN_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+kern_config_h_stamp_files = $(addprefix $(KERN_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(kern_config_h_stamp_files)
+
+endif
+
+clean-local: clean-local-config-h
+
+clean-local-config-h:
+ @$(foreach confh,$(config_h_stamp_files) $(kern_config_h_stamp_files),\
+ if [ -e $(confh) ] ; then rm $(confh) ; fi ; \
+ )
+
+
+# Local Variables:
+# mode:makefile
+# End:
+ #OMK@qt
+ifneq ($(QT_SUBDIRS),)
+
+.PHONY: qt-subpass clean-qt distclean-qt
+
+# Usage: $(call qt_makefile_template,<qt-subdir>)
+define qt_makefile_template
+$(SOURCES_DIR)/$(1)/Makefile: $(wildcard $(SOURCES_DIR)/$(1)/*.pro)
+ cd $(SOURCES_DIR)/$(1); $(QTDIR:%=%/bin/)qmake TOP_DIR=$(OUTPUT_DIR) \
+ RELATIVE_DIR=$(RELATIVE_PREFIX)$(1) $(QTDIR:%=QTDIR=%) CC=$(CC) \
+ CXX=$(CXX) LIBS+="-L$(USER_LIB_DIR)" INCLUDEPATH+="$(USER_INCLUDE_DIR)"
+endef
+$(foreach dir,$(QT_SUBDIRS), $(eval $(call qt_makefile_template,$(dir))))
+
+qt-subpass: $(foreach dir,$(QT_SUBDIRS), $(SOURCES_DIR)/$(dir)/Makefile)
+ $(foreach dir,$(QT_SUBDIRS),\
+ $(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir) \
+ RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir) -C $(SOURCES_DIR)/$(dir) \
+ -f $(SOURCES_DIR)/$(dir)/Makefile || exit 1 ;)
+
+# Hook to binary pass
+binary-pass-submakes: qt-subpass
+
+# Hook to clean pass
+clean-local: clean-qt
+clean-qt:
+ +@$(foreach dir, $(QT_SUBDIRS), \
+ $(if $(wildcard $(SOURCES_DIR)/$(dir)/Makefile), \
+ @$(QUIET_CMD_ECHO) " CLEAN $(dir)"; \
+ $(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir) \
+ RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir) -C $(SOURCES_DIR)/$(dir) \
+ -f $(SOURCES_DIR)/$(dir)/Makefile clean|| exit 1 ;))
+
+
+# Hook to distclean
+distclean: distclean-qt
+
+# TODO: Add distclean-qt-pass to handle QT_SUBDIRS in the whole
+# tree. This way we only distclean toplevel subdirs.
+distclean-qt:
+ +@$(foreach dir, $(QT_SUBDIRS), \
+ $(if $(wildcard $(SOURCES_DIR)/$(dir)/Makefile), \
+ @$(QUIET_CMD_ECHO) " DISTCLEAN $(dir)"; \
+ $(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir) \
+ RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir) -C $(SOURCES_DIR)/$(dir) \
+ -f $(SOURCES_DIR)/$(dir)/Makefile distclean|| exit 1 ;))
+endif
+
+# Local Variables:
+# mode:makefile
+# End:
+ #OMK@sources-list
+# Rules that creates the list of files which are used during
+# compilation. The list reflects conditional compilation depending on
+# config.omk and other variables.
+
+SOURCES_LIST_FN=sources.txt
+ifndef SOURCES_LIST
+SOURCES_LIST_DIR:=$(RELATIVE_DIR)
+SOURCES_LIST:=$(OUTPUT_DIR)/$(SOURCES_LIST_DIR)/$(SOURCES_LIST_FN)
+SOURCES_LIST_D := $(LOCAL_BUILD_DIR)/$(SOURCES_LIST_FN).d
+export SOURCES_LIST SOURCES_LIST_DIR SOURCES_LIST_D
+endif
+
+ifeq ($(MAKECMDGOALS),sources-list)
+NEED_SOURCES_LIST=y
+endif
+ifeq ($(MAKECMDGOALS),TAGS)
+NEED_SOURCES_LIST=y
+endif
+ifeq ($(MAKECMDGOALS),tags)
+NEED_SOURCES_LIST=y
+endif
+
+ifeq ($(NEED_SOURCES_LIST),y) # avoid execution of find command bellow if it is not useful
+.PHONY: sources-list
+sources-list: $(SOURCES_LIST)
+
+$(SOURCES_LIST): $(CONFIG_FILES) $(shell find -name $(MAKEFILE_OMK))
+ @echo -n "" > "$(SOURCES_LIST).tmp"
+ @echo -n "" > "$(SOURCES_LIST_D).tmp"
+ @$(MAKE) --no-print-directory sources-list-pass
+ @echo "# Automatically generated list of files in '$(RELATIVE_DIR)' that are used during OMK compilation" > "$(SOURCES_LIST).tmp2"
+ @cat "$(SOURCES_LIST).tmp"|sort|uniq >> "$(SOURCES_LIST).tmp2"
+ @rm "$(SOURCES_LIST).tmp"
+ @mv "$(SOURCES_LIST).tmp2" "$(SOURCES_LIST)"
+ @echo "$(SOURCES_LIST): \\" > "$(SOURCES_LIST_D).tmp2"
+ @cat "$(SOURCES_LIST_D).tmp"|grep -v "$(SOURCES_LIST_D).tmp"|sort|uniq|\
+ sed -e 's/$$/\\/' >> "$(SOURCES_LIST_D).tmp2"
+ @rm "$(SOURCES_LIST_D).tmp"
+ @mv "$(SOURCES_LIST_D).tmp2" "$(SOURCES_LIST_D)"
+endif
+
+$(eval $(call omk_pass_template,sources-list-pass,$$(LOCAL_BUILD_DIR),,always))
+
+sources-list-pass-local:
+ @$(foreach m,$(MAKEFILE_LIST),echo ' $(m)' >> "$(SOURCES_LIST_D).tmp";)
+ @$(foreach h,$(include_HEADERS) $(nobase_include_HEADERS) $(kernel_HEADERS),\
+ echo "$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%)/$(h)" >> "$(SOURCES_LIST).tmp";)
+ @$(foreach ch,$(config_include_HEADERS), \
+ echo "$(USER_INCLUDE_DIR:$(OUTPUT_DIR)/$(addsuffix /,$(SOURCES_LIST_DIR))%=%)/$(ch)" >> "$(SOURCES_LIST).tmp";)
+ @$(foreach h,$(renamed_include_HEADERS),echo '$(h)'|sed -e 's/\(.*\)->.*/$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%)\1/' >> "$(SOURCES_LIST).tmp";)
+ @$(foreach bin,$(lib_LIBRARIES) $(shared_LIBRARIES) $(bin_PROGRAMS) $(test_PROGRAMS) $(utils_PROGRAMS) \
+ $(kernel_LIBRARIES) $(rtlinux_LIBRARIES) $(kernel_MODULES),\
+ $(foreach src,$(filter-out %.o,$($(bin)_SOURCES)),echo "$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))$(src)" >> "$(SOURCES_LIST).tmp";))
+
+############ TAGS ###########
+
+ifeq ($(MAKECMDGOALS),TAGS)
+ETAGS=etags
+TAGS_CMD = $(ETAGS)
+TAGS: $(SOURCES_LIST)
+ @$(MAKE) --no-print-directory do-tags
+endif
+ifeq ($(MAKECMDGOALS),tags)
+CTAGS=ctags -N
+TAGS_CMD = $(CTAGS)
+tags: $(SOURCES_LIST)
+ @$(MAKE) --no-print-directory do-tags
+endif
+export TAGS_CMD
+
+ifeq ($(MAKECMDGOALS),do-tags)
+.PHONY: do-tags
+do-tags: $(shell sed -e '/^\#/d' $(SOURCES_LIST))
+ @$(QUIET_CMD_ECHO) " TAGS $(SOURCES_LIST_FN)"
+ $(Q)$(TAGS_CMD) $^
+endif
+
+############ CSCOPE ###########
+
+cscope: $(SOURCES_LIST)
+ @$(QUIET_CMD_ECHO) " CSCOPE < $(SOURCES_LIST_FN)"
+ $(Q)sed -e '/^#/d' $(SOURCES_LIST)|cscope -b -i-
+#FIXME: see doc to -i in cscope(1)
+
+# Local Variables:
+# mode:makefile
+# End:
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+backendsdir=@libdir@/orbit-2.0/idl-backends
+
+Name: ORBit-idl-2.0
+Description: ORBit-2.0 IDL Compiler Backend Interface
+Version: @ORBIT_VERSION@
+Requires: libIDL-2.0
+Libs:
+Cflags: -I${includedir}/orbit-2.0/orbit-idl
--- /dev/null
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.in by autoheader. */
+
+/* Define if HTTP connections are available */
+/* #undef ENABLE_HTTP */
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <arpa/nameser.h> header file. */
+#define HAVE_ARPA_NAMESER_H 1
+
+/* Define to 1 if you have the `basename' function. */
+#define HAVE_BASENAME 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+/* #undef HAVE_DOPRNT */
+
+/* Define to 1 if you have the <endian.h> header file. */
+#define HAVE_ENDIAN_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if getaddrinfo() is available */
+#define HAVE_GETADDRINFO 1
+
+/* Define if getnameinfo() is available */
+#define HAVE_GETNAMEINFO 1
+
+/* Define if inet_pton() is available */
+#define HAVE_INET_PTON 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `nsl' library (-lnsl). */
+/* #undef HAVE_LIBNSL */
+
+/* Define to 1 if you have the `resolv' library (-lresolv). */
+/* #undef HAVE_LIBRESOLV */
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+/* #undef HAVE_LIBSOCKET */
+
+/* Define to 1 if you have the <linux/socket.h> header file. */
+#define HAVE_LINUX_SOCKET_H 1
+
+/* Define to 1 if you have the <machine/endian.h> header file. */
+/* #undef HAVE_MACHINE_ENDIAN_H */
+
+/* Define to 1 if you have the <machine/types.h> header file. */
+/* #undef HAVE_MACHINE_TYPES_H */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+#define HAVE_NETINET_TCP_H 1
+
+/* Define to 1 if you have the `poll' function. */
+#define HAVE_POLL 1
+
+/* Define to 1 if you have the <resolv.h> header file. */
+#define HAVE_RESOLV_H 1
+
+/* Define if sockaddr has sa_len member */
+/* #undef HAVE_SOCKADDR_SA_LEN */
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#define HAVE_STDDEF_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#define HAVE_SYSLOG_H 1
+
+/* Define to 1 if you have the <sys/endian.h> header file. */
+/* #undef HAVE_SYS_ENDIAN_H */
+
+/* Define to 1 if you have the <sys/isa_defs.h> header file. */
+/* #undef HAVE_SYS_ISA_DEFS_H */
+
+/* Define to 1 if you have the <sys/machine.h> header file. */
+/* #undef HAVE_SYS_MACHINE_H */
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+#define HAVE_SYS_POLL_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+/* #undef HAVE_SYS_SOCKIO_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define to 1 if you have the <sys/un.h> header file. */
+#define HAVE_SYS_UN_H 1
+
+/* Define to 1 if you have the <sys/utime.h> header file. */
+/* #undef HAVE_SYS_UTIME_H */
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if you have the `vprintf' function. */
+#define HAVE_VPRINTF 1
+
+/* Define to 1 if you have the <wchar.h> header file. */
+#define HAVE_WCHAR_H 1
+
+/* Define to 1 if you have the <wcstr.h> header file. */
+/* #undef HAVE_WCSTR_H */
+
+/* Define to 1 if you have the <wctype.h> header file. */
+#define HAVE_WCTYPE_H 1
+
+/* Define to 1 if you have the <winsock2.h> header file. */
+/* #undef HAVE_WINSOCK2_H */
+
+/* defined if purify is enabled */
+/* #undef ORBIT_PURIFY */
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "http://bugzilla.gnome.org/enter_bug.cgi?product=ORBit2"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "ORBit2"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "ORBit2 2.14.13"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "ORBit2"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "2.14.13"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel and VAX). */
+#if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+#elif ! defined __LITTLE_ENDIAN__
+/* # undef WORDS_BIGENDIAN */
+#endif
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* Define socklen_t to be of type size_t */
+/* #undef socklen_t */
--- /dev/null
+/*
+ * orbit-idl-backend.c:
+ *
+ * Copyright (C) 2002 Sun Microsystems, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * Mark McLoughlin <mark@skynet.ie>
+ */
+
+#include "config.h"
+
+#include "forb-idl-backend.h"
+#include "forb-idl2.h"
+
+#include <glib.h>
+#include <gmodule.h>
+
+#if 0
+static GSList *
+prepend_from_env_var (GSList *paths,
+ const char *env_var)
+{
+ char *val;
+ char **strv;
+ int i;
+
+ if (!(val = getenv ("GNOME2_PATH")))
+ return paths;
+
+ strv = g_strsplit (val, ";", -1);
+ for (i = 0; strv [i]; i++)
+ paths = g_slist_prepend (
+ paths, g_strconcat (strv [i], "/lib/forb-2.0/idl-backends", NULL));
+
+ g_strfreev (strv);
+
+ return paths;
+}
+
+static ForbIDLBackendFunc
+load_language_backend (const char *path,
+ const char *language)
+{
+ ForbIDLBackendFunc retval = NULL;
+ GModule *module;
+ char *modname;
+ char *modpath;
+
+ modname = g_strconcat ("forb-idl-backend-", language, NULL);
+ modpath = g_module_build_path (path, modname);
+ g_free (modname);
+
+ if (!(module = g_module_open (modpath, G_MODULE_BIND_LAZY))) {
+ g_free (modpath);
+ return NULL;
+ }
+
+ if (!g_module_symbol (module, "forb_idl_backend_func", (gpointer *) &retval))
+ g_warning ("backend %s has no \"forb_idl_backend_func\" defined", modpath);
+
+ g_free (modpath);
+
+ return retval;
+}
+
+gboolean
+forb_idl_backend_output (OIDL_Run_Info *rinfo,
+ IDL_tree tree)
+{
+ ForbIDLBackendFunc func = NULL;
+ ForbIDLBackendContext context;
+ GSList *paths = NULL;
+ GSList *l;
+
+ paths = prepend_from_env_var (paths, "GNOME2_PATH");
+ paths = prepend_from_env_var (paths, "FORB_BACKENDS_PATH");
+
+ paths = g_slist_prepend (paths, g_strdup (FORB_BACKENDS_DIR));
+
+ if (rinfo->backend_directory)
+ paths = g_slist_prepend (paths, g_strdup (rinfo->backend_directory));
+
+ for (l = paths; l; l = l->next) {
+ func = load_language_backend (l->data, rinfo->output_language);
+
+ g_free (l->data);
+
+ if (func)
+ break;
+ }
+
+ g_slist_free (paths);
+
+ if (!func) {
+ g_warning("idl-compiler backend not found.");
+ return FALSE;
+ }
+
+ context.tree = tree;
+ context.filename = rinfo->input_filename;
+ context.do_stubs = (rinfo->enabled_passes & OUTPUT_STUBS ? 1 : 0);
+ context.do_skels = (rinfo->enabled_passes & OUTPUT_SKELS ? 1 : 0);
+ context.do_common = (rinfo->enabled_passes & OUTPUT_COMMON ? 1 : 0);
+
+ return func (&context);
+}
+#endif
--- /dev/null
+/*
+ * forb-idl-backend.h:
+ *
+ * Copyright (C) 2002 Sun Microsystems, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * Mark McLoughlin <mark@skynet.ie>
+ */
+
+#ifndef __FORB_IDL_BACKEND_H__
+#define __FORB_IDL_BACKEND_H__
+
+#include <glib.h>
+#include <libIDL/IDL.h>
+
+G_BEGIN_DECLS
+
+typedef struct {
+ IDL_tree tree;
+ char *filename;
+
+ guint do_stubs : 1;
+ guint do_skels : 1;
+ guint do_common : 1;
+} ForbIDLBackendContext;
+
+/* Define a function with this signature and named "forb_idl_backend_func"
+ * in the module.
+ *
+ * The module should be named libforb-idl-backend-$(language).so. $(language)
+ * is defined with the --lang idl-compiler command line option.
+ *
+ * Modules are searched for in the following order:
+ * 1. The directory specified by the --backenddir option.
+ * 2. %(prefix)/lib/forb-2.0/idl-backends/, where $(prefix) is the prefix
+ * Forb2 was installed in.
+ * 3. For each $(path) in the $FORB_BACKENDS_PATH environment variable,
+ * the module is searched for in $(path)/lib/forb-2.0/idl-backends/
+ * 4. For each $(path) in the $GNOME2_PATH environment variable,
+ * the module is searched for in $(path)/lib/forb-2.0/idl-backends/
+ */
+
+typedef gboolean (*ForbIDLBackendFunc) (ForbIDLBackendContext *context);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+#include "config.h"
+
+#include "forb-idl-c-backend.h"
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <glib/gstdio.h>
+
+static FILE *out_for_pass(const char *input_filename, int pass,
+ OIDL_Run_Info *rinfo);
+
+gboolean
+forb_idl_output_c (IDL_tree tree,
+ OIDL_Run_Info *rinfo)
+{
+ int i;
+ char *ctmp;
+ OIDL_C_Info ci;
+
+ ci.base_name = g_path_get_basename(rinfo->input_filename);
+ ctmp = strrchr(ci.base_name, '.');
+ g_assert(ctmp);
+ *ctmp = '\0';
+
+ ci.c_base_name = g_strdup(ci.base_name);
+ if(!isalpha((guchar)ci.c_base_name[0]))
+ ci.c_base_name[0] = '_';
+ for(i = 0; ci.c_base_name[i]; i++) {
+ if(!isalnum((guchar)ci.c_base_name[i])) ci.c_base_name[i] = '_';
+ }
+
+ ci.ext_dcls = g_string_new(NULL);
+
+ ci.do_impl_hack = 1;
+ ci.do_skel_defs = rinfo->do_skel_defs;
+ for(i = 0; i < OUTPUT_NUM_PASSES; i++) {
+ if( (1 << i) & rinfo->enabled_passes) {
+ ci.fh = out_for_pass(rinfo->input_filename, 1 << i, rinfo);
+
+ switch(1 << i) {
+ case OUTPUT_STUBS:
+ forb_idl_output_c_stubs(tree, rinfo, &ci);
+ break;
+ case OUTPUT_SKELS:
+ forb_idl_output_c_skeletons(tree, rinfo, &ci);
+ break;
+ case OUTPUT_COMMON:
+ forb_idl_output_c_common(tree, rinfo, &ci);
+ break;
+ case OUTPUT_HEADERS:
+ forb_idl_output_c_headers(tree, rinfo, &ci);
+ break;
+ case OUTPUT_SKELIMPL:
+ forb_idl_output_c_skelimpl(tree, rinfo, &ci);
+ break;
+ case OUTPUT_IMODULE:
+ forb_idl_output_c_imodule(tree, rinfo, &ci);
+ break;
+ case OUTPUT_DEPS:
+ forb_idl_output_c_deps(tree, rinfo, &ci);
+ break;
+ }
+ fclose(ci.fh);
+ }
+ }
+ g_string_free(ci.ext_dcls,TRUE);
+
+ return TRUE;
+}
+
+char *
+forb_idl_c_filename_for_pass (const char *input_filename,
+ int pass)
+{
+ char *filename;
+ char *basename;
+ char *dot;
+ const char *tack_on = NULL;
+
+ basename = g_path_get_basename (input_filename);
+ dot = strrchr (basename, '.');
+ if (dot != NULL)
+ *dot = '\0';
+
+ switch (pass) {
+ case OUTPUT_STUBS:
+ tack_on = "-stubs.c";
+ break;
+ case OUTPUT_SKELS:
+ tack_on = "-skels.c";
+ break;
+ case OUTPUT_COMMON:
+ tack_on = "-common.c";
+ break;
+ case OUTPUT_HEADERS:
+ tack_on = ".h";
+ break;
+ case OUTPUT_SKELIMPL:
+ tack_on = "-skelimpl.c";
+ break;
+ case OUTPUT_IMODULE:
+ tack_on = "-imodule.c";
+ break;
+ default:
+ g_error("Unknown output pass");
+ break;
+ }
+
+ filename = g_strconcat (basename, tack_on, NULL);
+ g_free (basename);
+
+ return filename;
+}
+
+static FILE *
+out_for_pass (const char *input_filename,
+ int pass,
+ OIDL_Run_Info *rinfo)
+{
+ FILE *fp;
+ char *output_filename;
+ gchar *output_full_path = NULL;
+
+
+ if ((strlen(rinfo->output_directory)) && (!g_file_test (rinfo->output_directory, G_FILE_TEST_IS_DIR))) {
+ g_error ("ouput directory '%s' does not exist",
+ rinfo->output_directory);
+ return NULL;
+ }
+
+ if (pass == OUTPUT_DEPS) {
+ if (!g_file_test (".deps", G_FILE_TEST_IS_DIR)) {
+ if (g_mkdir (".deps", 0775) < 0) {
+ g_warning ("failed to create '.deps' directory '%s'",
+ g_strerror (errno));
+ return NULL;
+ }
+ }
+
+ if (rinfo->deps_file)
+ fp = g_fopen (rinfo->deps_file, "w");
+ else
+ fp = NULL;
+
+ if (fp == NULL)
+ g_warning ("failed to open '%s': %s\n",
+ rinfo->deps_file, g_strerror (errno));
+
+ } else {
+ output_filename = forb_idl_c_filename_for_pass (input_filename, pass);
+ output_full_path = g_build_path (G_DIR_SEPARATOR_S, rinfo->output_directory, output_filename, NULL);
+ g_free (output_filename);
+
+ fp = g_fopen (output_full_path, "w+");
+ if (fp == NULL)
+ g_error ("failed to fopen '%s': %s\n", output_full_path, g_strerror(errno));
+
+ g_free (output_full_path);
+ }
+
+ return fp;
+}
--- /dev/null
+#ifndef FORB_IDL_C_BACKEND_H
+#define FORB_IDL_C_BACKEND_H
+
+#include "forb-idl2.h"
+#include <stdbool.h>
+
+#define OIDL_C_WARNING "/*\n * This file was generated by forb-idl - DO NOT EDIT!\n */\n\n"
+
+typedef struct {
+ char *base_name;
+ char *c_base_name;
+ FILE *fh;
+ GString *ext_dcls;
+ gboolean do_impl_hack;
+ gboolean do_skel_defs;
+} OIDL_C_Info;
+
+enum forb_ser {
+ DESERIALIZE,
+ SERIALIZE
+};
+
+void
+forb_cbe_write_ser_var(FILE *of, IDL_tree ts, IDL_tree name, bool use_name,
+ char *var_prefix, enum forb_ser serialization);
+
+
+gboolean forb_idl_output_c (IDL_tree tree,
+ OIDL_Run_Info *rinfo);
+void forb_idl_output_c_headers (IDL_tree tree,
+ OIDL_Run_Info *rinfo,
+ OIDL_C_Info *ci);
+void forb_idl_output_c_stubs (IDL_tree tree,
+ OIDL_Run_Info *rinfo,
+ OIDL_C_Info *ci);
+void forb_idl_output_c_skeletons (IDL_tree tree,
+ OIDL_Run_Info *rinfo,
+ OIDL_C_Info *ci);
+void forb_idl_output_c_common (IDL_tree tree,
+ OIDL_Run_Info *rinfo,
+ OIDL_C_Info *ci);
+void forb_idl_output_c_skelimpl (IDL_tree tree,
+ OIDL_Run_Info *rinfo,
+ OIDL_C_Info *ci);
+void forb_idl_output_c_imodule (IDL_tree tree,
+ OIDL_Run_Info *rinfo,
+ OIDL_C_Info *ci);
+void forb_idl_output_c_deps (IDL_tree tree,
+ OIDL_Run_Info *rinfo,
+ OIDL_C_Info *ci);
+
+void forb_output_typecode (OIDL_C_Info *ci, IDL_tree ts);
+
+char *forb_idl_c_filename_for_pass (const char *input_filename, int pass);
+
+/* utils */
+char *forb_cbe_get_typespec_str (IDL_tree tree);
+void forb_cbe_write_typespec (FILE *of,
+ IDL_tree tree);
+void forb_cbe_write_param_typespec (FILE *of,
+ IDL_tree tree);
+void forb_cbe_op_write_proto (FILE *of,
+ IDL_tree op,
+ const char *nom_prefix,
+ gboolean for_epv);
+IDL_tree forb_cbe_get_typespec (IDL_tree tree);
+void forb_cbe_write_const (FILE *of,
+ IDL_tree tree);
+gboolean forb_cbe_type_is_fixed_length (IDL_tree ts);
+gboolean forb_cbe_type_is_builtin (IDL_tree tree);
+void forb_cbe_id_define_hack (FILE *fh,
+ const char *def_prefix,
+ const char *def_name,
+ const char *def_value);
+void forb_cbe_id_cond_hack (FILE *fh,
+ const char *def_prefix,
+ const char *def_name,
+ const char *def_value);
+char *forb_cbe_get_typecode_name (IDL_tree tree);
+void forb_cbe_flatten_args (IDL_tree tree,
+ FILE *of,
+ const char *name);
+void forb_cbe_unflatten_args (IDL_tree tree,
+ FILE *of,
+ const char *name);
+#endif
--- /dev/null
+#include "config.h"
+
+#include "forb-idl-c-backend.h"
+
+#include <string.h>
+
+typedef struct {
+ IDL_tree tree;
+ GSList *methods; /* IDLN_OP_DCLs */
+} Interface;
+
+typedef struct {
+ FILE *of;
+ IDL_tree cur_node; /* Current Interface */
+ char *cur_id;
+ guint parents;
+} CCSmallInterfaceTraverseInfo;
+
+/* TypeCodes */
+
+/* static void cc_output_typecodes (IDL_tree tree, */
+/* OIDL_C_Info *ci); */
+
+/* static void */
+/* cc_typecode_prep_sequence (IDL_tree tree, */
+/* OIDL_C_Info *ci) */
+/* { */
+/* IDL_tree seq_type; */
+/* IDL_tree fake_seq_type = NULL; */
+/* char *type_str; */
+/* char *seq_type_str; */
+
+/* seq_type = forb_cbe_get_typespec (IDL_TYPE_SEQUENCE (tree).simple_type_spec); */
+
+/* if (IDL_NODE_TYPE (seq_type) != IDLN_INTERFACE) */
+/* seq_type_str = forb_cbe_get_typespec_str (seq_type); */
+/* else { */
+/* seq_type_str = g_strdup ("CORBA_Object"); */
+/* fake_seq_type = IDL_type_object_new (); */
+/* } */
+
+/* type_str = forb_cbe_get_typespec_str (IDL_TYPE_SEQUENCE (tree).simple_type_spec); */
+
+/* if (strcmp (type_str, seq_type_str)) { */
+/* IDL_tree fake_seq; */
+
+/* fake_seq = IDL_type_sequence_new ( */
+/* fake_seq_type ? fake_seq_type : seq_type, */
+/* NULL); */
+/* IDL_NODE_UP (fake_seq) = IDL_NODE_UP (tree); */
+
+/* cc_output_typecodes (fake_seq, ci); */
+
+/* IDL_TYPE_SEQUENCE (fake_seq).simple_type_spec = NULL; */
+/* IDL_tree_free (fake_seq); */
+/* } */
+
+/* if (fake_seq_type) */
+/* IDL_tree_free (fake_seq_type); */
+
+/* g_free (type_str); */
+/* g_free (seq_type_str); */
+/* } */
+
+/* static gboolean */
+/* cc_output_tc_walker (IDL_tree_func_data *tfd, */
+/* OIDL_C_Info *ci) */
+/* { */
+/* IDL_tree tree = tfd->tree; */
+
+/* switch(IDL_NODE_TYPE (tree)) { */
+/* case IDLN_CONST_DCL: */
+/* case IDLN_ATTR_DCL: */
+/* case IDLN_OP_DCL: */
+/* return FALSE; /\* dont recurse into these *\/ */
+
+/* case IDLN_TYPE_SEQUENCE: */
+/* if (!tfd->step) { */
+/* cc_typecode_prep_sequence (tree, ci); */
+/* break; */
+/* } */
+/* /\* drop through *\/ */
+
+/* case IDLN_INTERFACE: */
+/* case IDLN_EXCEPT_DCL: */
+/* case IDLN_TYPE_STRUCT: */
+/* case IDLN_TYPE_UNION: */
+/* case IDLN_TYPE_DCL: */
+/* case IDLN_TYPE_ENUM: */
+/* case IDLN_TYPE_FIXED: */
+/* if (tfd->step) */
+/* forb_output_typecode (ci, tree); */
+/* break; */
+/* default: */
+/* break; */
+/* } */
+
+/* return TRUE; /\* continue walking *\/ */
+/* } */
+
+/* static void */
+/* cc_output_typecodes (IDL_tree tree, */
+/* OIDL_C_Info *ci) */
+/* { */
+/* IDL_tree_walk2 (tree, NULL, IDL_WalkF_TypespecOnly, */
+/* (IDL_tree_func) cc_output_tc_walker, */
+/* (IDL_tree_func) cc_output_tc_walker, */
+/* ci); */
+/* } */
+
+/* serialization */
+
+static void
+cc_output_ser_struct(OIDL_C_Info *ci,
+ IDL_tree s)
+{
+ IDL_tree cur, curmem;
+ char *id;
+ id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_TYPE_STRUCT(s).ident), "_", 0);
+
+ fprintf(ci->fh, "CORBA_boolean %s_serialize(FORB_CDR_Codec *codec, const %s *ptr)\n", id, id);
+ fprintf(ci->fh, "{\n");
+ for(cur = IDL_TYPE_STRUCT(s).member_list; cur; cur = IDL_LIST(cur).next) {
+ for(curmem = IDL_MEMBER(IDL_LIST(cur).data).dcls; curmem; curmem = IDL_LIST(curmem).next) {
+ forb_cbe_write_ser_var(
+ ci->fh,
+ IDL_MEMBER(IDL_LIST(cur).data).type_spec,
+ IDL_LIST(curmem).data,
+ true,
+ "ptr->",
+ SERIALIZE);
+ }
+ }
+
+ fprintf(ci->fh, " return CORBA_TRUE;\n"
+ "ser_exception:\n"
+ " return CORBA_FALSE;\n"
+ "}\n\n");
+
+ fprintf(ci->fh, "CORBA_boolean %s_deserialize(FORB_CDR_Codec *codec, %s *ptr)\n", id, id);
+ fprintf(ci->fh, "{\n");
+ for(cur = IDL_TYPE_STRUCT(s).member_list; cur; cur = IDL_LIST(cur).next) {
+ for(curmem = IDL_MEMBER(IDL_LIST(cur).data).dcls; curmem; curmem = IDL_LIST(curmem).next) {
+ forb_cbe_write_ser_var(
+ ci->fh,
+ IDL_MEMBER(IDL_LIST(cur).data).type_spec,
+ IDL_LIST(curmem).data,
+ true,
+ "ptr->",
+ DESERIALIZE);
+ }
+ }
+
+ fprintf(ci->fh, " return CORBA_TRUE;\n"
+ "ser_exception:\n"
+ " return CORBA_FALSE;\n"
+ "}\n\n");
+
+
+ g_free(id);
+}
+
+static void
+cc_output_ser_seqence(OIDL_C_Info *ci,
+ IDL_tree s)
+{
+ //IDL_tree cur, curmem;
+ char *id, *type;
+ IDL_tree tts;
+ gboolean fake_if;
+ id = forb_cbe_get_typespec_str(s);
+ type = forb_cbe_get_typespec_str(IDL_TYPE_SEQUENCE(s).simple_type_spec);
+/*{
+ CORBA_boolean r;
+ int i;
+ r = CORBA_unsigned_long_serialize(codec, (val)->_length);
+ for (i=0; i<(val)->_length && r; i++)
+ r = type ## _serialize(codec, &((val)->_buffer[i]));
+}*/
+ tts = forb_cbe_get_typespec(IDL_TYPE_SEQUENCE(s).simple_type_spec);
+ fake_if = (IDL_NODE_TYPE(tts) == IDLN_INTERFACE);
+ if (fake_if) {
+ /* Header file already contains defines for CORBA_sequence_Object_[de]serialize */
+ return;
+ }
+
+ fprintf(ci->fh, "CORBA_boolean %s_serialize(FORB_CDR_Codec *codec, const %s *seq)\n", id, id);
+ fprintf(ci->fh, "{\n"
+ " int i;\n"
+ " CORBA_boolean ok;\n"
+ " ok = CORBA_unsigned_long_serialize(codec, &seq->_length);\n"
+ " for (i = 0; i<seq->_length && ok; i++)\n");
+ fprintf(ci->fh, " ok = %s_serialize(codec, &(seq->_buffer[i]));\n", type);
+
+ fprintf(ci->fh, " return ok;\n"
+ "}\n\n");
+
+ fprintf(ci->fh, "CORBA_boolean %s_deserialize(FORB_CDR_Codec *codec, %s *seq)\n", id, id);
+ fprintf(ci->fh, "{\n"
+ " CORBA_unsigned_long i;\n"
+ " CORBA_boolean ok;\n"
+ " ok = CORBA_unsigned_long_deserialize(codec, &i);\n"
+ " if (ok) {\n"
+ " ok = forb_sequence_alloc_buf(seq, i);\n"
+ " seq->_length = i;\n"
+ " CORBA_sequence_set_release(seq, CORBA_TRUE);\n"
+ " }\n"
+ " for (i = 0; i<seq->_length && ok; i++)\n");
+ fprintf(ci->fh, " ok = %s_deserialize(codec, &(seq->_buffer[i]));\n", type);
+
+ fprintf(ci->fh, " return ok;\n"
+ "}\n\n");
+
+ g_free(id);
+ g_free(type);
+}
+
+static void
+cc_output_ser_typedef_array(OIDL_C_Info *ci,
+ IDL_tree tree)
+{
+ IDL_tree cur;
+ char *id;
+
+ for(cur = IDL_TYPE_DCL(tree).dcls; cur; cur = IDL_LIST(cur).next) {
+ if (IDL_NODE_TYPE(IDL_LIST(cur).data) == IDLN_TYPE_ARRAY) {
+ id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_TYPE_ARRAY(IDL_LIST(cur).data).ident), "_", 0);
+ fprintf(ci->fh, "CORBA_boolean %s_serialize(FORB_CDR_Codec *codec, const %s array)\n", id, id);
+ fprintf(ci->fh, "{\n");
+ forb_cbe_write_ser_var(
+ ci->fh,
+ IDL_TYPE_DCL(tree).type_spec,
+ IDL_LIST(cur).data,
+ false,
+ "array",
+ SERIALIZE);
+ fprintf(ci->fh, " return CORBA_TRUE;\n"
+ "ser_exception:\n"
+ " return CORBA_FALSE;\n"
+ "}\n\n");
+
+ fprintf(ci->fh, "CORBA_boolean %s_deserialize(FORB_CDR_Codec *codec, %s array)\n", id, id);
+ fprintf(ci->fh, "{\n");
+ forb_cbe_write_ser_var(
+ ci->fh,
+ IDL_TYPE_DCL(tree).type_spec,
+ IDL_LIST(cur).data,
+ false,
+ "array",
+ DESERIALIZE);
+ fprintf(ci->fh, " return CORBA_TRUE;\n"
+ "ser_exception:\n"
+ " return CORBA_FALSE;\n"
+ "}\n\n");
+ g_free(id);
+ }
+ }
+}
+
+void
+forb_output_serialization (OIDL_C_Info *ci,
+ IDL_tree node)
+{
+ switch (IDL_NODE_TYPE (node)) {
+ case IDLN_TYPE_DCL:
+ cc_output_ser_typedef_array(ci, node);
+ break;
+ case IDLN_TYPE_STRUCT:
+ cc_output_ser_struct(ci, node);
+ break;
+ case IDLN_TYPE_UNION:
+ case IDLN_TYPE_ENUM:
+ case IDLN_EXCEPT_DCL:
+ case IDLN_INTERFACE:
+ break;
+ case IDLN_TYPE_SEQUENCE:
+ cc_output_ser_seqence(ci, node);
+ break;
+ default:
+ g_error ("You can't produce a serialization for a %s",
+ IDL_tree_type_names[IDL_NODE_TYPE (node)]);
+ }
+
+/* tci.ts = node; */
+/* tci.structname = forb_generate_tcstruct_name (node); */
+/* tci.substructname = NULL; */
+/* tci.array_gen_ctr = 0; */
+
+/* cbe_tc_generate (ci, &tci); */
+
+/* g_free (tci.structname); */
+}
+
+static gboolean
+cc_output_serialization_walker (IDL_tree_func_data *tfd,
+ OIDL_C_Info *ci)
+{
+ IDL_tree tree = tfd->tree;
+
+ switch(IDL_NODE_TYPE (tree)) {
+ case IDLN_CONST_DCL:
+ case IDLN_ATTR_DCL:
+ case IDLN_OP_DCL:
+ return FALSE; /* dont recurse into these */
+
+ case IDLN_TYPE_SEQUENCE:
+/* if (!tfd->step) { */
+/* cc_typecode_prep_sequence (tree, ci); */
+/* break; */
+/* } */
+ /* drop through */
+
+ case IDLN_INTERFACE:
+ case IDLN_EXCEPT_DCL:
+ case IDLN_TYPE_STRUCT:
+ case IDLN_TYPE_UNION:
+ case IDLN_TYPE_DCL:
+ case IDLN_TYPE_ENUM:
+ case IDLN_TYPE_FIXED:
+ if (tfd->step)
+ forb_output_serialization (ci, tree);
+ break;
+ case IDLN_SRCFILE:
+ if (!IDL_SRCFILE(tree).isTop) {
+ return FALSE;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return TRUE; /* continue walking */
+}
+
+static void
+cc_output_serialization (IDL_tree tree,
+ OIDL_C_Info *ci)
+{
+ IDL_tree_walk2 (tree, NULL, IDL_WalkF_TypespecOnly,
+ (IDL_tree_func) cc_output_serialization_walker,
+ (IDL_tree_func) cc_output_serialization_walker,
+ ci);
+}
+
+
+
+/* class ids */
+
+/* static void */
+/* cc_output_class_id (IDL_tree tree, */
+/* OIDL_Run_Info *rinfo, */
+/* OIDL_C_Info *ci) */
+/* { */
+/* char *iface_id; */
+
+/* iface_id = IDL_ns_ident_to_qstring ( */
+/* IDL_IDENT_TO_NS (IDL_INTERFACE (tree).ident), "_", 0); */
+
+/* fprintf (ci->fh, "\n#ifndef FORB_IDL_C_IMODULE_%s\n",ci->c_base_name); */
+/* fprintf (ci->fh, "CORBA_unsigned_long %s__classid = 0;\n", iface_id); */
+/* fprintf (ci->fh, "#endif\n"); */
+
+/* g_free (iface_id); */
+/* } */
+
+/* static void */
+/* cc_output_class_ids (IDL_tree tree, */
+/* OIDL_Run_Info *rinfo, */
+/* OIDL_C_Info *ci) */
+/* { */
+/* if (!tree || (tree->declspec & IDLF_DECLSPEC_PIDL)) */
+/* return; */
+
+/* switch (IDL_NODE_TYPE (tree)) { */
+/* case IDLN_MODULE: */
+/* cc_output_class_ids (IDL_MODULE (tree).definition_list, rinfo, ci); */
+/* break; */
+/* case IDLN_LIST: { */
+/* IDL_tree node; */
+
+/* for (node = tree; node; node = IDL_LIST (node).next) */
+/* cc_output_class_ids (IDL_LIST (node).data, rinfo, ci); */
+/* break; */
+/* } */
+/* case IDLN_INTERFACE: */
+/* cc_output_class_id (tree, rinfo, ci); */
+/* break; */
+/* default: */
+/* break; */
+/* } */
+/* } */
+
+/* IInterfaces */
+
+/* static void */
+/* cc_output_iargs (FILE *of, const char *method, IDL_tree tree) */
+/* { */
+/* IDL_tree sub; */
+/* int arg_count = 0; */
+
+/* /\* Build a list of IArgs *\/ */
+/* for (sub = IDL_OP_DCL (tree).parameter_dcls; sub; */
+/* sub = IDL_LIST (sub).next) { */
+/* IDL_tree parm; */
+/* char *tc; */
+
+/* if (!arg_count) */
+/* fprintf (of, "static Forb_IArg %s__arginfo [] = {\n", method); */
+
+/* parm = IDL_LIST(sub).data; */
+
+/* fprintf (of, "\t{ "); */
+
+/* /\* TypeCode tc *\/ */
+/* tc = forb_cbe_get_typecode_name ( */
+/* IDL_PARAM_DCL (parm).param_type_spec); */
+/* if (!tc) { */
+/* g_warning ("Can't get typecode"); */
+/* tc = g_strdup ("NULL /\* no typecode *\/"); */
+/* } */
+/* fprintf (of, "%s, ", tc); */
+
+/* /\* IArgFlag flags *\/ */
+/* switch (IDL_PARAM_DCL (parm).attr) { */
+/* case IDL_PARAM_IN: */
+/* fprintf (of, " Forb_I_ARG_IN "); */
+/* break; */
+/* case IDL_PARAM_OUT: */
+/* fprintf (of, " Forb_I_ARG_OUT "); */
+/* break; */
+/* case IDL_PARAM_INOUT: */
+/* fprintf (of, " Forb_I_ARG_INOUT "); */
+/* break; */
+/* } */
+
+/* if (forb_cbe_type_is_fixed_length ( */
+/* IDL_PARAM_DCL (parm).param_type_spec)) */
+/* fprintf (of, "| Forb_I_COMMON_FIXED_SIZE"); */
+
+/* else if (IDL_PARAM_DCL(parm).attr == IDL_PARAM_OUT) { */
+
+/* IDL_tree ts = forb_cbe_get_typespec ( */
+/* IDL_PARAM_DCL (parm).param_type_spec); */
+
+/* switch(IDL_NODE_TYPE (ts)) { */
+/* case IDLN_TYPE_STRUCT: */
+/* case IDLN_TYPE_UNION: */
+/* case IDLN_TYPE_ARRAY: */
+/* /\* fprintf (of, "| FORB_I_ARG_FIXED");*\/ */
+/* break; */
+/* default: */
+/* break; */
+/* }; */
+/* } */
+
+/* fprintf (of, ", "); */
+
+/* /\* string name *\/ */
+/* fprintf (of, "(char *)\"%s\"", IDL_IDENT (IDL_PARAM_DCL ( */
+/* IDL_LIST (sub).data).simple_declarator).str); */
+
+/* fprintf (of, " }%s\n", IDL_LIST (sub).next ? "," : ""); */
+
+/* g_free (tc); */
+/* arg_count++; */
+/* } */
+
+/* if (arg_count) */
+/* fprintf (of, "};\n"); */
+/* } */
+
+/* static void */
+/* cc_output_contexts (FILE *of, const char *method, IDL_tree tree) */
+/* { */
+/* /\* Build a list of contest names *\/ */
+/* if (IDL_OP_DCL (tree).context_expr) { */
+/* IDL_tree curitem; */
+
+/* fprintf (of, "/\* Exceptions *\/\n"); */
+/* fprintf (of, "static CORBA_string %s__contextinfo [] = {\n", */
+/* method); */
+
+/* for (curitem = IDL_OP_DCL (tree).context_expr; curitem; */
+/* curitem = IDL_LIST (curitem).next) { */
+/* fprintf (of, "\"%s\"%c", */
+/* IDL_STRING (IDL_LIST (curitem).data).value, */
+/* IDL_LIST (curitem).next ? ',' : ' '); */
+/* } */
+
+/* fprintf (of, "};\n"); */
+/* } */
+/* } */
+
+/* static void */
+/* cc_output_exceptinfo (FILE *of, const char *method, IDL_tree tree) */
+/* { */
+/* /\* Build a list of exception typecodes *\/ */
+/* if (IDL_OP_DCL (tree).raises_expr) { */
+/* IDL_tree curitem; */
+
+/* fprintf (of, "/\* Exceptions *\/\n"); */
+/* fprintf (of, "static CORBA_TypeCode %s__exceptinfo [] = {\n", */
+/* method); */
+
+/* for (curitem = IDL_OP_DCL (tree).raises_expr; curitem; */
+/* curitem = IDL_LIST(curitem).next) { */
+/* char *type_id; */
+/* IDL_tree curnode = IDL_LIST(curitem).data; */
+
+/* type_id = forb_cbe_get_typecode_name (curnode); */
+/* fprintf (of, "\t%s,\n", type_id); */
+/* g_free (type_id); */
+/* } */
+/* fprintf (of, "\tNULL\n};\n"); */
+/* } */
+/* } */
+
+/* static void */
+/* cc_output_method_bits (IDL_tree tree, const char *id, OIDL_C_Info *ci) */
+/* { */
+/* FILE *of = ci->fh; */
+/* char *fullname; */
+
+/* fullname = g_strconcat (id, "_", IDL_IDENT ( */
+/* IDL_OP_DCL (tree).ident).str, NULL); */
+
+/* cc_output_iargs (of, fullname, tree); */
+
+/* cc_output_contexts (of, fullname, tree); */
+
+/* cc_output_exceptinfo (of, fullname, tree); */
+
+/* g_free (fullname); */
+/* } */
+
+/* static void */
+/* cc_output_method (FILE *of, IDL_tree tree, const char *id) */
+/* { */
+/* int arg_count; */
+/* int except_count; */
+/* int context_count; */
+/* const char *method; */
+/* char *fullname; */
+
+/* fullname = g_strconcat (id, "_", IDL_IDENT ( */
+/* IDL_OP_DCL (tree).ident).str, NULL); */
+
+/* arg_count = IDL_list_length (IDL_OP_DCL (tree).parameter_dcls); */
+/* except_count = IDL_list_length (IDL_OP_DCL (tree).raises_expr); */
+/* context_count = IDL_list_length (IDL_OP_DCL (tree).context_expr); */
+
+/* fprintf (of, "\t{\n"); */
+
+/* /\* IArgs arguments *\/ */
+/* if (arg_count) */
+/* fprintf (of, "\t\t{ %d, %d, %s__arginfo, FALSE },\n", */
+/* arg_count, arg_count, fullname); */
+/* else */
+/* fprintf (of, "\t\t{ 0, 0, NULL, FALSE },\n"); */
+
+/* /\* IContexts contexts *\/ */
+/* if (context_count) */
+/* fprintf (of, "\t\t{ %d, %d, %s__contextinfo, FALSE },\n", */
+/* context_count, context_count, fullname); */
+/* else */
+/* fprintf (of, "\t\t{ 0, 0, NULL, FALSE },\n"); */
+
+/* /\* ITypes exceptions *\/ */
+/* if (IDL_OP_DCL (tree).raises_expr) */
+/* fprintf (of, "\t\t{ %d, %d, %s__exceptinfo, FALSE },\n", */
+/* except_count, except_count, fullname); */
+/* else */
+/* fprintf (of, "\t\t{ 0, 0, NULL, FALSE },\n"); */
+
+/* /\* TypeCode ret *\/ */
+/* if (IDL_OP_DCL (tree).op_type_spec) { */
+/* char *type_id; */
+
+/* type_id = forb_cbe_get_typespec_str ( */
+/* IDL_OP_DCL (tree).op_type_spec); */
+/* fprintf (of, "\t\tTC_%s, ", type_id); */
+/* g_free (type_id); */
+/* } else */
+/* fprintf (of, "TC_void, "); */
+
+/* /\* string name, long name_len *\/ */
+/* method = IDL_IDENT (IDL_OP_DCL (tree).ident).str; */
+/* fprintf (of, "(char *)\"%s\", %d,\n", method, strlen (method)); */
+
+/* /\* IMethodFlags flags *\/ */
+/* fprintf (of, "\t\t0"); */
+
+/* if (IDL_OP_DCL(tree).f_oneway) */
+/* fprintf (of, " | Forb_I_METHOD_1_WAY"); */
+
+/* /\* FIXME: re-scan for no_out *\/ */
+/* /\* if (no_out) */
+/* fprintf (of, " | Forb_I_METHOD_NO_OUT");*\/ */
+
+/* if (IDL_OP_DCL (tree).op_type_spec && */
+/* forb_cbe_type_is_fixed_length ( */
+/* IDL_OP_DCL (tree).op_type_spec)) */
+/* fprintf (of, "| Forb_I_COMMON_FIXED_SIZE"); */
+
+/* if (IDL_OP_DCL(tree).context_expr) */
+/* fprintf (of, "| Forb_I_METHOD_HAS_CONTEXT"); */
+
+/* fprintf (of, "\n}\n"); */
+
+/* g_free (fullname); */
+/* } */
+
+/* static void */
+/* cc_output_base_itypes(IDL_tree node, CCSmallInterfaceTraverseInfo *iti) */
+/* { */
+/* if (iti->cur_node == node) */
+/* return; */
+
+/* fprintf (iti->of, "(char *)\"%s\",\n", */
+/* IDL_IDENT(IDL_INTERFACE(node).ident).repo_id); */
+
+/* iti->parents++; */
+/* } */
+
+/* static void */
+/* cc_output_itypes (GSList *list, OIDL_C_Info *ci) */
+/* { */
+/* GSList *l; */
+/* FILE *of = ci->fh; */
+
+/* for (l = list; l; l = l->next) { */
+/* CCSmallInterfaceTraverseInfo iti; */
+/* Interface *i = l->data; */
+/* char *id; */
+/* GSList *m; */
+
+/* id = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS ( */
+/* IDL_INTERFACE (i->tree).ident), "_", 0); */
+
+/* for (m = i->methods; m; m = m->next) */
+/* cc_output_method_bits (m->data, id, ci); */
+
+/* if (i->methods) { */
+/* fprintf (of, "\n#ifdef FORB_IDL_C_IMODULE_%s\n", */
+/* ci->c_base_name); */
+/* fprintf (of, "static\n"); */
+/* fprintf (of, "#endif\n"); */
+
+/* fprintf (of, "Forb_IMethod %s__imethods [] = {\n", id); */
+
+/* if (!(m = i->methods)) */
+/* fprintf (of, "{{0}}"); */
+
+/* else for (; m; m = m->next) { */
+/* cc_output_method (of, m->data, id); */
+/* if (m->next) */
+/* fprintf(of, ", "); */
+/* } */
+
+/* fprintf (of, "};\n\n"); */
+/* } */
+
+/* fprintf (of, "static CORBA_string %s__base_itypes[] = {\n", id); */
+
+/* iti.of = of; */
+/* iti.cur_node = i->tree; */
+/* iti.cur_id = id; */
+/* iti.parents = 0; */
+/* IDL_tree_traverse_parents(i->tree, (GFunc)cc_output_base_itypes, &iti); */
+
+/* fprintf (of, "(char *)\"IDL:omg.org/CORBA/Object:1.0\"\n};"); */
+
+/* fprintf (of, "\n#ifdef FORB_IDL_C_IMODULE_%s\n", */
+/* ci->c_base_name); */
+/* fprintf (of, "static\n"); */
+/* fprintf (of, "#endif\n"); */
+/* fprintf (of, "Forb_IInterface %s__iinterface = {\n", id); */
+/* fprintf (of, "TC_%s,", id); */
+/* fprintf (of, "{%d, %d, %s__imethods, FALSE},\n", */
+/* g_slist_length (i->methods), */
+/* g_slist_length (i->methods), id); */
+
+/* fprintf (of, "{%d, %d, %s__base_itypes, FALSE}\n", */
+/* iti.parents + 1, iti.parents + 1, id); */
+
+/* fprintf (of, "};\n\n"); */
+
+/* g_free (id); */
+/* } */
+
+/* for (l = list; l; l = l->next) { */
+/* g_slist_free (((Interface *)l->data)->methods); */
+/* g_free (l->data); */
+/* } */
+
+/* g_slist_free (list); */
+/* } */
+
+/* static GSList * */
+/* cc_build_interfaces (GSList *list, IDL_tree tree) */
+/* { */
+/* if (!tree) */
+/* return list; */
+
+/* switch (IDL_NODE_TYPE (tree)) { */
+/* case IDLN_MODULE: */
+/* list = cc_build_interfaces ( */
+/* list, IDL_MODULE (tree).definition_list); */
+/* break; */
+/* case IDLN_LIST: { */
+/* IDL_tree sub; */
+/* for (sub = tree; sub; sub = IDL_LIST (sub).next) */
+/* list = cc_build_interfaces ( */
+/* list, IDL_LIST (sub).data); */
+/* break; */
+/* } */
+/* case IDLN_ATTR_DCL: { */
+/* IDL_tree curitem; */
+
+/* for (curitem = IDL_ATTR_DCL (tree).simple_declarations; */
+/* curitem; curitem = IDL_LIST (curitem).next) { */
+/* OIDL_Attr_Info *ai = IDL_LIST (curitem).data->data; */
+
+/* list = cc_build_interfaces (list, ai->op1); */
+/* if (ai->op2) */
+/* list = cc_build_interfaces (list, ai->op2); */
+/* } */
+/* break; */
+/* } */
+/* case IDLN_INTERFACE: { */
+/* Interface *i = g_new0 (Interface, 1); */
+
+/* i->tree = tree; */
+
+/* list = g_slist_append (list, i); */
+
+/* list = cc_build_interfaces (list, IDL_INTERFACE(tree).body); */
+
+/* break; */
+/* } */
+/* case IDLN_OP_DCL: { */
+/* Interface *i; */
+
+/* g_return_val_if_fail (list != NULL, NULL); */
+
+/* i = ( g_slist_last(list) )->data; */
+/* i->methods = g_slist_append (i->methods, tree); */
+/* break; */
+/* } */
+/* case IDLN_EXCEPT_DCL: */
+/* break; */
+/* default: */
+/* break; */
+/* } */
+
+/* return list; */
+/* } */
+
+/* static void */
+/* cc_output_skel (IDL_tree tree, */
+/* OIDL_C_Info *ci, */
+/* int *idx) */
+/* { */
+/* IDL_tree intf; */
+/* gboolean has_retval; */
+/* char *opname; */
+/* char *ifname; */
+
+/* g_return_if_fail (idx != NULL); */
+
+/* intf = IDL_get_parent_node (tree, IDLN_INTERFACE, NULL); */
+
+/* has_retval = IDL_OP_DCL (tree).op_type_spec != NULL; */
+
+/* opname = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (IDL_OP_DCL (tree).ident), "_", 0); */
+/* ifname = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (IDL_INTERFACE (intf).ident), "_", 0); */
+
+/* fprintf (ci->fh, "void _FORB_skel_small_%s(" */
+/* "POA_%s *_o_servant, " */
+/* "gpointer _o_retval," */
+/* "gpointer *_o_args," */
+/* "CORBA_Context _o_ctx," */
+/* "CORBA_Environment *_o_ev,\n", opname, ifname); */
+
+/* forb_cbe_op_write_proto (ci->fh, tree, "_impl_", TRUE); */
+
+/* fprintf (ci->fh, ") {\n"); */
+
+/* if (has_retval) { */
+/* fprintf (ci->fh, "*("); */
+/* forb_cbe_write_param_typespec (ci->fh, tree); */
+/* fprintf (ci->fh, " *)_o_retval = "); */
+/* } */
+
+/* fprintf (ci->fh, "_impl_%s (_o_servant, ", IDL_IDENT (IDL_OP_DCL (tree).ident).str); */
+
+/* forb_cbe_unflatten_args (tree, ci->fh, "_o_args"); */
+
+/* if (IDL_OP_DCL (tree).context_expr) */
+/* fprintf (ci->fh, "_o_ctx, "); */
+
+/* fprintf (ci->fh, "_o_ev);\n"); */
+
+/* fprintf (ci->fh, "}\n"); */
+
+/* g_free (opname); */
+/* g_free (ifname); */
+
+/* (*idx)++; */
+/* } */
+
+/* static void */
+/* cc_output_skels (IDL_tree tree, */
+/* OIDL_Run_Info *rinfo, */
+/* OIDL_C_Info *ci, */
+/* int *idx) */
+/* { */
+/* if (!tree || (tree->declspec & IDLF_DECLSPEC_PIDL)) */
+/* return; */
+
+/* switch (IDL_NODE_TYPE (tree)) { */
+/* case IDLN_MODULE: */
+/* cc_output_skels (IDL_MODULE (tree).definition_list, rinfo, ci, idx); */
+/* break; */
+/* case IDLN_LIST: { */
+/* IDL_tree node; */
+
+/* for (node = tree; node; node = IDL_LIST (node).next) */
+/* cc_output_skels (IDL_LIST (node).data, rinfo, ci, idx); */
+/* break; */
+/* } */
+/* case IDLN_ATTR_DCL: { */
+/* OIDL_Attr_Info *ai = tree->data; */
+/* IDL_tree node; */
+
+/* for (node = IDL_ATTR_DCL (tree).simple_declarations; node; node = IDL_LIST (node).next) { */
+/* ai = IDL_LIST (node).data->data; */
+
+/* cc_output_skels (ai->op1, rinfo, ci, idx); */
+/* if (ai->op2) */
+/* cc_output_skels (ai->op2, rinfo, ci, idx); */
+/* } */
+/* break; */
+/* } */
+/* case IDLN_INTERFACE: { */
+/* int real_idx = 0; */
+
+/* cc_output_skels (IDL_INTERFACE (tree).body, rinfo, ci, &real_idx); */
+/* } */
+/* break; */
+/* case IDLN_OP_DCL: */
+/* cc_output_skel (tree, ci, idx); */
+/* break; */
+/* default: */
+/* break; */
+/* } */
+/* } */
+
+void
+forb_idl_output_c_common (IDL_tree tree,
+ OIDL_Run_Info *rinfo,
+ OIDL_C_Info *ci)
+{
+ fprintf (ci->fh, OIDL_C_WARNING);
+/* fprintf (ci->fh, "#include <string.h>\n"); */
+/* fprintf (ci->fh, "#define FORB2_STUBS_API\n"); */
+/* fprintf (ci->fh, "#define FORB_IDL_C_COMMON\n"); */
+/* fprintf (ci->fh, "#define %s_COMMON\n", ci->c_base_name); */
+ fprintf (ci->fh, "#include \"%s.h\"\n", ci->base_name);
+ fprintf (ci->fh, "#include <forb/cdr.h>\n");
+ fprintf (ci->fh, "#include <forb/object.h>\n\n");
+/* fprintf (ci->fh, "static const CORBA_unsigned_long Forb_zero_int = 0;\n"); */
+
+ /* FIXME: this is slightly nasty, but we need these in common,
+ and this fixes an internal build issue */
+/* if (rinfo->enabled_passes & OUTPUT_SKELS || */
+/* rinfo->enabled_passes & OUTPUT_STUBS) { */
+/* fprintf (ci->fh, "\n#ifndef FORB_IDL_C_IMODULE_%s\n",ci->c_base_name); */
+/* cc_output_skels (tree, rinfo, ci, NULL); */
+/* fprintf (ci->fh, "\n#endif\n"); */
+/* } */
+
+ cc_output_serialization (tree, ci);
+/* cc_output_typecodes (tree, ci); */
+
+/* cc_output_class_ids (tree, rinfo, ci); */
+
+/* if (rinfo->idata) { */
+/* GSList *list = NULL; */
+
+/* fprintf (ci->fh, "\n/\* Interface type data *\/\n\n"); */
+
+/* list = cc_build_interfaces (list, tree); */
+/* cc_output_itypes (list, ci); */
+/* } */
+}
--- /dev/null
+/*
+ * Copyright (C) 2001 Maciej Stachowiak, Ximian Inc.
+ */
+
+#include "config.h"
+#include "forb-idl-c-backend.h"
+
+#include <string.h>
+#include <ctype.h>
+
+static void
+output_deps (IDL_tree tree,
+ OIDL_Run_Info *rinfo,
+ OIDL_C_Info *ci)
+{
+ if (!tree)
+ return;
+
+ switch (IDL_NODE_TYPE (tree)) {
+ case IDLN_SRCFILE: {
+ char *idlfn = IDL_SRCFILE (tree).filename;
+ fprintf (ci->fh, " \\\n\t%s", idlfn);
+ break;
+ }
+
+ case IDLN_MODULE:
+ output_deps (IDL_MODULE (tree).definition_list, rinfo, ci);
+ break;
+
+ case IDLN_LIST: {
+ IDL_tree sub;
+
+ for (sub = tree; sub; sub = IDL_LIST (sub).next)
+ output_deps (IDL_LIST (sub).data, rinfo, ci);
+ break;
+ }
+
+ case IDLN_INTERFACE:
+ output_deps (IDL_INTERFACE (tree).body, rinfo, ci);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void
+forb_idl_output_c_deps (IDL_tree tree,
+ OIDL_Run_Info *rinfo,
+ OIDL_C_Info *ci)
+{
+ int i;
+
+ g_return_if_fail (ci->fh != NULL);
+
+ for (i = 0; i < OUTPUT_NUM_PASSES - 1; i++) {
+ char *name = forb_idl_c_filename_for_pass (
+ rinfo->input_filename, 1 << i);
+ fprintf (ci->fh, "%s ", name);
+ g_free (name);
+ }
+
+ fprintf (ci->fh, ": ");
+
+ output_deps (tree, rinfo, ci);
+
+ fprintf (ci->fh, "\n");
+}
--- /dev/null
+#include "config.h"
+#include "forb-idl-c-backend.h"
+#include "forb_config.h"
+
+#include <string.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+/* ch = C header */
+static void ch_output_types(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+/* static void ch_output_poa(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci); */
+/* static void ch_output_itypes (IDL_tree tree, OIDL_C_Info *ci); */
+static void ch_output_stub_protos(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+/* static void ch_output_skel_protos(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci); */
+static GSList *ch_build_interfaces (GSList *list, IDL_tree tree);
+static void ch_output_method (FILE *of, IDL_tree tree, const char *id);
+/* static void ch_output_imethods_index (GSList *list, OIDL_C_Info *ci); */
+
+typedef struct {
+ IDL_tree tree;
+ GSList *methods; /* IDLN_OP_DCLs */
+} Interface;
+
+/* this is hardcopy from cc_build_interfaces() defined in forb-idl-c-common.c */
+static GSList *
+ch_build_interfaces (GSList *list, IDL_tree tree)
+{
+ if (!tree)
+ return list;
+
+ switch (IDL_NODE_TYPE (tree)) {
+ case IDLN_MODULE:
+ list = ch_build_interfaces (
+ list, IDL_MODULE (tree).definition_list);
+ break;
+ case IDLN_LIST: {
+ IDL_tree sub;
+ for (sub = tree; sub; sub = IDL_LIST (sub).next)
+ list = ch_build_interfaces (
+ list, IDL_LIST (sub).data);
+ break;
+ }
+ case IDLN_ATTR_DCL: {
+ IDL_tree curitem;
+
+ for (curitem = IDL_ATTR_DCL (tree).simple_declarations;
+ curitem; curitem = IDL_LIST (curitem).next) {
+ OIDL_Attr_Info *ai = IDL_LIST (curitem).data->data;
+
+ list = ch_build_interfaces (list, ai->op1);
+ if (ai->op2)
+ list = ch_build_interfaces (list, ai->op2);
+ }
+ break;
+ }
+ case IDLN_INTERFACE: {
+ Interface *i = g_new0 (Interface, 1);
+
+ i->tree = tree;
+
+ list = g_slist_append (list, i);
+
+ list = ch_build_interfaces (list, IDL_INTERFACE(tree).body);
+
+ break;
+ }
+ case IDLN_OP_DCL: {
+ Interface *i;
+
+ g_return_val_if_fail (list != NULL, NULL);
+
+ i = ( g_slist_last(list) )->data;
+ i->methods = g_slist_append (i->methods, tree);
+ break;
+ }
+ case IDLN_EXCEPT_DCL:
+ break;
+ default:
+ break;
+ }
+
+ return list;
+}
+
+static void
+ch_output_method (FILE *of, IDL_tree tree, const char *id)
+{
+ char *fullname = NULL;
+
+ fullname = g_strconcat (id, "_", IDL_IDENT (
+ IDL_OP_DCL (tree).ident).str, NULL);
+
+ fprintf (of, "\t%s__method_index", fullname);
+
+ g_free (fullname);
+}
+
+static void
+ch_output_method_indices (GSList *list, OIDL_C_Info *ci)
+{
+ GSList *l;
+ FILE *of = ci->fh;
+
+ for (l = list; l; l = l->next) {
+ Interface *i = l->data;
+ char *id;
+ GSList *m;
+
+ id = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (
+ IDL_INTERFACE (i->tree).ident), "_", 0);
+
+ if (i->methods) {
+
+ fprintf (of, "#ifndef __%s__method_indices\n", id);
+ fprintf (of, "#define __%s__method_indices\n", id);
+
+ fprintf (of, "typedef enum {\n");
+
+ for (m = i->methods; m; m = m->next) {
+ ch_output_method (of, m->data, id);
+ if (m->next)
+ fprintf(of, ",\n");
+ else
+ fprintf(of, "\n");
+ }
+
+ fprintf (of, "} %s__method_indices;\n", id);
+ fprintf (of, "#endif /* __%s__method_indices */\n\n", id);
+ }
+
+ g_free (id);
+ }
+
+ for (l = list; l; l = l->next) {
+ g_slist_free (((Interface *)l->data)->methods);
+ g_free (l->data);
+ }
+
+ g_slist_free (list);
+}
+
+
+#if 0
+static gboolean is_native(IDL_tree_func_data *tfd, gpointer user_data)
+{
+ IDL_tree tree = tfd->tree;
+ if (IDL_NODE_TYPE (tree) == IDLN_NATIVE) {
+ *(bool*)user_data = true;
+ return FALSE; /* Stop recursing */
+ }
+ return TRUE; /* continue */
+}
+
+static bool
+contains_native_type(IDL_tree tree)
+{
+ bool found = false;
+ IDL_tree_walk_in_order(tree, is_native, &found);
+ return found;
+}
+#endif
+
+void
+forb_idl_output_c_headers (IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+ fprintf (ci->fh, OIDL_C_WARNING);
+ fprintf(ci->fh, "#ifndef %s%s_H\n", rinfo->header_guard_prefix, ci->c_base_name);
+ fprintf(ci->fh, "#define %s%s_H 1\n", rinfo->header_guard_prefix, ci->c_base_name);
+
+ fprintf(ci->fh, "#define FORB_IDL_SERIAL %d\n", FORB_CONFIG_SERIAL);
+
+ fprintf(ci->fh, "#include <forb/cdr_codec.h>\n");
+ if (!rinfo->is_pidl) {
+ fprintf(ci->fh, "#include <forb/object_type.h>\n");
+ }
+ fprintf(ci->fh, "#include <forb/basic_types.h>\n");
+ if (rinfo->include) {
+ fprintf(ci->fh, "#include <%s>\n", rinfo->include);
+ }
+ fprintf(ci->fh, "\n");
+
+ fprintf(ci->fh, "#ifdef __cplusplus\n");
+ fprintf(ci->fh, "extern \"C\" {\n");
+ fprintf(ci->fh, "#endif /* __cplusplus */\n\n");
+
+ /* Do all the typedefs, etc. */
+ fprintf(ci->fh, "\n/** typedefs **/\n");
+ ch_output_types(tree, rinfo, ci);
+
+ if ( ci->do_skel_defs ) {
+/* /\* Do all the POA structures, etc. *\/ */
+/* fprintf(ci->fh, "\n/\** POA structures **\/\n"); */
+/* ch_output_poa(tree, rinfo, ci); */
+
+/* fprintf(ci->fh, "\n/\** skel prototypes **\/\n"); */
+/* fprintf(ci->fh, "/\* FIXME: Maybe we don't need this for FORB. *\/\n"); */
+/* ch_output_skel_protos(tree, rinfo, ci); */
+ }
+ fprintf(ci->fh, "\n/** stub prototypes **/\n");
+ ch_output_stub_protos(tree, rinfo, ci);
+
+/* if ( ci->ext_dcls && ci->ext_dcls->str ) */
+/* fputs( ci->ext_dcls->str, ci->fh); /\* this may be huge! *\/ */
+
+/* if (rinfo->idata) { */
+/* /\* FIXME: hackish ? *\/ */
+/* fprintf(ci->fh, "#include <forb/orb-core/forb-interface.h>\n\n"); */
+
+/* ch_output_itypes(tree, ci); */
+/* } */
+
+ if (rinfo->idata) {
+ GSList *list = NULL;
+ fprintf (ci->fh, "\n/** Method indices */\n\n");
+
+ list = ch_build_interfaces (list, tree);
+ ch_output_method_indices (list, ci);
+ }
+
+ fprintf(ci->fh, "#ifdef __cplusplus\n");
+ fprintf(ci->fh, "}\n");
+ fprintf(ci->fh, "#endif /* __cplusplus */\n\n");
+
+/* fprintf(ci->fh, "#ifndef EXCLUDE_FORB_H\n"); */
+/* fprintf(ci->fh, "#include <forb.h>\n\n"); */
+/* fprintf(ci->fh, "#endif /\* EXCLUDE_FORB_H *\/\n"); */
+
+ fprintf(ci->fh, "#endif\n");
+
+ fprintf(ci->fh, "#undef FORB_IDL_SERIAL\n");
+}
+
+static void
+ch_output_var(IDL_tree val, IDL_tree name, OIDL_C_Info *ci)
+{
+ forb_cbe_write_typespec(ci->fh, val);
+
+ fprintf(ci->fh, " ");
+ switch(IDL_NODE_TYPE(name)) {
+ case IDLN_IDENT:
+ fprintf(ci->fh, "%s", IDL_IDENT(name).str);
+ break;
+ case IDLN_TYPE_ARRAY:
+ {
+ IDL_tree curitem;
+
+ fprintf(ci->fh, "%s", IDL_IDENT(IDL_TYPE_ARRAY(name).ident).str);
+ for(curitem = IDL_TYPE_ARRAY(name).size_list; curitem; curitem = IDL_LIST(curitem).next) {
+ fprintf(ci->fh, "[%" PRId64 "]", IDL_INTEGER(IDL_LIST(curitem).data).value);
+ }
+ }
+ break;
+ default:
+ g_error("Weird varname - %s", IDL_tree_type_names[IDL_NODE_TYPE(name)]);
+ break;
+ }
+ fprintf(ci->fh, ";\n");
+}
+
+static void ch_output_interface(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+static void ch_output_type_struct(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+static void ch_output_type_enum(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+static void ch_output_type_dcl(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+/* static void ch_output_native(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci); */
+static void ch_output_type_union(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+static void ch_output_codefrag(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+static void ch_output_const_dcl(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+static void ch_prep(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+/* static void ch_type_alloc_and_tc(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci, gboolean do_alloc); */
+
+static void
+ch_output_types (IDL_tree tree,
+ OIDL_Run_Info *rinfo,
+ OIDL_C_Info *ci)
+{
+ if (!tree)
+ return;
+
+ switch (IDL_NODE_TYPE (tree)) {
+ case IDLN_EXCEPT_DCL: {
+ IDL_tree_warning(tree, IDL_WARNING1, "Exceptions are not supperted\n");
+/* char *id; */
+
+/* id = IDL_ns_ident_to_qstring ( */
+/* IDL_IDENT_TO_NS (IDL_EXCEPT_DCL (tree).ident), "_", 0); */
+
+/* fprintf (ci->fh, "#undef ex_%s\n", id); */
+/* fprintf (ci->fh, "#define ex_%s \"%s\"\n", */
+/* id, IDL_IDENT (IDL_EXCEPT_DCL (tree).ident).repo_id); */
+
+/* g_free (id); */
+
+/* ch_output_type_struct (tree, rinfo, ci); */
+ }
+ break;
+ case IDLN_FORWARD_DCL:
+ case IDLN_INTERFACE:
+ ch_output_interface (tree, rinfo, ci);
+ break;
+ case IDLN_TYPE_STRUCT:
+ ch_output_type_struct (tree, rinfo, ci);
+ break;
+ case IDLN_TYPE_ENUM:
+ ch_output_type_enum (tree, rinfo, ci);
+ break;
+ case IDLN_TYPE_DCL:
+ ch_output_type_dcl (tree, rinfo, ci);
+ break;
+ case IDLN_TYPE_UNION:
+ ch_output_type_union (tree, rinfo, ci);
+ break;
+ case IDLN_CODEFRAG:
+ ch_output_codefrag (tree, rinfo, ci);
+ break;
+ case IDLN_SRCFILE: {
+ char *idlfn = IDL_SRCFILE (tree).filename;
+ if (rinfo->onlytop) {
+
+ if (!IDL_SRCFILE (tree).seenCnt &&
+ !IDL_SRCFILE(tree).isTop &&
+ !IDL_SRCFILE(tree).wasInhibit) {
+ gchar *hfn, *htail;
+
+ hfn = g_path_get_basename (idlfn);
+ htail = strrchr (hfn,'.');
+
+ g_assert (htail && strlen (htail) >= 2);
+
+ htail [1] = 'h';
+ htail [2] = 0;
+
+ fprintf (ci->fh, "#include \"%s\"\n", hfn);
+
+ g_free (hfn);
+ }
+ } else {
+ fprintf (ci->fh, "/* from IDL source file \"%s\" "
+ "(seen %d, isTop %d, wasInhibit %d) */ \n",
+ idlfn,
+ IDL_SRCFILE (tree).seenCnt,
+ IDL_SRCFILE (tree).isTop,
+ IDL_SRCFILE (tree).wasInhibit);
+ }
+ }
+ break;
+ case IDLN_CONST_DCL:
+ ch_output_const_dcl (tree, rinfo, ci);
+ break;
+/* case IDLN_NATIVE: */
+/* ch_output_native (tree, rinfo, ci); */
+/* break; */
+ default:
+ break;
+ }
+
+ switch (IDL_NODE_TYPE (tree)) {
+ case IDLN_MODULE:
+ ch_output_types (IDL_MODULE (tree).definition_list, rinfo, ci);
+ break;
+ case IDLN_LIST: {
+ IDL_tree sub;
+
+ for (sub = tree; sub; sub = IDL_LIST (sub).next) {
+ ch_output_types (IDL_LIST (sub).data, rinfo, ci);
+ }
+ }
+ break;
+ case IDLN_INTERFACE:
+ ch_output_types (IDL_INTERFACE (tree).body, rinfo, ci);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+ch_output_impl_struct_members(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+ if(!tree) return;
+
+ switch(IDL_NODE_TYPE(tree)) {
+ case IDLN_LIST:
+ {
+ IDL_tree sub;
+
+ for(sub = tree; sub; sub = IDL_LIST(sub).next) {
+ ch_output_stub_protos(IDL_LIST(sub).data, rinfo, ci);
+ }
+ }
+ break;
+ case IDLN_INTERFACE:
+ {
+ IDL_tree sub;
+
+/* if(IDL_INTERFACE(tree).inheritance_spec) { */
+/* InheritedOutputInfo ioi; */
+/* ioi.of = ci->fh; */
+/* ioi.realif = tree; */
+/* IDL_tree_traverse_parents(IDL_INTERFACE(tree).inheritance_spec, (GFunc)ch_output_inherited_protos, &ioi); */
+/* } */
+
+ for(sub = IDL_INTERFACE(tree).body; sub; sub = IDL_LIST(sub).next) {
+ IDL_tree cur;
+
+ cur = IDL_LIST(sub).data;
+
+ switch(IDL_NODE_TYPE(cur)) {
+ case IDLN_OP_DCL:
+ forb_idl_check_oneway_op (cur);
+ fprintf(ci->fh, " ");
+ forb_cbe_op_write_proto(ci->fh, cur, "", TRUE);
+ fprintf(ci->fh, ";\n");
+ break;
+/* case IDLN_ATTR_DCL: */
+/* { */
+/* OIDL_Attr_Info *ai; */
+/* IDL_tree curitem; */
+
+/* for(curitem = IDL_ATTR_DCL(cur).simple_declarations; curitem; curitem = IDL_LIST(curitem).next) { */
+/* ai = IDL_LIST(curitem).data->data; */
+
+/* forb_cbe_op_write_proto(ci->fh, ai->op1, "", FALSE); */
+/* fprintf(ci->fh, ";\n"); */
+
+/* if(ai->op2) { */
+/* forb_cbe_op_write_proto(ci->fh, ai->op2, "", FALSE); */
+/* fprintf(ci->fh, ";\n"); */
+/* } */
+/* } */
+/* } */
+/* break; */
+ default:
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+static void
+ch_output_impl_struct(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+ char *fullname;
+ fullname = forb_cbe_get_typespec_str(tree);
+ fprintf(ci->fh, "struct forb_%s_impl {\n", fullname);
+ ch_output_impl_struct_members(tree, rinfo, ci);
+ fprintf(ci->fh, "};\n\n");
+ g_free(fullname);
+}
+
+static void
+ch_output_interface(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+ char *fullname;
+ fullname = forb_cbe_get_typespec_str(tree);
+ fprintf(ci->fh, "#if !defined(FORB_DECL_%s)\n"
+ "#define FORB_DECL_%s 1\n",
+ fullname, fullname);
+
+ if ( tree->declspec & IDLF_DECLSPEC_PIDL ) {
+ /* PIDL interfaces are not normal CORBA Objects */
+ fprintf(ci->fh, "// PIDL: %s\n", fullname);
+/* fprintf(ci->fh, "typedef struct %s_type *%s;\n", fullname, fullname); */
+/* fprintf(ci->fh, "#ifndef TC_%s\n", fullname); */
+/* fprintf(ci->fh, "# define TC_%s TC_CORBA_Object\n", fullname); */
+/* fprintf(ci->fh, "#endif\n"); */
+ } else {
+
+ fprintf(ci->fh, " #if !defined(_%s_defined)\n"
+ " #define _%s_defined 1\n",
+ fullname, fullname);
+/* fprintf(ci->fh, "#define %s__freekids CORBA_Object__freekids\n", fullname); */
+ fprintf(ci->fh, " typedef forb_object %s;\n"
+ " #endif\n", fullname);
+ fprintf(ci->fh, " #define %s_serialize(codec, obj) forb_object_serialize((codec), (obj))\n", fullname);
+ fprintf(ci->fh, " #define %s_deserialize(codec, obj) forb_object_deserialize((codec), (obj))\n", fullname);
+/* fprintf(ci->fh, "extern CORBA_unsigned_long %s__classid;\n", fullname); */
+
+ ch_output_impl_struct(tree, rinfo, ci);
+
+/* fprintf(ci->fh, "void forb_register_%s_interface(void);\n", fullname); */
+ fprintf(ci->fh, " %s forb_%s_new(forb_orb orb,\n"
+ " const struct forb_%s_impl *impl,\n"
+ " void *instance_data);\n\n",
+ fullname, fullname, fullname);
+
+ /* ch_type_alloc_and_tc(tree, rinfo, ci, FALSE); */
+ }
+
+ fprintf(ci->fh, "#endif\n\n");
+ g_free(fullname);
+}
+
+static void
+ch_output_type_enum (IDL_tree tree,
+ OIDL_Run_Info *rinfo,
+ OIDL_C_Info *ci)
+{
+ IDL_tree l;
+ char *enumid;
+
+ /* CORBA spec says to do
+ * typedef unsigned int enum_name;
+ * and then #defines for each enumerator.
+ * This works just as well and seems cleaner.
+ */
+
+ enumid = IDL_ns_ident_to_qstring (
+ IDL_IDENT_TO_NS (IDL_TYPE_ENUM (tree).ident), "_", 0);
+ fprintf (ci->fh, "#if !defined(_%s_defined)\n#define _%s_defined 1\n", enumid, enumid);
+ fprintf (ci->fh, "typedef enum {\n");
+
+ for (l = IDL_TYPE_ENUM (tree).enumerator_list; l; l = IDL_LIST (l).next) {
+ char *id;
+
+ id = IDL_ns_ident_to_qstring (
+ IDL_IDENT_TO_NS (IDL_LIST (l).data), "_", 0);
+
+ fprintf (ci->fh, " %s%s\n", id, IDL_LIST (l).next ? "," : "");
+
+ g_free (id);
+ }
+
+ fprintf (ci->fh, "} %s;\n", enumid);
+
+ /* ch_type_alloc_and_tc (tree, rinfo, ci, FALSE); */
+ fprintf (ci->fh, "#define %s_serialize(codec, val) CORBA_unsigned_long_serialize(codec, val)\n", enumid);
+ fprintf (ci->fh, "#define %s_deserialize(codec, val) CORBA_unsigned_long_deserialize(codec, val)\n", enumid);
+
+ fprintf (ci->fh, "#endif\n\n");
+
+ g_free (enumid);
+}
+
+static void
+ch_output_type_dcl(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+ IDL_tree l;
+
+ ch_prep (IDL_TYPE_DCL (tree).type_spec, rinfo, ci);
+
+ for (l = IDL_TYPE_DCL (tree).dcls; l; l = IDL_LIST (l).next) {
+ char *ctmp = NULL;
+
+ IDL_tree ent = IDL_LIST (l).data;
+
+ switch (IDL_NODE_TYPE(ent)) {
+ case IDLN_IDENT:
+ ctmp = IDL_ns_ident_to_qstring (
+ IDL_IDENT_TO_NS (ent), "_", 0);
+ break;
+ case IDLN_TYPE_ARRAY:
+ ctmp = IDL_ns_ident_to_qstring (
+ IDL_IDENT_TO_NS (IDL_TYPE_ARRAY (ent).ident), "_", 0);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ fprintf (ci->fh, "#if !defined(_%s_defined)\n#define _%s_defined 1\n", ctmp, ctmp);
+ fprintf (ci->fh, "typedef ");
+ forb_cbe_write_typespec (ci->fh, IDL_TYPE_DCL (tree).type_spec);
+
+ switch (IDL_NODE_TYPE (ent)) {
+ case IDLN_IDENT:
+ fprintf (ci->fh, " %s;\n", ctmp);
+ fprintf (ci->fh, "#define %s_serialize(x,y) ", ctmp);
+ forb_cbe_write_typespec (ci->fh, IDL_TYPE_DCL (tree).type_spec);
+ fprintf (ci->fh, "_serialize((x),(y))\n");
+
+ fprintf (ci->fh, "#define %s_deserialize(x,y) ", ctmp);
+ forb_cbe_write_typespec (ci->fh, IDL_TYPE_DCL (tree).type_spec);
+ fprintf (ci->fh, "_deserialize((x),(y))\n");
+ break;
+ case IDLN_TYPE_ARRAY: {
+ IDL_tree sub;
+
+ fprintf (ci->fh, " %s", ctmp);
+ for (sub = IDL_TYPE_ARRAY (ent).size_list; sub; sub = IDL_LIST (sub).next)
+ fprintf (ci->fh, "[%" PRId64 "]",
+ IDL_INTEGER (IDL_LIST (sub).data).value);
+
+ fprintf (ci->fh, ";\n");
+ fprintf(ci->fh, "CORBA_boolean %s_serialize(FORB_CDR_Codec *codec, const %s array);\n", ctmp, ctmp);
+ fprintf(ci->fh, "CORBA_boolean %s_deserialize(FORB_CDR_Codec *codec, %s array);\n", ctmp, ctmp);
+/* fprintf (ci->fh, "typedef "); */
+/* forb_cbe_write_typespec (ci->fh, IDL_TYPE_DCL (tree).type_spec); */
+/* fprintf (ci->fh, " %s_slice", ctmp); */
+/* for (sub = IDL_LIST (IDL_TYPE_ARRAY (ent).size_list).next; */
+/* sub; sub = IDL_LIST (sub).next) */
+/* fprintf (ci->fh, "[%" PRId64 "d]", IDL_INTEGER (IDL_LIST (sub).data).value); */
+/* fprintf(ci->fh, ";\n"); */
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* ch_type_alloc_and_tc (ent, rinfo, ci, TRUE); */
+ fprintf (ci->fh, "#endif\n");
+ g_free (ctmp);
+ }
+}
+
+/* static void */
+/* ch_output_native(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci) */
+/* { */
+/* char *ctmp; */
+/* IDL_tree id = IDL_NATIVE(tree).ident; */
+/* ctmp = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(id), "_", 0); */
+/* fprintf(ci->fh, "#if !defined(_%s_defined)\n#define _%s_defined 1\n", ctmp, ctmp); */
+/* fprintf(ci->fh, "typedef struct %s_type *%s;\n", ctmp, ctmp); */
+/* /\* Dont even think about emitting a typecode. *\/ */
+/* fprintf(ci->fh, "#endif\n"); */
+/* g_free(ctmp); */
+/* } */
+
+static void
+ch_output_type_struct(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+ char *id;
+ IDL_tree cur, curmem;
+
+ id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_TYPE_STRUCT(tree).ident),
+ "_", 0);
+ fprintf(ci->fh, "#if !defined(_%s_defined)\n#define _%s_defined 1\n", id, id);
+ /* put typedef out first for recursive seq */
+ fprintf(ci->fh, "typedef struct %s_type %s;\n", id, id);
+
+ /* Scan for any nested decls */
+ for(cur = IDL_TYPE_STRUCT(tree).member_list; cur; cur = IDL_LIST(cur).next) {
+ IDL_tree ts;
+ ts = IDL_MEMBER(IDL_LIST(cur).data).type_spec;
+ ch_prep(ts, rinfo, ci);
+ }
+
+ fprintf(ci->fh, "struct %s_type {\n", id);
+
+ for(cur = IDL_TYPE_STRUCT(tree).member_list; cur; cur = IDL_LIST(cur).next) {
+ for(curmem = IDL_MEMBER(IDL_LIST(cur).data).dcls; curmem; curmem = IDL_LIST(curmem).next) {
+ ch_output_var(IDL_MEMBER(IDL_LIST(cur).data).type_spec, IDL_LIST(curmem).data, ci);
+ }
+ }
+ if(!IDL_TYPE_STRUCT(tree).member_list)
+ fprintf(ci->fh, "int dummy;\n");
+ fprintf(ci->fh, "};\n");
+
+ fprintf(ci->fh, "CORBA_boolean %s_serialize(FORB_CDR_Codec *codec, const %s *ptr);\n", id, id);
+ fprintf(ci->fh, "CORBA_boolean %s_deserialize(FORB_CDR_Codec *codec, %s *ptr);\n", id, id);
+
+ /* ch_type_alloc_and_tc(tree, rinfo, ci, TRUE); */
+
+ fprintf(ci->fh, "#endif\n\n");
+
+ g_free(id);
+}
+
+
+static void
+ch_output_type_union(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+ char *id;
+ IDL_tree curitem;
+
+ if (IDL_NODE_TYPE (IDL_TYPE_UNION (tree).switch_type_spec) == IDLN_TYPE_ENUM)
+ ch_output_type_enum (IDL_TYPE_UNION (tree).switch_type_spec, rinfo, ci);
+
+ id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_TYPE_UNION(tree).ident), "_", 0);
+ fprintf(ci->fh, "#if !defined(_%s_defined)\n#define _%s_defined 1\n", id, id);
+ fprintf(ci->fh, "typedef struct %s_type %s;\n", id, id);
+
+ /* Scan for any nested decls */
+ for(curitem = IDL_TYPE_UNION(tree).switch_body; curitem; curitem = IDL_LIST(curitem).next) {
+ IDL_tree member = IDL_CASE_STMT(IDL_LIST(curitem).data).element_spec;
+ ch_prep(IDL_MEMBER(member).type_spec, rinfo, ci);
+ }
+
+ fprintf(ci->fh, "struct %s_type {\n", id);
+ forb_cbe_write_typespec(ci->fh, IDL_TYPE_UNION(tree).switch_type_spec);
+ fprintf(ci->fh, " _d;\nunion {\n");
+
+ for(curitem = IDL_TYPE_UNION(tree).switch_body; curitem; curitem = IDL_LIST(curitem).next) {
+ IDL_tree member;
+
+ member = IDL_CASE_STMT(IDL_LIST(curitem).data).element_spec;
+ ch_output_var(IDL_MEMBER(member).type_spec,
+ IDL_LIST(IDL_MEMBER(member).dcls).data,
+ ci);
+ }
+
+ fprintf(ci->fh, "} _u;\n};\n");
+
+ /* ch_type_alloc_and_tc(tree, rinfo, ci, TRUE); */
+
+ fprintf(ci->fh, "#endif\n");
+
+ g_free(id);
+}
+
+static void
+ch_output_codefrag(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+ GSList *list;
+
+ for(list = IDL_CODEFRAG(tree).lines; list;
+ list = g_slist_next(list)) {
+ if(!strncmp(list->data,
+ "#pragma include_defs",
+ sizeof("#pragma include_defs")-1)) {
+ char *ctmp, *cte;
+ ctmp = ((char *)list->data) + sizeof("#pragma include_defs");
+ while(*ctmp && (isspace((int)*ctmp) || *ctmp == '"')) ctmp++;
+ cte = ctmp;
+ while(*cte && !isspace((int)*cte) && *cte != '"') cte++;
+ *cte = '\0';
+ fprintf(ci->fh, "#include <%s>\n", ctmp);
+ } else
+ fprintf(ci->fh, "%s\n", (char *)list->data);
+ }
+}
+
+static void
+ch_output_const_dcl(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+ char *id;
+ IDL_tree ident;
+ IDL_tree typespec;
+
+ ident = IDL_CONST_DCL (tree).ident;
+ id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS (ident), "_", 0);
+
+ fprintf(ci->fh, "#ifndef %s\n", id);
+ fprintf(ci->fh, "#define %s ", id);
+
+ forb_cbe_write_const(ci->fh,
+ IDL_CONST_DCL(tree).const_exp);
+
+ typespec = forb_cbe_get_typespec (IDL_CONST_DCL(tree).const_type);
+ if (IDL_NODE_TYPE (typespec) == IDLN_TYPE_INTEGER &&
+ !IDL_TYPE_INTEGER (typespec).f_signed)
+ fprintf(ci->fh, "U");
+
+ fprintf(ci->fh, "\n");
+ fprintf(ci->fh, "#endif /* !%s */\n\n", id);
+
+ g_free(id);
+}
+
+static void
+ch_prep_fixed(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+ char *ctmp;
+
+ ctmp = forb_cbe_get_typespec_str(tree);
+ fprintf(ci->fh,
+ "typedef struct { CORBA_unsigned_short _digits; CORBA_short _scale; CORBA_char _value[%d]; } %s;\n",
+ (int) (IDL_INTEGER(IDL_TYPE_FIXED(tree).positive_int_const).value + 2)/2,
+ ctmp);
+ g_free(ctmp);
+
+ /* ch_type_alloc_and_tc(tree, rinfo, ci, TRUE); */
+}
+
+static void
+ch_prep_sequence(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+ char *ctmp, *fullname, *fullname_def, *ctmp2;
+ IDL_tree tts;
+ gboolean separate_defs, fake_if;
+ IDL_tree fake_seq = NULL;
+
+ tts = forb_cbe_get_typespec(IDL_TYPE_SEQUENCE(tree).simple_type_spec);
+ ctmp = forb_cbe_get_typespec_str(IDL_TYPE_SEQUENCE(tree).simple_type_spec);
+ ctmp2 = forb_cbe_get_typespec_str(tts);
+ fake_if = (IDL_NODE_TYPE(tts) == IDLN_INTERFACE);
+ if(fake_if)
+ {
+ g_free(ctmp2);
+ ctmp2 = g_strdup("CORBA_Object");
+ }
+ separate_defs = false; //strcmp(ctmp, ctmp2);
+ fullname = forb_cbe_get_typespec_str(tree);
+ //printf("YYY %s\n", fullname);
+
+ if(separate_defs)
+ {
+ char *member_type;
+ //printf("XXXXXXXX Separate defs %s, %s\n", ctmp, ctmp2);
+ //forb_idl_print_node(tree, 2);
+ if(fake_if)
+ tts = IDL_type_object_new();
+ fake_seq = IDL_type_sequence_new(tts, NULL);
+ IDL_NODE_UP(fake_seq) = IDL_NODE_UP(tree);
+ ch_prep_sequence(fake_seq, rinfo, ci);
+ member_type = forb_cbe_type_is_builtin (tts) ?
+ ctmp2 + strlen ("CORBA_") : ctmp2;
+ fullname_def = g_strdup_printf("CORBA_sequence_%s", member_type);
+
+ if(!fake_if)
+ IDL_TYPE_SEQUENCE(fake_seq).simple_type_spec = NULL;
+ }
+ else
+ fullname_def = g_strdup(fullname);
+
+ if(IDL_NODE_TYPE(IDL_TYPE_SEQUENCE(tree).simple_type_spec)
+ == IDLN_TYPE_SEQUENCE)
+ ch_prep_sequence(IDL_TYPE_SEQUENCE(tree).simple_type_spec, rinfo, ci);
+
+ /* NOTE: FORB_DECL_%s protects redef of everything (struct,TC,externs)
+ * while _%s_defined protects only the struct */
+
+ fprintf(ci->fh, "#if !defined(FORB_DECL_%s)\n#define FORB_DECL_%s 1\n",
+ fullname, fullname);
+/* if ( ci->do_impl_hack ) */
+/* forb_cbe_id_define_hack(ci->fh, "FORB_IMPL", fullname, ci->c_base_name); */
+
+ if(separate_defs)
+ {
+ fprintf(ci->fh, "#if !defined(_%s_defined)\n#define _%s_defined 1\n",
+ fullname, fullname);
+ if(!strcmp(ctmp, "CORBA_RepositoryId"))
+ fprintf(ci->fh, "/* CRACKHEADS */\n");
+ fprintf(ci->fh, "typedef %s\n %s;\n", fullname_def, fullname);
+ fprintf(ci->fh, "#endif\n");
+ /* ch_type_alloc_and_tc(tree, rinfo, ci, FALSE); */
+/* fprintf(ci->fh, "#define %s__alloc %s__alloc\n", */
+/* fullname, fullname_def); */
+/* fprintf(ci->fh, "#define %s__freekids %s__freekids\n", */
+/* fullname, fullname_def); */
+ fprintf(ci->fh, "#define CORBA_sequence_%s_allocbuf(l) %s_allocbuf(l)\n",
+ ctmp, fullname_def);
+ fprintf(ci->fh, "#define %s_serialize(x,y) %s_serialize((x),(y))\n", fullname, fullname_def);
+
+ fprintf(ci->fh, "#define %s_deserialize(x,y) %s_deserialize((x),(y))\n", fullname, fullname_def);
+ IDL_tree_free(fake_seq);
+ }
+ else
+ {
+ char *member_type;
+
+ fprintf(ci->fh, "#if !defined(_%s_defined)\n#define _%s_defined 1\n",
+ fullname, fullname);
+ fprintf(ci->fh, "typedef struct { CORBA_unsigned_long _maximum, _length; ");
+ forb_cbe_write_typespec(ci->fh, IDL_TYPE_SEQUENCE(tree).simple_type_spec);
+ fprintf(ci->fh, "* _buffer; CORBA_boolean _release; }\n ");
+ forb_cbe_write_typespec(ci->fh, tree);
+ fprintf(ci->fh, ";\n#endif\n");
+
+ fprintf(ci->fh, "CORBA_boolean %s_serialize(FORB_CDR_Codec *codec, const %s *ptr);\n", fullname, fullname);
+ fprintf(ci->fh, "CORBA_boolean %s_deserialize(FORB_CDR_Codec *codec, %s *ptr);\n", fullname, fullname);
+ /* ch_type_alloc_and_tc(tree, rinfo, ci, TRUE); */
+
+/* tc = forb_cbe_get_typecode_name (forb_cbe_get_typespec (tree)); */
+ member_type = forb_cbe_type_is_builtin (IDL_TYPE_SEQUENCE (tree).simple_type_spec) ?
+ ctmp + strlen ("CORBA_") : ctmp;
+
+ fprintf (ci->fh, "#define CORBA_sequence_%s_allocbuf(l) "
+ "((%s*)forb_malloc(sizeof(%s)*(l)))\n",
+ member_type, ctmp, ctmp);
+
+/* g_free (tc); */
+ }
+
+ fprintf(ci->fh, "#endif\n\n");
+
+ g_free(ctmp2);
+ g_free(ctmp);
+ g_free(fullname);
+ g_free(fullname_def);
+}
+
+static
+void ch_prep (IDL_tree tree,
+ OIDL_Run_Info *rinfo,
+ OIDL_C_Info *ci)
+{
+ switch (IDL_NODE_TYPE (tree)) {
+ case IDLN_TYPE_SEQUENCE:
+ ch_prep_sequence (tree, rinfo, ci);
+ break;
+ case IDLN_TYPE_FIXED:
+ ch_prep_fixed (tree, rinfo, ci);
+ break;
+ case IDLN_TYPE_STRUCT:
+ ch_output_type_struct (tree, rinfo, ci);
+ break;
+ case IDLN_TYPE_ENUM:
+ ch_output_type_enum (tree, rinfo, ci);
+ break;
+ default:
+ break;
+ }
+}
+
+/* static void */
+/* ch_type_alloc_and_tc(IDL_tree tree, OIDL_Run_Info *rinfo, */
+/* OIDL_C_Info *ci, gboolean do_alloc) */
+/* { */
+/* char *ctmp; */
+/* IDL_tree tts; */
+
+/* ctmp = forb_cbe_get_typespec_str(tree); */
+
+/* if ( ci->do_impl_hack ) { */
+/* fprintf(ci->fh, "#if !defined(TC_IMPL_TC_%s_0)\n", ctmp); */
+/* forb_cbe_id_define_hack(ci->fh, "TC_IMPL_TC", ctmp, ci->c_base_name); */
+/* } */
+
+/* fprintf (ci->fh, "#ifdef FORB_IDL_C_IMODULE_%s\n", ci->c_base_name); */
+/* fprintf (ci->fh, "static\n"); */
+/* fprintf (ci->fh, "#else\n"); */
+/* fprintf (ci->fh, "extern\n"); */
+/* fprintf (ci->fh, "#endif\n"); */
+/* fprintf (ci->fh, "FORB2_MAYBE_CONST struct CORBA_TypeCode_struct TC_%s_struct;\n", ctmp); */
+
+/* fprintf (ci->fh, "#define TC_%s ((CORBA_TypeCode)&TC_%s_struct)\n", ctmp, ctmp); */
+/* if (ci->do_impl_hack) */
+/* fprintf (ci->fh, "#endif\n"); */
+
+/* if(do_alloc) { */
+/* char *tc; */
+
+/* tts = forb_cbe_get_typespec(tree); */
+
+/* tc = forb_cbe_get_typecode_name (tts); */
+
+/* fprintf (ci->fh, "#define %s__alloc() ((%s%s *)Forb_small_alloc (%s))\n", */
+/* ctmp, ctmp, (IDL_NODE_TYPE(tree) == IDLN_TYPE_ARRAY)?"_slice":"", tc); */
+
+/* fprintf (ci->fh, "#define %s__freekids(m,d) Forb_small_freekids (%s,(m),(d))\n", ctmp, tc); */
+
+/* if ( IDL_NODE_TYPE(tts) == IDLN_TYPE_SEQUENCE ) */
+/* { */
+/* char *member_type = forb_cbe_get_typespec_str(IDL_TYPE_SEQUENCE(tts).simple_type_spec); */
+/* char *member_name = forb_cbe_type_is_builtin (IDL_TYPE_SEQUENCE (tts).simple_type_spec) ? */
+/* member_type + strlen ("CORBA_") : member_type; */
+
+/* fprintf (ci->fh, "#define %s_allocbuf(l) " */
+/* "((%s*)Forb_small_allocbuf (%s, (l)))\n", */
+/* ctmp, member_name, tc); */
+
+/* g_free (member_type); */
+/* } */
+
+/* g_free (tc); */
+/* } */
+
+/* g_free(ctmp); */
+/* } */
+
+/************************/
+/* static void */
+/* cbe_header_interface_print_vepv(IDL_tree node, FILE *of) */
+/* { */
+/* char *id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(node).ident), */
+/* "_", 0); */
+/* fprintf(of, " POA_%s__epv *%s_epv;\n", id, id); */
+/* g_free(id); */
+
+/* } */
+
+/* static void */
+/* ch_output_poa(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci) */
+/* { */
+/* if(!tree) return; */
+
+/* if ( tree->declspec & IDLF_DECLSPEC_PIDL ) */
+/* return; */
+
+/* switch(IDL_NODE_TYPE(tree)) { */
+/* case IDLN_MODULE: */
+/* ch_output_poa(IDL_MODULE(tree).definition_list, rinfo, ci); */
+/* break; */
+/* case IDLN_LIST: */
+/* { */
+/* IDL_tree sub; */
+
+/* for(sub = tree; sub; sub = IDL_LIST(sub).next) { */
+/* ch_output_poa(IDL_LIST(sub).data, rinfo, ci); */
+/* } */
+/* } */
+/* break; */
+/* case IDLN_INTERFACE: */
+/* { */
+/* IDL_tree sub; */
+/* char *id; */
+
+
+/* id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(tree).ident), "_", 0); */
+
+/* fprintf(ci->fh, "#ifndef _defined_POA_%s\n#define _defined_POA_%s 1\n", */
+/* id, id); */
+
+/* /\* First, do epv for this interface, then vepv, then servant *\/ */
+/* fprintf(ci->fh, "typedef struct {\n"); */
+/* fprintf(ci->fh, " void *_private;\n"); */
+/* for(sub = IDL_INTERFACE(tree).body; sub; sub = IDL_LIST(sub).next) { */
+/* IDL_tree cur; */
+
+/* cur = IDL_LIST(sub).data; */
+
+/* switch(IDL_NODE_TYPE(cur)) { */
+/* case IDLN_OP_DCL: */
+/* forb_cbe_op_write_proto(ci->fh, cur, "", TRUE); */
+/* fprintf(ci->fh, ";\n"); */
+/* break; */
+/* case IDLN_ATTR_DCL: */
+/* { */
+/* OIDL_Attr_Info *ai; */
+/* IDL_tree curitem; */
+
+/* for(curitem = IDL_ATTR_DCL(cur).simple_declarations; curitem; curitem = IDL_LIST(curitem).next) { */
+/* ai = IDL_LIST(curitem).data->data; */
+
+/* forb_cbe_op_write_proto(ci->fh, ai->op1, "", TRUE); */
+/* fprintf(ci->fh, ";\n"); */
+
+/* if(ai->op2) { */
+/* forb_cbe_op_write_proto(ci->fh, ai->op2, "", TRUE); */
+/* fprintf(ci->fh, ";\n"); */
+/* } */
+/* } */
+/* } */
+/* break; */
+/* default: */
+/* break; */
+/* } */
+/* } */
+
+/* fprintf(ci->fh, "} POA_%s__epv;\n", id); */
+
+/* fprintf(ci->fh, "typedef struct {\n"); */
+/* fprintf(ci->fh, " PortableServer_ServantBase__epv *_base_epv;\n"); */
+/* IDL_tree_traverse_parents(tree, (GFunc)cbe_header_interface_print_vepv, ci->fh); */
+/* fprintf(ci->fh, "} POA_%s__vepv;\n", id); */
+
+/* fprintf(ci->fh, "typedef struct {\n"); */
+/* fprintf(ci->fh, " void *_private;\n"); */
+/* fprintf(ci->fh, " POA_%s__vepv *vepv;\n", id); */
+/* fprintf(ci->fh, "} POA_%s;\n", id); */
+
+/* fprintf(ci->fh, */
+/* "extern void POA_%s__init(PortableServer_Servant servant, CORBA_Environment *ev);\n", id); */
+/* fprintf(ci->fh, */
+/* "extern void POA_%s__fini(PortableServer_Servant servant, CORBA_Environment *ev);\n", id); */
+
+/* fprintf(ci->fh, "#endif /\* _defined_POA_%s *\/\n", id); */
+
+/* g_free(id); */
+/* } */
+/* break; */
+/* default: */
+/* break; */
+/* } */
+/* } */
+
+/************************/
+typedef struct {
+ FILE *of;
+ IDL_tree realif;
+} InheritedOutputInfo;
+static void ch_output_inherited_protos(IDL_tree curif, InheritedOutputInfo *ioi);
+
+static void
+ch_output_stub_protos(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+ if(!tree) return;
+
+
+ switch(IDL_NODE_TYPE(tree)) {
+ case IDLN_MODULE:
+ ch_output_stub_protos(IDL_MODULE(tree).definition_list, rinfo, ci);
+ break;
+ case IDLN_LIST:
+ {
+ IDL_tree sub;
+
+ for(sub = tree; sub; sub = IDL_LIST(sub).next) {
+ ch_output_stub_protos(IDL_LIST(sub).data, rinfo, ci);
+ }
+ }
+ break;
+ case IDLN_INTERFACE:
+ {
+ IDL_tree sub;
+
+ if(IDL_INTERFACE(tree).inheritance_spec) {
+ InheritedOutputInfo ioi;
+ ioi.of = ci->fh;
+ ioi.realif = tree;
+ IDL_tree_traverse_parents(IDL_INTERFACE(tree).inheritance_spec, (GFunc)ch_output_inherited_protos, &ioi);
+ }
+
+ for(sub = IDL_INTERFACE(tree).body; sub; sub = IDL_LIST(sub).next) {
+ IDL_tree cur;
+
+ cur = IDL_LIST(sub).data;
+
+ switch(IDL_NODE_TYPE(cur)) {
+ case IDLN_OP_DCL:
+ forb_idl_check_oneway_op (cur);
+ forb_cbe_op_write_proto(ci->fh, cur, "", FALSE);
+ fprintf(ci->fh, ";\n");
+ break;
+ case IDLN_ATTR_DCL:
+ {
+ OIDL_Attr_Info *ai;
+ IDL_tree curitem;
+
+ for(curitem = IDL_ATTR_DCL(cur).simple_declarations; curitem; curitem = IDL_LIST(curitem).next) {
+ ai = IDL_LIST(curitem).data->data;
+
+ forb_cbe_op_write_proto(ci->fh, ai->op1, "", FALSE);
+ fprintf(ci->fh, ";\n");
+
+ if(ai->op2) {
+ forb_cbe_op_write_proto(ci->fh, ai->op2, "", FALSE);
+ fprintf(ci->fh, ";\n");
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+ch_output_inherited_protos(IDL_tree curif, InheritedOutputInfo *ioi)
+{
+ char *id, *realid;
+ IDL_tree curitem;
+
+ if(curif == ioi->realif)
+ return;
+
+ realid = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(ioi->realif).ident), "_", 0);
+ id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(curif).ident), "_", 0);
+
+ for(curitem = IDL_INTERFACE(curif).body; curitem; curitem = IDL_LIST(curitem).next) {
+ IDL_tree curop = IDL_LIST(curitem).data;
+
+ switch(IDL_NODE_TYPE(curop)) {
+ case IDLN_OP_DCL:
+ fprintf(ioi->of, "#define %s_%s %s_%s\n",
+ realid, IDL_IDENT(IDL_OP_DCL(curop).ident).str,
+ id, IDL_IDENT(IDL_OP_DCL(curop).ident).str);
+ break;
+ case IDLN_ATTR_DCL:
+ {
+ IDL_tree curitem;
+
+ /* We don't use OIDL_Attr_Info here because inherited ops may go back into trees that are output-inhibited
+ and therefore don't have the OIDL_Attr_Info generated on them */
+
+ for(curitem = IDL_ATTR_DCL(curop).simple_declarations; curitem; curitem = IDL_LIST(curitem).next) {
+ IDL_tree ident;
+
+ ident = IDL_LIST(curitem).data;
+
+ fprintf(ioi->of, "#define %s__get_%s %s__get_%s\n",
+ realid, IDL_IDENT(ident).str,
+ id, IDL_IDENT(ident).str);
+
+ if(!IDL_ATTR_DCL(curop).f_readonly)
+ fprintf(ioi->of, "#define %s__set_%s %s__set_%s\n",
+ realid, IDL_IDENT(ident).str,
+ id, IDL_IDENT(ident).str);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ g_free(id);
+ g_free(realid);
+}
+
+/* static void */
+/* doskel(IDL_tree cur, OIDL_Run_Info *rinfo, char *ifid, OIDL_C_Info *ci) */
+/* { */
+/* char *id; */
+
+/* id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(cur).ident), "_", 0); */
+
+/* fprintf(ci->fh, "void _forb_skel_%s(" */
+/* "FORB_CDR_Codec *codec, %s *obj", */
+/* id, ifid); */
+/* /\* forb_cbe_op_write_proto(ci->fh, cur, "_impl_", TRUE); *\/ */
+/* fprintf(ci->fh, ");\n"); */
+
+/* g_free(id); */
+/* } */
+
+/* static void */
+/* ch_output_skel_protos(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci) */
+/* { */
+/* if(!tree) return; */
+
+/* if ( tree->declspec & IDLF_DECLSPEC_PIDL ) */
+/* return; */
+
+/* switch(IDL_NODE_TYPE(tree)) { */
+/* case IDLN_MODULE: */
+/* ch_output_skel_protos(IDL_MODULE(tree).definition_list, rinfo, ci); */
+/* break; */
+/* case IDLN_LIST: */
+/* { */
+/* IDL_tree sub; */
+
+/* for(sub = tree; sub; sub = IDL_LIST(sub).next) { */
+/* ch_output_skel_protos(IDL_LIST(sub).data, rinfo, ci); */
+/* } */
+/* } */
+/* break; */
+/* case IDLN_INTERFACE: */
+/* { */
+/* IDL_tree sub; */
+/* char *ifid; */
+
+/* ifid = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(tree).ident), "_", 0); */
+
+/* for(sub = IDL_INTERFACE(tree).body; sub; sub = IDL_LIST(sub).next) { */
+/* IDL_tree cur; */
+
+/* cur = IDL_LIST(sub).data; */
+
+/* switch(IDL_NODE_TYPE(cur)) { */
+/* case IDLN_OP_DCL: */
+/* doskel(cur, rinfo, ifid, ci); */
+/* break; */
+/* case IDLN_ATTR_DCL: */
+/* IDL_tree_warning(cur, IDL_WARNING1, "Attributes are not supperted\n"); */
+/* /\* { *\/ */
+/* /\* OIDL_Attr_Info *ai = cur->data; *\/ */
+/* /\* IDL_tree curitem; *\/ */
+
+/* /\* for(curitem = IDL_ATTR_DCL(cur).simple_declarations; curitem; curitem = IDL_LIST(curitem).next) { *\/ */
+/* /\* ai = IDL_LIST(curitem).data->data; *\/ */
+
+/* /\* doskel(ai->op1, rinfo, ifid, ci); *\/ */
+/* /\* if(ai->op2) *\/ */
+/* /\* doskel(ai->op2, rinfo, ifid, ci); *\/ */
+/* /\* } *\/ */
+/* /\* } *\/ */
+/* break; */
+/* default: */
+/* break; */
+/* } */
+/* } */
+/* g_free(ifid); */
+/* } */
+/* break; */
+/* default: */
+/* break; */
+/* } */
+/* } */
+
+/* static void */
+/* ch_output_itypes (IDL_tree tree, OIDL_C_Info *ci) */
+/* { */
+/* static int num_methods = 0; */
+
+/* if (!tree) */
+/* return; */
+
+/* switch(IDL_NODE_TYPE(tree)) { */
+/* case IDLN_MODULE: */
+/* ch_output_itypes (IDL_MODULE(tree).definition_list, ci); */
+/* break; */
+/* case IDLN_LIST: { */
+/* IDL_tree sub; */
+/* for (sub = tree; sub; sub = IDL_LIST(sub).next) */
+/* ch_output_itypes (IDL_LIST(sub).data, ci); */
+/* } */
+/* break; */
+/* case IDLN_ATTR_DCL: { */
+/* OIDL_Attr_Info *ai = tree->data; */
+
+/* IDL_tree curitem; */
+
+/* for(curitem = IDL_ATTR_DCL(tree).simple_declarations; curitem; */
+/* curitem = IDL_LIST(curitem).next) { */
+/* ai = IDL_LIST(curitem).data->data; */
+
+/* ch_output_itypes (ai->op1, ci); */
+/* if(ai->op2) */
+/* ch_output_itypes (ai->op2, ci); */
+/* } */
+/* } */
+/* break; */
+
+/* case IDLN_INTERFACE: { */
+/* char *id; */
+
+/* id = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS ( */
+/* IDL_INTERFACE (tree).ident), "_", 0); */
+
+/* ch_output_itypes (IDL_INTERFACE(tree).body, ci); */
+
+/* fprintf (ci->fh, "#ifdef FORB_IDL_C_IMODULE_%s\n", */
+/* ci->c_base_name); */
+/* fprintf (ci->fh, "static \n"); */
+/* fprintf (ci->fh, "#else\n"); */
+/* fprintf (ci->fh, "extern \n"); */
+/* fprintf (ci->fh, "#endif\n"); */
+/* fprintf (ci->fh, "Forb_IInterface %s__iinterface;\n", id); */
+
+/* fprintf (ci->fh, "#define %s_IMETHODS_LEN %d\n", id, num_methods); */
+
+/* if (num_methods == 0) */
+/* fprintf (ci->fh, "#define %s__imethods (Forb_IMethod*) NULL\n", id); */
+/* else { */
+/* fprintf (ci->fh, "#ifdef FORB_IDL_C_IMODULE_%s\n", */
+/* ci->c_base_name); */
+/* fprintf (ci->fh, "static \n"); */
+/* fprintf (ci->fh, "#else\n"); */
+/* fprintf (ci->fh, "extern \n"); */
+/* fprintf (ci->fh, "#endif\n"); */
+/* fprintf (ci->fh, "Forb_IMethod %s__imethods[%s_IMETHODS_LEN];\n", id, id); */
+/* } */
+
+
+/* num_methods = 0; */
+
+/* break; */
+/* } */
+
+/* case IDLN_OP_DCL: */
+/* num_methods++; */
+/* break; */
+/* default: */
+/* break; */
+/* } */
+/* } */
--- /dev/null
+#include "config.h"
+
+#include "forb-idl-c-backend.h"
+
+#include <string.h>
+#include "forb_config.h"
+
+static void
+ci_build_interfaces (OIDL_C_Info *ci,
+ IDL_tree tree)
+{
+ if (!tree)
+ return;
+
+ switch (IDL_NODE_TYPE (tree)) {
+ case IDLN_MODULE:
+ ci_build_interfaces (
+ ci, IDL_MODULE (tree).definition_list);
+ break;
+ case IDLN_LIST: {
+ IDL_tree sub;
+ for (sub = tree; sub; sub = IDL_LIST (sub).next)
+ ci_build_interfaces (
+ ci, IDL_LIST (sub).data);
+ break;
+ }
+ case IDLN_INTERFACE: {
+ char *id;
+
+ id = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (
+ IDL_INTERFACE (tree).ident), "_", 0);
+
+ fprintf (ci->fh, "\t&%s__iinterface,\n", id);
+
+ g_free (id);
+
+ ci_build_interfaces (
+ ci, IDL_INTERFACE(tree).body);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static void
+ci_build_types (OIDL_C_Info *ci,
+ IDL_tree tree,
+ guint *count)
+{
+ if (!tree)
+ return;
+
+ switch (IDL_NODE_TYPE (tree)) {
+ case IDLN_MODULE:
+ ci_build_types (
+ ci, IDL_MODULE (tree).definition_list, count);
+ break;
+ case IDLN_LIST: {
+ IDL_tree sub;
+ for (sub = tree; sub; sub = IDL_LIST (sub).next)
+ ci_build_types (
+ ci, IDL_LIST (sub).data, count);
+ break;
+ }
+ case IDLN_INTERFACE:
+ ci_build_types (
+ ci, IDL_INTERFACE(tree).body, count);
+ break;
+ case IDLN_TYPE_DCL: {
+ IDL_tree sub;
+ for (sub = IDL_TYPE_DCL (tree).dcls; sub; sub = IDL_LIST (sub).next) {
+ IDL_tree ent = IDL_LIST (sub).data;
+ gchar *id;
+
+ id = forb_cbe_get_typespec_str (ent);
+
+ fprintf (ci->fh, "\tTC_%s,\n", id);
+ (*count)++;
+
+ g_free (id);
+ }
+
+ break;
+ }
+ case IDLN_TYPE_STRUCT: {
+ gchar *id;
+ IDL_tree l;
+
+ id = forb_cbe_get_typespec_str (tree);
+
+ fprintf (ci->fh, "\tTC_%s,\n", id);
+ (*count)++;
+
+ g_free (id);
+
+ /* check for nested structs/enums */
+ for (l = IDL_TYPE_STRUCT (tree).member_list; l; l = IDL_LIST (l).next) {
+ IDL_tree dcl;
+
+ g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_MEMBER);
+ dcl = IDL_MEMBER (IDL_LIST (l).data).type_spec;
+
+ /* skip straight declarations */
+ if (IDL_NODE_TYPE(dcl) == IDLN_TYPE_STRUCT ||
+ IDL_NODE_TYPE(dcl) == IDLN_TYPE_UNION ||
+ IDL_NODE_TYPE(dcl) == IDLN_TYPE_ENUM)
+ ci_build_types (ci, dcl, count);
+ }
+ break;
+ };
+ case IDLN_TYPE_UNION: {
+ gchar *id;
+ IDL_tree l;
+
+ id = forb_cbe_get_typespec_str (tree);
+
+ fprintf (ci->fh, "\tTC_%s,\n", id);
+ (*count)++;
+
+ g_free (id);
+
+ /* if discriminator is an enum, register it */
+ if (IDL_NODE_TYPE (IDL_TYPE_UNION (tree).switch_type_spec) == IDLN_TYPE_ENUM)
+ ci_build_types (
+ ci, IDL_TYPE_UNION (tree).switch_type_spec, count);
+
+ /* check for nested structs/enums */
+ for (l = IDL_TYPE_UNION (tree).switch_body; l; l = IDL_LIST (l).next) {
+ IDL_tree dcl;
+
+ g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_CASE_STMT);
+ dcl = IDL_MEMBER (
+ IDL_CASE_STMT (IDL_LIST (l).data).element_spec).type_spec;
+
+ if (IDL_NODE_TYPE(dcl) == IDLN_TYPE_STRUCT ||
+ IDL_NODE_TYPE(dcl) == IDLN_TYPE_UNION ||
+ IDL_NODE_TYPE(dcl) == IDLN_TYPE_ENUM)
+ ci_build_types (ci, dcl, count);
+ }
+ break;
+ }
+ case IDLN_EXCEPT_DCL: {
+ gchar *id;
+ IDL_tree l;
+
+ id = forb_cbe_get_typespec_str (tree);
+
+ fprintf (ci->fh, "\tTC_%s,\n", id);
+ (*count)++;
+
+ g_free (id);
+
+ /* check for nested structs/enums */
+ for (l = IDL_EXCEPT_DCL (tree).members; l; l = IDL_LIST (l).next) {
+ IDL_tree dcl;
+
+ g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_MEMBER);
+ dcl = IDL_MEMBER (IDL_LIST (l).data).type_spec;
+
+ /* skip straight declarations */
+ if (IDL_NODE_TYPE(dcl) == IDLN_TYPE_STRUCT ||
+ IDL_NODE_TYPE(dcl) == IDLN_TYPE_UNION ||
+ IDL_NODE_TYPE(dcl) == IDLN_TYPE_ENUM)
+ ci_build_types (ci, dcl, count);
+ }
+ break;
+ }
+ case IDLN_TYPE_INTEGER:
+ case IDLN_TYPE_ANY:
+ case IDLN_TYPE_STRING:
+ case IDLN_TYPE_WIDE_STRING:
+ case IDLN_TYPE_CHAR:
+ case IDLN_TYPE_WIDE_CHAR:
+ case IDLN_TYPE_FLOAT:
+ case IDLN_TYPE_BOOLEAN:
+ case IDLN_TYPE_OCTET:
+ case IDLN_TYPE_SEQUENCE:
+ case IDLN_TYPE_ENUM:
+ case IDLN_IDENT:
+ case IDLN_FORWARD_DCL:
+ case IDLN_TYPE_OBJECT: {
+ gchar *id;
+
+ id = forb_cbe_get_typespec_str (tree);
+
+ fprintf (ci->fh, "\tTC_%s,\n", id);
+ (*count)++;
+
+ g_free (id);
+
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void
+forb_idl_output_c_imodule (IDL_tree tree,
+ OIDL_Run_Info *rinfo,
+ OIDL_C_Info *ci)
+{
+ guint count;
+
+ fprintf (ci->fh, OIDL_C_WARNING);
+ fprintf (ci->fh, "#include <string.h>\n");
+ fprintf (ci->fh, "#define FORB_IDL_C_IMODULE_%s\n\n",ci->c_base_name);
+
+ fprintf (ci->fh, "#include \"%s-common.c\"\n\n", ci->base_name);
+
+ fprintf (ci->fh, "#include <forb/orb-core/forb-small.h>\n\n");
+
+ fprintf (ci->fh, "static CORBA_TypeCode %s__itypes[] = {\n",
+ ci->c_base_name);
+
+ count = 0;
+ ci_build_types (ci, tree, &count);
+
+ fprintf (ci->fh, "\tNULL\n};\n\n");
+
+ fprintf (ci->fh, "static Forb_IInterface *%s__iinterfaces[] = {\n",
+ ci->c_base_name);
+
+ ci_build_interfaces (ci, tree);
+
+ fprintf (ci->fh, "\tNULL\n};\n");
+
+ fprintf (ci->fh, "Forb_IModule forb_imodule_data = {\n");
+ fprintf (ci->fh, " %d,\n", FORB_CONFIG_SERIAL);
+ fprintf (ci->fh, " %s__iinterfaces,\n", ci->c_base_name);
+ fprintf (ci->fh, " { %u, %u, %s__itypes, FALSE }\n",
+ count, count, ci->c_base_name);
+ fprintf (ci->fh, "};\n\n");
+}
--- /dev/null
+#include "config.h"
+
+#include "forb-idl-c-backend.h"
+
+/* This file copied from the old IDL compiler forb-c-skelimpl.c, with minimal changes. */
+
+static void forb_cbe_write_skelimpl(FILE *outfile, IDL_tree tree, const char *hdrname);
+
+void
+forb_idl_output_c_skelimpl(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+ forb_cbe_write_skelimpl(ci->fh, tree, ci->base_name);
+}
+
+#include <ctype.h>
+#include <errno.h>
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* Abbreviations used here:
+ "cbe" stands for "C backend"
+ "hdr" -> "header" (duh :)
+ "of" -> "output file"
+ "ns" -> "name space"
+*/
+
+typedef struct {
+ FILE *of;
+ IDL_tree tree;
+ enum { PASS_SERVANTS, PASS_PROTOS, PASS_EPVS, PASS_VEPVS,
+ PASS_IMPLSTUBS, PASS_LAST } pass;
+} CBESkelImplInfo;
+
+static const char *passnames[] = {
+ "App-specific servant structures",
+ "Implementation stub prototypes",
+ "epv structures",
+ "vepv structures",
+ "Stub implementations",
+ "Boohoo!"
+};
+
+static void forb_cbe_ski_process_piece(CBESkelImplInfo *ski);
+static void cbe_ski_do_list(CBESkelImplInfo *ski);
+static void cbe_ski_do_inherited_attr_dcl(CBESkelImplInfo *ski, IDL_tree current_interface);
+static void cbe_ski_do_attr_dcl(CBESkelImplInfo *ski);
+static void cbe_ski_do_inherited_op_dcl(CBESkelImplInfo *ski, IDL_tree current_interface);
+static void cbe_ski_do_op_dcl(CBESkelImplInfo *ski);
+static void cbe_ski_do_param_dcl(CBESkelImplInfo *ski);
+static void cbe_ski_do_interface(CBESkelImplInfo *ski);
+static void cbe_ski_do_module(CBESkelImplInfo *ski);
+
+static void
+forb_cbe_write_skelimpl(FILE *outfile, IDL_tree tree, const char *hdrname)
+{
+ CBESkelImplInfo ski = {NULL, NULL, PASS_SERVANTS};
+
+ ski.of = outfile;
+ ski.tree = tree;
+
+ g_return_if_fail(IDL_NODE_TYPE(tree) == IDLN_LIST);
+
+ fprintf(outfile, "/* This is a template file generated by command */\n");
+ fprintf(outfile, "/* forb-idl-2 --skeleton-impl %s.idl */\n", hdrname);
+ fprintf(outfile, "/* User must edit this file, inserting servant */\n");
+ fprintf(outfile, "/* specific code between markers. */\n\n");
+
+ fprintf(outfile, "#include \"%s.h\"\n", hdrname);
+
+ for(ski.pass = PASS_SERVANTS; ski.pass < PASS_LAST; ski.pass++) {
+ fprintf(ski.of, "\n/*** %s ***/\n\n", passnames[ski.pass]);
+ forb_cbe_ski_process_piece(&ski);
+ }
+}
+
+static void
+forb_cbe_ski_process_piece(CBESkelImplInfo *ski)
+{
+ /* I'm not implementing this as an array of function pointers
+ because we may want to do special logic for particular cases in
+ the future. Hope this is clear enough. -ECL */
+
+ switch(IDL_NODE_TYPE(ski->tree)) {
+ case IDLN_ATTR_DCL:
+ cbe_ski_do_attr_dcl(ski);
+ break;
+ case IDLN_INTERFACE:
+ cbe_ski_do_interface(ski);
+ break;
+ case IDLN_LIST:
+ cbe_ski_do_list(ski);
+ break;
+ case IDLN_MODULE:
+ cbe_ski_do_module(ski);
+ break;
+ case IDLN_OP_DCL:
+ cbe_ski_do_op_dcl(ski);
+ break;
+ case IDLN_PARAM_DCL:
+ cbe_ski_do_param_dcl(ski);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+cbe_ski_do_module(CBESkelImplInfo *ski)
+{
+ CBESkelImplInfo subski = *ski;
+ subski.tree = IDL_MODULE(ski->tree).definition_list;
+ cbe_ski_do_list(&subski);
+}
+
+/* Returns 1 if the previous character written to f */
+/* was '\n', 0 otherwise. */
+static inline unsigned char
+prev_char_is_nl(FILE *f)
+{
+ char c;
+ long pos;
+ size_t count;
+ unsigned char retv = 0;
+
+ pos = ftell(f);
+ if (pos < sizeof(char))
+ return 0; /* beginning of file */
+
+ if (fseek(f, (-1)*sizeof(char), SEEK_CUR))
+ goto out;
+
+ count = fread((void*)&c, sizeof(char), 1, f);
+ if (sizeof(char) == count)
+ retv = ('\n' == c) ? 1 : 0;
+
+out:
+ fseek(f, pos, SEEK_SET);
+ return retv;
+}
+
+static void
+cbe_ski_do_list(CBESkelImplInfo *ski)
+{
+ CBESkelImplInfo subski = *ski;
+ IDL_tree curitem;
+
+ for(curitem = ski->tree; curitem; curitem = IDL_LIST(curitem).next) {
+ subski.tree = IDL_LIST(curitem).data;
+ forb_cbe_ski_process_piece(&subski);
+ if(!prev_char_is_nl(ski->of))
+ fprintf(ski->of, "\n");
+ }
+}
+
+static void
+cbe_ski_do_attr_dcl_internal(CBESkelImplInfo *ski, IDL_tree current_interface, gboolean inherited)
+{
+ IDL_tree curop, curitem;
+ GString *attrname = g_string_new(NULL);
+ CBESkelImplInfo subski = *ski;
+
+ if(ski->pass == PASS_SERVANTS) {
+ for(curitem = IDL_ATTR_DCL(ski->tree).simple_declarations; curitem;
+ curitem = IDL_LIST(curitem).next) {
+ forb_cbe_write_typespec(ski->of, IDL_ATTR_DCL(ski->tree).param_type_spec);
+ fprintf(ski->of, " attr_%s;\n", IDL_IDENT(IDL_LIST(curitem).data).str);
+ }
+ }
+
+ for(curitem = IDL_ATTR_DCL(ski->tree).simple_declarations;
+ curitem; curitem = IDL_LIST(curitem).next) {
+
+ /* Fake the attribute get/set methods as operation declarations */
+ IDL_tree ident, ns_data_save;
+ int i;
+
+ for (i = 0; i < 2; ++i) {
+
+ if (i && IDL_ATTR_DCL(ski->tree).f_readonly)
+ break;
+ /* Output the operation on this attribute */
+ g_string_printf(attrname, i ? "_set_%s" : "_get_%s",
+ IDL_IDENT(IDL_LIST(curitem).data).str);
+ ident = IDL_ident_new(g_strdup(attrname->str));
+
+ /* Tell the ident where our namespace node is, and request a return value
+ if this is the _get operation */
+ IDL_IDENT_TO_NS(ident) = IDL_IDENT_TO_NS(IDL_LIST(curitem).data);
+ curop = IDL_op_dcl_new(0, i == 0 ?
+ IDL_ATTR_DCL(ski->tree).param_type_spec : NULL,
+ ident, NULL, NULL, NULL);
+
+ curop->up = ski->tree->up;
+ subski.tree = curop;
+
+ /* Save the namespace ident (IDL_GENTREE data) reference, assign
+ back to the temporary tree, output the operation, then restore
+ the namespace ident link */
+ ns_data_save = IDL_GENTREE(IDL_IDENT_TO_NS(IDL_LIST(curitem).data)).data;
+ IDL_GENTREE(IDL_IDENT_TO_NS(IDL_LIST(curitem).data)).data = ident;
+
+ if (i) {
+ /* The set routine also needs the value, so we
+ temporarily add that to the operation
+ declaration */
+ IDL_OP_DCL(curop).parameter_dcls = IDL_list_new(
+ IDL_param_dcl_new(IDL_PARAM_IN,
+ IDL_ATTR_DCL(ski->tree).param_type_spec,
+ IDL_ident_new(g_strdup("value"))));
+ }
+
+ if(inherited==TRUE)
+ cbe_ski_do_inherited_op_dcl(&subski, current_interface);
+ else
+ forb_cbe_ski_process_piece(&subski);
+
+ /* Restore the fake link to the original in the namespace */
+ IDL_GENTREE(IDL_IDENT_TO_NS(IDL_LIST(curitem).data)).data = ns_data_save;
+
+ if (i) {
+ /* Free only what we've created for the fake node, so remove
+ the attribute node element and then free the rest */
+ IDL_PARAM_DCL(IDL_LIST(
+ IDL_OP_DCL(curop).parameter_dcls).data).param_type_spec = NULL;
+ }
+
+ /* Remove what we've "borrowed" from ATTR_DCL from the
+ fake curop node then free the rest */
+ IDL_OP_DCL(curop).op_type_spec = NULL;
+ IDL_tree_free(curop);
+ }
+ }
+
+ g_string_free(attrname, TRUE);
+}
+
+static void
+cbe_ski_do_attr_dcl(CBESkelImplInfo *ski)
+{
+ cbe_ski_do_attr_dcl_internal(ski, NULL, FALSE);
+}
+
+void
+cbe_ski_do_inherited_attr_dcl(CBESkelImplInfo *ski, IDL_tree current_interface)
+{
+ cbe_ski_do_attr_dcl_internal(ski, current_interface, TRUE);
+}
+
+static void
+cbe_ski_do_op_dcl(CBESkelImplInfo *ski)
+{
+ /* If you fix anything here, please also fix it in
+ cbe_ski_do_inherited_op_dcl(), which is almost a
+ cut-and-paste of this routine */
+
+ char *id, *id2;
+ IDL_tree curitem, op;
+ int level;
+ CBESkelImplInfo subski = *ski;
+
+ switch(ski->pass) {
+ case PASS_PROTOS:
+ case PASS_IMPLSTUBS:
+ curitem = IDL_get_parent_node(ski->tree, IDLN_INTERFACE, &level);
+ g_assert(curitem);
+
+ id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(ski->tree).ident), "_", 0);
+ id2 = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(curitem).ident), "_", 0);
+
+ /* protect with #ifdef block */
+ if(PASS_PROTOS == ski->pass)
+ fprintf(ski->of, "#if !defined(_decl_impl_");
+ else
+ fprintf(ski->of, "#if !defined(_impl_");
+ fprintf(ski->of, "%s_)\n", id);
+
+ if(PASS_PROTOS == ski->pass)
+ fprintf(ski->of, "#define _decl_impl_");
+ else
+ fprintf(ski->of, "#define _impl_");
+ fprintf(ski->of, "%s_ 1\n", id);
+
+ fprintf(ski->of, "static ");
+ forb_cbe_write_param_typespec(ski->of, ski->tree);
+ fprintf(ski->of, "\nimpl_%s(impl_POA_%s *servant,\n", id, id2);
+ g_free(id); g_free(id2);
+
+ op = ski->tree;
+ for(curitem = IDL_OP_DCL(ski->tree).parameter_dcls;
+ curitem; curitem = IDL_LIST(curitem).next) {
+ subski.tree = IDL_LIST(curitem).data;
+ forb_cbe_ski_process_piece(&subski);
+ }
+
+ if(IDL_OP_DCL(op).context_expr)
+ fprintf(ski->of, "CORBA_Context ctx,\n");
+
+ fprintf(ski->of, "CORBA_Environment *ev)");
+ if(ski->pass == PASS_IMPLSTUBS) {
+ fprintf(ski->of, "\n{\n");
+ if(IDL_OP_DCL(op).op_type_spec) {
+ forb_cbe_write_param_typespec(ski->of, ski->tree);
+ fprintf(ski->of, " retval;\n");
+ fprintf(ski->of, " /* ------ insert method code here ------ */\n");
+ fprintf(ski->of, " /* ------ ---------- end ------------ ------ */\n");
+ fprintf(ski->of, "\nreturn retval;\n");
+ }
+ else
+ {
+ fprintf(ski->of, " /* ------ insert method code here ------ */\n");
+ fprintf(ski->of, " /* ------ ---------- end ------------ ------ */\n");
+ }
+ fprintf(ski->of, "}\n");
+ } else /* PASS_PROTOS */
+ fprintf(ski->of, ";\n");
+
+ fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
+ break; /* End PASS_PROTOS | PASS_IMPLSTUBS */
+ case PASS_EPVS:
+ id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(ski->tree).ident), "_", 0);
+ fprintf(ski->of, "(gpointer)&impl_%s,\n", id);
+ g_free(id);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+cbe_ski_do_inherited_op_dcl(CBESkelImplInfo *ski, IDL_tree current_interface)
+{
+ char *id, *id2;
+ IDL_tree ident, curitem, intf, op;
+ int level;
+ CBESkelImplInfo subski = *ski;
+
+ id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(current_interface).ident), "_", 0);
+ intf = IDL_get_parent_node(ski->tree, IDLN_INTERFACE, NULL);
+ id2 = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(intf).ident), "_", 0);
+
+ ident=IDL_OP_DCL(ski->tree).ident;
+ g_assert(ident);
+
+ switch(ski->pass) {
+ case PASS_PROTOS:
+ case PASS_IMPLSTUBS:
+ curitem = IDL_get_parent_node(ski->tree, IDLN_INTERFACE, &level);
+ g_assert(curitem);
+
+ /* protect with #ifdef block */
+ if(PASS_PROTOS == ski->pass)
+ fprintf(ski->of, "#if !defined(_decl_impl_");
+ else
+ fprintf(ski->of, "#if !defined(_impl_");
+ fprintf(ski->of, "%s_%s_)\n", id, IDL_IDENT(ident).str);
+
+ if(PASS_PROTOS == ski->pass)
+ fprintf(ski->of, "#define _decl_impl_");
+ else
+ fprintf(ski->of, "#define _impl_");
+ fprintf(ski->of, "%s_%s_ 1\n", id, IDL_IDENT(ident).str);
+
+ fprintf(ski->of, "static ");
+ forb_cbe_write_param_typespec(ski->of, ski->tree);
+ fprintf(ski->of, "\nimpl_%s_%s(impl_POA_%s *servant,\n", id, IDL_IDENT(ident).str, id);
+
+ op = ski->tree;
+ for(curitem = IDL_OP_DCL(ski->tree).parameter_dcls;
+ curitem; curitem = IDL_LIST(curitem).next) {
+ subski.tree = IDL_LIST(curitem).data;
+ forb_cbe_ski_process_piece(&subski);
+ }
+
+ if(IDL_OP_DCL(op).context_expr)
+ fprintf(ski->of, "CORBA_Context ctx,\n");
+
+ fprintf(ski->of, "CORBA_Environment *ev)");
+ if(ski->pass == PASS_IMPLSTUBS) {
+ fprintf(ski->of, "\n{\n");
+ if(IDL_OP_DCL(op).op_type_spec) {
+ forb_cbe_write_param_typespec(ski->of, ski->tree);
+ fprintf(ski->of, " retval;\n");
+ fprintf(ski->of, " /* ------ insert method code here ------ */\n");
+ fprintf(ski->of, " /* ------ ---------- end ------------ ------ */\n");
+ fprintf(ski->of, "\nreturn retval;\n");
+ }
+ else
+ {
+ fprintf(ski->of, " /* ------ insert method code here ------ */\n");
+ fprintf(ski->of, " /* ------ ---------- end ------------ ------ */\n");
+ }
+ fprintf(ski->of, "}\n");
+ } else /* PASS_PROTOS */
+ fprintf(ski->of, ";\n");
+
+ fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
+ break; /* End PASS_PROTOS | PASS_IMPLSTUBS */
+ case PASS_EPVS:
+ ident=IDL_OP_DCL(ski->tree).ident;
+ g_assert(ident);
+
+ fprintf(ski->of, "(gpointer)&impl_%s_%s,\n", id, IDL_IDENT(ident).str);
+ default:
+ break;
+ }
+
+ g_free(id);
+ g_free(id2);
+}
+
+static void
+cbe_ski_do_param_dcl(CBESkelImplInfo *ski)
+{
+ forb_cbe_write_param_typespec(ski->of, ski->tree);
+ fprintf(ski->of, " %s,\n", IDL_IDENT(IDL_PARAM_DCL(ski->tree).simple_declarator).str);
+}
+
+static void
+cbe_ski_do_interface_vepv_entry(IDL_tree interface, CBESkelImplInfo *ski)
+{
+ char *id, *inherit_id;
+
+ if(interface==ski->tree) {
+ id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(ski->tree).ident), "_", 0);
+ fprintf(ski->of, "&impl_%s_epv,\n", id);
+ g_free(id);
+ return;
+ }
+
+ id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(ski->tree).ident), "_", 0);
+ inherit_id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(interface).ident),
+ "_", 0);
+ fprintf(ski->of, "&impl_%s_%s_epv,\n", id, inherit_id);
+
+ g_free(id);
+ g_free(inherit_id);
+}
+
+static void
+cbe_ski_do_inherited_methods(IDL_tree interface, CBESkelImplInfo *ski)
+{
+ CBESkelImplInfo subski= *ski;
+ IDL_tree curitem;
+ char *id = NULL, *inherit_id = NULL; /* Quiet gcc */
+
+ if(interface==ski->tree)
+ return;
+
+ if(ski->pass==PASS_EPVS) {
+ id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(ski->tree).ident),
+ "_", 0);
+ inherit_id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(interface).ident),
+ "_", 0);
+ /* protect with #ifdef block */
+ fprintf(ski->of, "#if !defined(_impl_%s_%s_epv_)\n", id, inherit_id);
+ fprintf(ski->of, "#define _impl_%s_%s_epv_ 1\n", id, inherit_id);
+ fprintf(ski->of, "static POA_%s__epv impl_%s_%s_epv = {\nNULL, /* _private */\n", inherit_id, id, inherit_id);
+ }
+
+ for(curitem = IDL_INTERFACE(interface).body; curitem; curitem=IDL_LIST(curitem).next) {
+ subski.tree=IDL_LIST(curitem).data;
+
+ switch(IDL_NODE_TYPE(IDL_LIST(curitem).data)) {
+ case IDLN_OP_DCL:
+ cbe_ski_do_inherited_op_dcl(&subski, ski->tree);
+ break;
+ case IDLN_ATTR_DCL:
+ cbe_ski_do_inherited_attr_dcl(&subski, ski->tree);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if(ski->pass==PASS_EPVS) {
+ fprintf(ski->of, "};\n");
+ fprintf(ski->of, "#endif\n"); /* end of protective #ifdef block */
+
+ g_free(id);
+ g_free(inherit_id);
+ }
+}
+
+static void
+cbe_ski_do_interface(CBESkelImplInfo *ski)
+{
+ char *id;
+ CBESkelImplInfo subski = *ski;
+
+ id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(ski->tree).ident), "_", 0);
+
+ switch(ski->pass) {
+ case PASS_SERVANTS:
+ /* protect with #ifdef block */
+ fprintf(ski->of, "#if !defined(_typedef_impl_POA_%s_)\n", id);
+ fprintf(ski->of, "#define _typedef_impl_POA_%s_ 1\n", id);
+
+ fprintf(ski->of, "typedef struct {\nPOA_%s servant;\nPortableServer_POA poa;\n", id);
+ subski.tree = IDL_INTERFACE(ski->tree).body;
+ cbe_ski_do_list(&subski);
+ IDL_tree_traverse_parents(ski->tree, (GFunc)&cbe_ski_do_inherited_methods, ski);
+ fprintf(ski->of, " /* ------ add private attributes here ------ */\n");
+ fprintf(ski->of, " /* ------ ---------- end ------------ ------ */\n");
+ fprintf(ski->of, "} impl_POA_%s;\n", id);
+
+ fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
+ break;
+ case PASS_EPVS:
+ /* protect with #ifdef block */
+ fprintf(ski->of, "#if !defined(_impl_%s_base_epv_)\n", id);
+ fprintf(ski->of, "#define _impl_%s_base_epv_ 1\n", id);
+ fprintf(ski->of, "static PortableServer_ServantBase__epv impl_%s_base_epv = {\n", id);
+ fprintf(ski->of, "NULL, /* _private data */\n");
+ fprintf(ski->of, "(gpointer) & impl_%s__destroy, /* finalize routine */\n", id);
+ fprintf(ski->of, "NULL, /* default_POA routine */\n");
+ fprintf(ski->of, "};\n");
+ fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
+
+ /* protect with #ifdef block */
+ fprintf(ski->of, "#if !defined(_impl_%s_epv_)\n", id);
+ fprintf(ski->of, "#define _impl_%s_epv_ 1\n", id);
+ fprintf(ski->of, "static POA_%s__epv impl_%s_epv = {\nNULL, /* _private */\n", id, id);
+ subski.tree = IDL_INTERFACE(ski->tree).body;
+ cbe_ski_do_list(&subski);
+ fprintf(ski->of, "};\n");
+ fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
+
+ IDL_tree_traverse_parents(ski->tree, (GFunc)&cbe_ski_do_inherited_methods, ski);
+ break;
+ case PASS_VEPVS:
+ /* protect with #ifdef block */
+ fprintf(ski->of, "#if !defined(_impl_%s_vepv_)\n", id);
+ fprintf(ski->of, "#define _impl_%s_vepv_ 1\n", id);
+
+ fprintf(ski->of, "static POA_%s__vepv impl_%s_vepv = {\n", id, id);
+ fprintf(ski->of, "&impl_%s_base_epv,\n", id);
+ IDL_tree_traverse_parents(ski->tree, (GFunc)&cbe_ski_do_interface_vepv_entry, ski);
+ fprintf(ski->of, "};\n");
+
+ fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
+ break;
+ case PASS_IMPLSTUBS:
+ /* protect __create with #ifdef block */
+ fprintf(ski->of, "#if !defined(_impl_%s__create_)\n", id);
+ fprintf(ski->of, "#define _impl_%s__create_ 1\n", id);
+ fprintf(ski->of, "static %s impl_%s__create(PortableServer_POA poa, CORBA_Environment *ev)\n", id, id);
+ fprintf(ski->of, "{\n%s retval;\nimpl_POA_%s *newservant;\nPortableServer_ObjectId *objid;\n\n", id, id);
+ fprintf(ski->of, "newservant = g_new0(impl_POA_%s, 1);\n", id);
+ fprintf(ski->of, "newservant->servant.vepv = &impl_%s_vepv;\n", id);
+ fprintf(ski->of, "newservant->poa = (PortableServer_POA) CORBA_Object_duplicate((CORBA_Object)poa, ev);\n");
+ fprintf(ski->of, "POA_%s__init((PortableServer_Servant)newservant, ev);\n", id);
+ fprintf(ski->of, " /* Before servant is going to be activated all\n");
+ fprintf(ski->of, " * private attributes must be initialized. */\n");
+ fprintf(ski->of, "\n");
+ fprintf(ski->of, " /* ------ init private attributes here ------ */\n");
+ fprintf(ski->of, " /* ------ ---------- end ------------- ------ */\n");
+ fprintf(ski->of, "\n");
+ fprintf(ski->of, "objid = PortableServer_POA_activate_object(poa, newservant, ev);\n");
+ fprintf(ski->of, "CORBA_free(objid);\n");
+ fprintf(ski->of, "retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);\n");
+ fprintf(ski->of, "\nreturn retval;\n}\n");
+ fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
+
+ /* protect __destroy with #ifdef block */
+ fprintf(ski->of, "#if !defined(_impl_%s__destroy_)\n", id);
+ fprintf(ski->of, "#define _impl_%s__destroy_ 1\n", id);
+ fprintf(ski->of, "static void\nimpl_%s__destroy(impl_POA_%s *servant, CORBA_Environment *ev)\n{\n", id, id);
+ fprintf(ski->of, " CORBA_Object_release ((CORBA_Object) servant->poa, ev);\n\n");
+ fprintf(ski->of, " /* No further remote method calls are delegated to \n");
+ fprintf(ski->of, " * servant and you may free your private attributes. */\n");
+ fprintf(ski->of, " /* ------ free private attributes here ------ */\n");
+ fprintf(ski->of, " /* ------ ---------- end ------------- ------ */\n");
+ fprintf(ski->of, "\nPOA_%s__fini((PortableServer_Servant)servant, ev);\n", id);
+ fprintf(ski->of, "\ng_free (servant);\n");
+ fprintf(ski->of, "}\n");
+ fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
+
+ subski.tree = IDL_INTERFACE(ski->tree).body;
+ cbe_ski_do_list(&subski);
+ IDL_tree_traverse_parents(ski->tree, (GFunc)&cbe_ski_do_inherited_methods, ski);
+ break;
+ case PASS_PROTOS:
+ /* protect __destroy declaration with #ifdef block */
+ fprintf(ski->of, "#if !defined(_decl_impl_%s__destroy_)\n", id);
+ fprintf(ski->of, "#define _decl_impl_%s__destroy_ 1\n", id);
+ fprintf(ski->of, "static void impl_%s__destroy(impl_POA_%s *servant,\nCORBA_Environment *ev);\n", id, id);
+ fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
+
+ subski.tree = IDL_INTERFACE(ski->tree).body;
+ cbe_ski_do_list(&subski);
+ IDL_tree_traverse_parents(ski->tree, (GFunc)&cbe_ski_do_inherited_methods, ski);
+ break;
+ default:
+ break;
+ }
+
+ g_free(id);
+}
--- /dev/null
+#include "config.h"
+
+#include "forb-idl-c-backend.h"
+
+#include <string.h>
+
+typedef struct {
+ OIDL_C_Info *ci;
+ GSList *oplist;
+ int curlevel;
+} CBESkelInterfaceTraverseInfo;
+
+typedef struct {
+ char *iface_id;
+ char *opname;
+ IDL_tree op;
+ int idx;
+} CBESkelOpInfo;
+
+static void cbe_skel_do_interface(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
+
+static void
+ck_output_poastuff(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+ if( !tree || (tree->declspec & IDLF_DECLSPEC_PIDL)!=0 )
+ return;
+
+ switch(IDL_NODE_TYPE(tree)) {
+ case IDLN_MODULE:
+ ck_output_poastuff(IDL_MODULE(tree).definition_list, rinfo, ci);
+ break;
+ case IDLN_LIST:
+ {
+ IDL_tree sub;
+ for(sub = tree; sub; sub = IDL_LIST(sub).next) {
+ ck_output_poastuff(IDL_LIST(sub).data, rinfo, ci);
+ }
+ }
+ break;
+ case IDLN_INTERFACE:
+ cbe_skel_do_interface(tree, rinfo, ci);
+ break;
+ default:
+ break;
+ }
+}
+
+/* static gint */
+/* cbe_skel_compare_op_dcls(CBESkelOpInfo *op1, CBESkelOpInfo *op2) */
+/* { */
+/* return strcmp(op1->opname, op2->opname); */
+/* } */
+
+/* static void */
+/* cbe_skel_free_op_info(CBESkelOpInfo *op) */
+/* { */
+/* g_free(op->opname); */
+/* g_free(op->iface_id); */
+/* g_free(op); */
+/* } */
+
+/* static void */
+/* cbe_skel_interface_add_relayer (IDL_tree intf, CBESkelInterfaceTraverseInfo *iti) */
+/* { */
+/* CBESkelOpInfo *newopi; */
+/* IDL_tree curitem, curdcl, curattr, curattrdcl; */
+/* char *iface_id; */
+/* int idx = 0; */
+
+/* iface_id = */
+/* IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(intf).ident), */
+/* "_", 0); */
+
+/* for(curitem = IDL_INTERFACE(intf).body; curitem; */
+/* curitem = IDL_LIST(curitem).next) { */
+/* curdcl = IDL_LIST(curitem).data; */
+
+/* switch(IDL_NODE_TYPE(curdcl)) { */
+/* case IDLN_OP_DCL: */
+/* newopi = g_new0(CBESkelOpInfo, 1); */
+/* newopi->iface_id = g_strdup(iface_id); */
+/* newopi->opname = g_strdup(IDL_IDENT(IDL_OP_DCL(curdcl).ident).str); */
+/* newopi->idx = idx++; */
+/* iti->oplist = g_slist_insert_sorted(iti->oplist, newopi, */
+/* (GCompareFunc)cbe_skel_compare_op_dcls); */
+/* break; */
+/* case IDLN_ATTR_DCL: */
+/* for(curattr = IDL_ATTR_DCL(curdcl).simple_declarations; */
+/* curattr; curattr = IDL_LIST(curattr).next) { */
+/* curattrdcl = IDL_LIST(curattr).data; */
+
+/* newopi = g_new0(CBESkelOpInfo, 1); */
+/* newopi->iface_id = g_strdup(iface_id); */
+/* newopi->opname = g_strdup_printf("_get_%s", IDL_IDENT(curattrdcl).str); */
+/* newopi->idx = idx++; */
+/* iti->oplist = g_slist_insert_sorted(iti->oplist, newopi, */
+/* (GCompareFunc)cbe_skel_compare_op_dcls); */
+/* if(!IDL_ATTR_DCL(curdcl).f_readonly) { */
+/* newopi = g_new0(CBESkelOpInfo, 1); */
+/* newopi->iface_id = g_strdup(iface_id); */
+/* newopi->opname = g_strdup_printf("_set_%s", IDL_IDENT(curattrdcl).str); */
+/* newopi->idx = idx++; */
+/* iti->oplist = g_slist_insert_sorted(iti->oplist, newopi, */
+/* (GCompareFunc)cbe_skel_compare_op_dcls); */
+/* } */
+/* } */
+/* break; */
+/* default: */
+/* break; */
+/* } */
+/* } */
+
+/* g_free(iface_id); */
+/* } */
+
+/* static void */
+/* cbe_skel_interface_print_relayers(const CBESkelInterfaceTraverseInfo *iti) */
+/* { */
+/* CBESkelInterfaceTraverseInfo subiti = *iti; */
+/* GSList *curnode; */
+/* CBESkelOpInfo *opi; */
+/* char curchar; */
+
+/* curnode = iti->oplist; */
+/* subiti.curlevel = iti->curlevel+1; */
+/* fprintf(iti->ci->fh, "switch(opname[%d]) {\n", iti->curlevel); */
+/* while(curnode) { */
+/* opi = (CBESkelOpInfo *)curnode->data; */
+/* if(iti->curlevel > strlen(opi->opname)) { */
+/* curnode = g_slist_next(curnode); */
+/* continue; */
+/* } */
+/* curchar = opi->opname[iti->curlevel]; */
+/* if(curchar) */
+/* fprintf(iti->ci->fh, "case '%c':\n", curchar); */
+/* else */
+/* fprintf(iti->ci->fh, "case '\\0':\n"); */
+/* subiti.oplist = NULL; */
+/* while(curnode && ((CBESkelOpInfo *)curnode->data)->opname[iti->curlevel] */
+/* == curchar) { */
+/* subiti.oplist = g_slist_append(subiti.oplist, curnode->data); */
+/* curnode = g_slist_next(curnode); */
+/* } */
+
+/* if(g_slist_length(subiti.oplist) > 1) { */
+/* if(curchar) */
+/* cbe_skel_interface_print_relayers(&subiti); */
+/* else */
+/* g_error("two ops with same name!!!!"); */
+/* } else { */
+/* if(strlen(opi->opname + iti->curlevel)) */
+/* fprintf(iti->ci->fh, "if(strcmp((opname + %d), \"%s\")) break;\n", */
+/* iti->curlevel + 1, opi->opname + iti->curlevel+1); */
+/* fprintf(iti->ci->fh, "*impl = (gpointer)servant->vepv->%s_epv->%s;\n", */
+/* opi->iface_id, opi->opname); */
+/* fprintf(iti->ci->fh, "{Forb_IInterface *volatile _t_=&%s__iinterface;*m_data = (gpointer)&_t_->methods._buffer [%d];}\n", */
+/* opi->iface_id, opi->idx); */
+/* fprintf(iti->ci->fh, "return (ForbSmallSkeleton)_FORB_skel_small_%s_%s;\n", */
+/* opi->iface_id, opi->opname); */
+/* } */
+/* fprintf(iti->ci->fh, "break;\n"); */
+/* g_slist_free(subiti.oplist); */
+/* } */
+/* fprintf(iti->ci->fh, "default: break; \n}\n"); */
+/* } */
+
+/* static void */
+/* cbe_skel_interface_print_relayer(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci) */
+/* { */
+/* char *id; */
+/* CBESkelInterfaceTraverseInfo iti; */
+
+/* id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(tree).ident), "_", 0); */
+/* fprintf(ci->fh, "static ForbSmallSkeleton get_skel_small_%s(POA_%s *servant,\nconst char *opname," */
+/* "gpointer *m_data, gpointer *impl)\n{\n", id, id); */
+
+/* iti.ci = ci; */
+/* iti.oplist = NULL; */
+/* iti.curlevel = 0; */
+
+/* IDL_tree_traverse_parents(tree, */
+/* (GFunc)cbe_skel_interface_add_relayer, &iti); */
+
+/* cbe_skel_interface_print_relayers(&iti); */
+
+/* g_slist_foreach(iti.oplist, (GFunc)cbe_skel_free_op_info, NULL); */
+/* g_slist_free(iti.oplist); */
+
+/* fprintf(ci->fh, "return NULL;\n"); */
+/* fprintf(ci->fh, "}\n\n"); */
+
+/* g_free(id); */
+/* } */
+
+typedef struct {
+ OIDL_C_Info *ci;
+ const char *for_id;
+} CBESkelVEPVMapTraverseInfo;
+
+/* static void */
+/* cbe_skel_interface_print_vepvmap_offsets (IDL_tree node, CBESkelVEPVMapTraverseInfo *ti) */
+/* { */
+/* char *id; */
+/* id = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (IDL_INTERFACE (node).ident), "_", 0); */
+/* fprintf (ti->ci->fh, "(CORBA_unsigned_long) %s__classid,\n", id); */
+/* fprintf (ti->ci->fh, "FORB_VEPV_OFFSET (POA_%s__vepv, %s_epv),\n", ti->for_id, id); */
+/* g_free (id); */
+/* } */
+
+/**
+ * If the type specified in @a type_spec is dynamically allocated
+ * (such as string, sequence or object reference), the parameters of
+ * this type must be freed after they are not needed. For input
+ * parameter this is after the implementation is called, for out and
+ * inout return parameters after the returned value is serialized.
+ */
+static void free_memory_if_needed(IDL_tree type_spec, const char *name, int n, OIDL_C_Info *ci)
+{
+ type_spec = forb_cbe_get_typespec(type_spec);
+ /* forb_idl_print_node(type_spec, 7); */
+ switch(IDL_NODE_TYPE(type_spec)) {
+ case IDLN_TYPE_STRING:
+ case IDLN_TYPE_WIDE_STRING:
+ fprintf(ci->fh, " ");
+ fprintf(ci->fh, "forb_free(%s);\n", name);
+ break;
+ case IDLN_TYPE_ARRAY:
+ break;
+ case IDLN_TYPE_SEQUENCE: {
+ char *dot = n==2?"->":".";
+ IDL_tree simple_type = forb_cbe_get_typespec(IDL_TYPE_SEQUENCE(type_spec).simple_type_spec);
+
+ fprintf(ci->fh, " if (CORBA_sequence_get_release(%s%s)) {\n",
+ n==2?"":"&",name);
+ if (IDLN_NATIVE == IDL_NODE_TYPE(simple_type)) {
+ fprintf(ci->fh, " int i;\n"
+ " for (i=0; i<%s%s_length; i++)\n"
+ " %s_free(%s%s_buffer[i]);\n",
+ name, dot, forb_cbe_get_typespec_str(IDL_NATIVE(type_spec).ident),
+ name, dot);
+ }
+ fprintf(ci->fh, " forb_free(%s%s_buffer);\n"
+ " }\n", name, dot);
+ if (n==2) {
+ fprintf(ci->fh, " ");
+ fprintf(ci->fh, "forb_free(%s);\n", name);
+ }
+ break;
+ }
+ case IDLN_NATIVE:
+ fprintf(ci->fh, " ");
+ fprintf(ci->fh, "%s_free(%s);\n",
+ forb_cbe_get_typespec_str(IDL_NATIVE(type_spec).ident),
+ name);
+ return;
+ case IDLN_INTERFACE:
+ fprintf(ci->fh, " ");
+ fprintf(ci->fh, "forb_object_release(%s);\n", name);
+ break;
+ default:
+ break;
+ }
+
+}
+
+static void ck_output_op_skel(IDL_tree op, char *intf_id, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+ char *id, *id_plain;
+ IDL_tree sub;
+ gboolean has_retval, has_args;
+ const char *const seq_init = " = {0,0,NULL}";
+
+ has_retval = IDL_OP_DCL (op).op_type_spec != NULL;
+ has_args = IDL_OP_DCL (op).parameter_dcls != NULL;
+
+ id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(op).ident), "_", 0);
+ id_plain = IDL_IDENT(IDL_OP_DCL(op).ident).str;
+ fprintf(ci->fh, "static void\n"
+ "forb_skel_%s(FORB_CDR_Codec *cin, FORB_CDR_Codec *cout, %s _obj, struct forb_env *env)\n"
+ "{\n",
+ id, intf_id);
+/* fprintf(ci->fh, " if (_obj->interface != %s_interface) {\n", intf_id); */
+/* fprintf(ci->fh, " env->major = FORB_EX_BAD_OPERATION;\n" */
+/* " return;\n" */
+/* " }\n"); */
+ fprintf(ci->fh, " if (_%s_impl(_obj) && _%s_impl(_obj)->%s) {\n", intf_id, intf_id, id_plain);
+
+ /* Declare variables for parameters */
+ for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+ IDL_tree parm = IDL_LIST (sub).data;
+ IDL_ParamRole role;
+ IDL_tree ts = forb_cbe_get_typespec(parm);
+ gboolean isSlice;
+ int n;
+ char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
+ role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
+ n = oidl_param_info (ts, role, &isSlice);
+
+ fprintf(ci->fh, " ");
+ forb_cbe_write_typespec(ci->fh, IDL_PARAM_DCL(parm).param_type_spec);
+ fprintf(ci->fh, " %s%s%s;\n",
+ n == 2 ? "*":"",
+ name,
+ (n < 2 && IDL_NODE_TYPE(ts) == IDLN_TYPE_SEQUENCE)?seq_init : "");
+ }
+ if (has_retval) {
+ fprintf (ci->fh, " ");
+ forb_cbe_write_param_typespec (ci->fh, op);
+ fprintf (ci->fh, " _forb_ret;\n"); /* TODO: seq_init */
+ }
+
+ /* Deserialize in parameters */
+ for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+ IDL_tree parm = IDL_LIST (sub).data;
+ IDL_ParamRole role;
+ role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
+ if (role == DATA_IN || role == DATA_INOUT) {
+ char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
+ fprintf(ci->fh, " if (!");
+ forb_cbe_write_typespec(ci->fh, IDL_PARAM_DCL(parm).param_type_spec);
+ fprintf(ci->fh, "_deserialize(cin, &%s)) {\n", name);
+ fprintf(ci->fh, " env->major = FORB_EX_MARSHAL; goto exception;\n }\n");
+ }
+ }
+
+ /* Call the implementation */
+ fprintf(ci->fh, " ");
+ if (has_retval)
+ fprintf(ci->fh, "_forb_ret = ");
+ fprintf(ci->fh, "_%s_impl(_obj)->%s(_obj, ",
+ intf_id, id_plain);
+ for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+ IDL_tree parm = IDL_LIST (sub).data;
+ IDL_ParamRole role;
+ IDL_tree ts = forb_cbe_get_typespec(parm);
+ gboolean isSlice;
+ int n;
+ char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
+ role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
+ n = oidl_param_info (ts, role, &isSlice);
+
+ fprintf(ci->fh, "%s%s, ", n?"&":"", name);
+ }
+ fprintf(ci->fh, "env);\n");
+ fprintf(ci->fh,
+ " if (forb_exception_occurred(env)) goto exception;\n");
+ if (has_retval) {
+ fprintf(ci->fh, " ");
+ forb_cbe_write_typespec(ci->fh, IDL_OP_DCL(op).op_type_spec);
+ fprintf(ci->fh, "_serialize(cout, &_forb_ret);\n");
+ }
+ for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+ IDL_tree parm = IDL_LIST (sub).data;
+ IDL_ParamRole role;
+ IDL_tree ts = forb_cbe_get_typespec(parm);
+ gboolean isSlice;
+ int n;
+ char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
+ role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
+ n = oidl_param_info (ts, role, &isSlice);
+ if (role == DATA_OUT || role == DATA_INOUT) {
+ fprintf(ci->fh, " ");
+ forb_cbe_write_typespec(ci->fh, IDL_PARAM_DCL(parm).param_type_spec);
+ fprintf(ci->fh, "_serialize(cout, %s%s);\n", n==2?"":"&", name);
+ }
+ }
+ fprintf(ci->fh, "exception:;\n");
+
+ /* Free all dynamically allocated parameteres and retvals */
+ if (has_retval) {
+ free_memory_if_needed(IDL_OP_DCL(op).op_type_spec, "_forb_ret", 0, ci);
+ }
+ for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+ IDL_tree parm = IDL_LIST (sub).data;
+ char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
+ IDL_ParamRole role;
+ IDL_tree ts = forb_cbe_get_typespec(parm);
+ gboolean isSlice;
+ int n;
+ role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
+ n = oidl_param_info (ts, role, &isSlice);
+ free_memory_if_needed(IDL_PARAM_DCL(parm).param_type_spec, name, n, ci);
+ }
+
+ fprintf(ci->fh, " } else {\n");
+ fprintf(ci->fh, " env->major = FORB_EX_NO_IMPLEMENT;\n");
+ fprintf(ci->fh, " }\n");
+ fprintf(ci->fh, "}\n\n");
+ g_free(id);
+}
+
+static void
+cbe_skel_do_interface(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
+{
+ char *id;
+ IDL_tree pnt;
+ IDL_tree sub;
+ //int i;
+ //CBESkelVEPVMapTraverseInfo ti;
+ int num_methods = 0;
+
+ /* PIDL methods dont have normal skel functions. */
+ for ( pnt=tree; pnt; pnt=IDL_NODE_UP(pnt) ) {
+ if ( pnt->declspec & IDLF_DECLSPEC_PIDL )
+ return;
+ }
+
+ id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(tree).ident), "_", 0);
+
+ fprintf(ci->fh, "#define _%s_impl(obj) ((struct forb_%s_impl*)(obj)->implementation)\n\n", id, id);
+ fprintf(ci->fh, "static const struct forb_interface %s_interface;\n\n", id);
+
+ for(sub = IDL_INTERFACE(tree).body; sub; sub = IDL_LIST(sub).next) {
+ IDL_tree cur = IDL_LIST(sub).data;
+
+ switch(IDL_NODE_TYPE(cur)) {
+ case IDLN_OP_DCL:
+ ck_output_op_skel(cur, id, rinfo, ci);
+ num_methods++;
+ break;
+ default:
+ break;
+ }
+ }
+
+ fprintf(ci->fh, "static const forb_skel_func %s_skeletons[%d] = {\n",
+ id, num_methods);
+ for(sub = IDL_INTERFACE(tree).body; sub; sub = IDL_LIST(sub).next) {
+ IDL_tree cur = IDL_LIST(sub).data;
+
+ switch(IDL_NODE_TYPE(cur)) {
+ case IDLN_OP_DCL: {
+ char *op_id;
+ op_id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(cur).ident), "_", 0);
+ fprintf(ci->fh, " forb_skel_%s,\n", op_id);
+ g_free(op_id);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ fprintf(ci->fh, "};\n\n");
+
+ fprintf(ci->fh, "static const struct forb_interface %s_interface = {\n", id);
+ fprintf(ci->fh, " .name = \"%s\",\n", id);
+ fprintf(ci->fh, " .num_methods = %d,\n", num_methods);
+ fprintf(ci->fh, " .skeletons = %s_skeletons,\n", id);
+ fprintf(ci->fh, " .type_hash = 0 /* not implemented */\n");
+ fprintf(ci->fh, "};\n\n");
+
+/* fprintf(ci->fh, "void forb_register_%s_interface(void)\n" */
+/* "{\n" */
+/* " forb_register_interface(&%s_interface);\n" */
+/* "}\n\n", id, id); */
+
+ fprintf(ci->fh, "%s forb_%s_new(forb_orb orb, const struct forb_%s_impl *impl,"
+ "void *instance_data)\n"
+ "{\n"
+ " %s obj = forb_object_new(orb, NULL, 0);\n"
+ " if (obj) {\n"
+ " obj->instance_data = instance_data;\n"
+ " obj->implementation = impl;\n"
+ " obj->interface = &%s_interface;\n"
+ " }\n"
+ " return obj;\n"
+ "}\n\n", id, id, id, id, id);
+ fprintf(ci->fh, "\n");
+
+
+/* cbe_skel_interface_print_relayer(tree, rinfo, ci); */
+
+/* fprintf(ci->fh, */
+/* "void POA_%s__init(PortableServer_Servant servant,\nCORBA_Environment *env)\n", */
+/* id); */
+/* fprintf(ci->fh, "{\n"); */
+/* fprintf(ci->fh," static PortableServer_ClassInfo class_info = {"); */
+
+/* fprintf(ci->fh, "NULL, (Forb_small_impl_finder)&get_skel_small_%s, ", id); */
+
+/* fprintf(ci->fh,"\"%s\", &%s__classid, NULL, &%s__iinterface};\n", */
+/* IDL_IDENT(IDL_INTERFACE(tree).ident).repo_id, id, id); */
+
+/* fprintf(ci->fh," PortableServer_ServantBase__init (" */
+/* " ((PortableServer_ServantBase *)servant), env);\n"); */
+
+/* for(curitem = IDL_INTERFACE(tree).inheritance_spec; curitem; */
+/* curitem = IDL_LIST(curitem).next) { */
+/* id2 = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_LIST(curitem).data), */
+/* "_", 0); */
+/* fprintf(ci->fh, " POA_%s__init(servant, env);\n", id2); */
+/* g_free(id2); */
+/* } */
+
+ /* registering after other __inits() makes the classids increment nicely. */
+/* fprintf (ci->fh, " Forb_skel_class_register (&class_info,\n"); */
+/* fprintf (ci->fh, " (PortableServer_ServantBase *)servant, POA_%s__fini,\n", id); */
+/* fprintf (ci->fh, " FORB_VEPV_OFFSET (POA_%s__vepv, %s_epv),\n", id, id); */
+/* ti.for_id = id; ti.ci = ci; */
+/* IDL_tree_traverse_parents_full (tree, (GFunc) cbe_skel_interface_print_vepvmap_offsets, &ti, FALSE); */
+/* fprintf (ci->fh, " (CORBA_unsigned_long) 0);"); */
+
+/* fprintf(ci->fh, "}\n\n"); */
+
+/* fprintf(ci->fh, */
+/* "void POA_%s__fini(PortableServer_Servant servant,\nCORBA_Environment *env)\n", */
+/* id); */
+/* fprintf(ci->fh, "{\n"); */
+/* if(IDL_INTERFACE(tree).inheritance_spec) */
+/* { */
+/* for(i = IDL_list_length(IDL_INTERFACE(tree).inheritance_spec) - 1; */
+/* i >= 0; i--) { */
+/* curitem = IDL_list_nth(IDL_INTERFACE(tree).inheritance_spec, i); */
+/* id2 = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_LIST(curitem).data), */
+/* "_", 0); */
+/* /\* XXX fixme - this is going to call ServantBase__fini multiple times *\/ */
+/* fprintf(ci->fh, " POA_%s__fini(servant, env);\n", */
+/* id2); */
+/* g_free(id2); */
+/* } */
+/* } */
+/* fprintf(ci->fh, " PortableServer_ServantBase__fini(servant, env);\n"); */
+/* fprintf(ci->fh, "}\n\n"); */
+
+ g_free(id);
+}
+
+void
+forb_idl_output_c_skeletons (IDL_tree tree,
+ OIDL_Run_Info *rinfo,
+ OIDL_C_Info *ci)
+{
+ fprintf (ci->fh, OIDL_C_WARNING);
+/* fprintf (ci->fh, "#include <string.h>\n"); */
+/* fprintf (ci->fh, "#define FORB2_STUBS_API\n"); */
+ fprintf (ci->fh, "#include \"%s.h\"\n\n", ci->base_name);
+ fprintf(ci->fh, "#include <forb/cdr.h>\n");
+ fprintf(ci->fh, "#include <forb/forb-internal.h>\n");
+ fprintf(ci->fh, "#include <forb/object.h>\n\n");
+
+ ck_output_poastuff (tree, rinfo, ci);
+}
--- /dev/null
+#include "config.h"
+
+#include "forb-idl-c-backend.h"
+
+#include <string.h>
+
+static void
+cs_output_stub (IDL_tree tree,
+ OIDL_C_Info *ci,
+ int *idx)
+{
+ FILE *of = ci->fh;
+ IDL_tree sub;
+ char *iface_id;
+ char *opname;
+ char *opname_plain;
+ gboolean has_retval, has_args;
+
+ g_return_if_fail (idx != NULL);
+
+ iface_id = IDL_ns_ident_to_qstring (
+ IDL_IDENT_TO_NS (IDL_INTERFACE (
+ IDL_get_parent_node (tree, IDLN_INTERFACE, NULL)
+ ).ident), "_", 0);
+ opname_plain = IDL_IDENT(IDL_OP_DCL (tree).ident).str;
+ opname = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (IDL_OP_DCL (tree).ident), "_", 0);
+
+ has_retval = IDL_OP_DCL (tree).op_type_spec != NULL;
+ has_args = IDL_OP_DCL (tree).parameter_dcls != NULL;
+
+ forb_cbe_op_write_proto (of, tree, "", FALSE);
+
+ fprintf (of, "\n{\n");
+
+ if (has_retval) {
+ fprintf (of, " ");
+ forb_cbe_write_param_typespec (of, tree);
+ fprintf (of, " " FORB_RETVAL_VAR_NAME ";\n");
+ }
+
+/* fprintf(of, " if (_obj->type != %s_type) {\n" */
+/* " ev->major = FORB_EX_BAD_OPERATION;\n", iface_id); */
+/* if (has_retval) { */
+/* fprintf(of, " return "FORB_RETVAL_VAR_NAME";\n"); */
+/* } */
+ fprintf(of, " if (ev) ev->major = FORB_EX_NONE;\n");
+ fprintf(of, " if (forb_object_is_local(_obj)) {\n");
+ fprintf(of, " if (!_obj->interface ||\n"
+ " strncmp(_obj->interface->name, \"%s\", %zd) != 0) {\n"
+ " ev->major = FORB_EX_BAD_OPERATION;\n"
+ " return %s;\n"
+ " }\n", iface_id, strlen(iface_id), has_retval ? FORB_RETVAL_VAR_NAME : "");
+ fprintf(of, " ");
+ if (has_retval) {
+ fprintf(of, FORB_RETVAL_VAR_NAME " = ");
+ }
+ fprintf(of, "_%s_impl(_obj)->%s(_obj, ",
+ iface_id, opname_plain);
+ for (sub = IDL_OP_DCL (tree).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+ IDL_tree parm = IDL_LIST (sub).data;
+ fprintf (of, "%s, ", IDL_IDENT (IDL_PARAM_DCL (parm).simple_declarator).str);
+ }
+ fprintf(of, "ev);\n");
+
+ fprintf(of, " } else {\n");
+ fprintf(of, " /* remote object */\n"
+ " forb_request_t req;\n");
+ fprintf(of, " ex_on_fail(forb_request_init(&req, _obj) == 0, FORB_EX_INTERNAL);\n");
+ fprintf(of, " forb_iop_prepare_request(&req, \"%s\", FORB_METHOD_INDEX(%s), ev);\n",
+ iface_id, opname);
+ fprintf(of, " if (forb_exception_occurred(ev)) goto exception;\n");
+ for (sub = IDL_OP_DCL (tree).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+ IDL_tree parm = IDL_LIST (sub).data;
+ IDL_ParamRole role;
+ role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
+ if (role == DATA_IN || role == DATA_INOUT) {
+ char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
+ gboolean isSlice;
+ IDL_tree ts = forb_cbe_get_typespec(parm);
+ int n = oidl_param_info (ts, role, &isSlice);
+ fprintf(of, " ex_on_fail(");
+ forb_cbe_write_typespec(of, IDL_PARAM_DCL(parm).param_type_spec);
+ fprintf(of, "_serialize(&req.cdr_request, %s%s), FORB_EX_IMP_LIMIT);\n",
+ n == 0 ? "&":"", name);
+ }
+ }
+ fprintf(of, " forb_request_send(&req, ev);\n");
+ fprintf(of, " if (forb_exception_occurred(ev)) goto exception;\n");
+ fprintf(of, " forb_request_wait_for_reply(&req);\n");
+ fprintf(of, " if (forb_exception_occurred(ev)) goto exception;\n");
+ if (has_retval) {
+ fprintf(of, " ");
+ forb_cbe_write_typespec(of, IDL_OP_DCL(tree).op_type_spec);
+ fprintf(of, "_deserialize(req.cdr_reply, &"FORB_RETVAL_VAR_NAME");\n");
+ }
+ for (sub = IDL_OP_DCL (tree).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+ IDL_tree parm = IDL_LIST (sub).data;
+ IDL_ParamRole role;
+ role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
+ if (role == DATA_OUT || role == DATA_INOUT) {
+ char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
+ gboolean isSlice;
+ IDL_tree ts = forb_cbe_get_typespec(parm);
+ int n = oidl_param_info (ts, role, &isSlice);
+ if (IDL_NODE_TYPE(forb_cbe_get_typespec(parm)) == IDLN_TYPE_SEQUENCE &&
+ role == DATA_OUT) { /* Allocate out sequence */
+ fprintf(ci->fh, " *%s = forb_malloc(sizeof(**%s));\n", name, name);
+ fprintf(ci->fh, " if (!*%s) { ev->major = FORB_EX_NO_MEMORY; goto exception; }\n", name);
+ fprintf(ci->fh, " memset(*%s, 0, sizeof(**%s));\n", name, name);
+ fprintf(ci->fh, " CORBA_sequence_set_release(*%s, CORBA_TRUE);\n", name);
+ /* TODO: Free previously allocated parameters on no memory error. */
+ }
+ fprintf(of, " ");
+ forb_cbe_write_typespec(of, IDL_PARAM_DCL(parm).param_type_spec);
+ fprintf(ci->fh, "_deserialize(req.cdr_reply, %s%s);\n", n==2?"*":"", name);
+ }
+ }
+ fprintf(of, " forb_request_signal_processed(&req);\n"
+ "exception:\n"
+ " forb_request_destroy(&req);\n");
+ fprintf(of, " }\n");
+ if (has_retval) {
+ fprintf(of, " return " FORB_RETVAL_VAR_NAME ";\n");
+ }
+
+ fprintf (of, "}\n\n");
+
+ g_free (iface_id);
+ g_free (opname);
+
+ (*idx)++;
+}
+
+static void
+cs_output_stubs (IDL_tree tree,
+ OIDL_C_Info *ci,
+ int *idx)
+{
+ if (!tree)
+ return;
+
+ switch (IDL_NODE_TYPE (tree)) {
+ case IDLN_MODULE:
+ cs_output_stubs (IDL_MODULE (tree).definition_list, ci, idx);
+ break;
+ case IDLN_LIST: {
+ IDL_tree sub;
+
+ for (sub = tree; sub; sub = IDL_LIST (sub).next)
+ cs_output_stubs (IDL_LIST (sub).data, ci, idx);
+ break;
+ }
+ case IDLN_ATTR_DCL: {
+/* IDL_tree node; */
+
+/* for (node = IDL_ATTR_DCL (tree).simple_declarations; node; node = IDL_LIST (node).next) { */
+/* OIDL_Attr_Info *ai; */
+
+/* ai = IDL_LIST (node).data->data; */
+
+/* cs_output_stubs (ai->op1, ci, idx); */
+
+/* if (ai->op2) */
+/* cs_output_stubs (ai->op2, ci, idx); */
+/* } */
+ break;
+ }
+ case IDLN_INTERFACE: {
+ int real_idx = 0;
+ char *id;
+ /* Do not output skeletons for PIDL interfaces */
+ if ((tree->declspec & IDLF_DECLSPEC_PIDL) == 0) {
+ id = IDL_ns_ident_to_qstring (IDL_INTERFACE (tree).ident, "_", 0);
+ fprintf(ci->fh, "#define _%s_impl(obj) ((struct forb_%s_impl*)(obj)->implementation)\n\n",
+ id, id);
+ g_free(id);
+ cs_output_stubs (IDL_INTERFACE (tree).body, ci, &real_idx);
+ }
+ break;
+ }
+ case IDLN_OP_DCL:
+ cs_output_stub (tree, ci, idx);
+ break;
+ default:
+ break;
+ }
+}
+
+void
+forb_idl_output_c_stubs (IDL_tree tree,
+ OIDL_Run_Info *rinfo,
+ OIDL_C_Info *ci)
+{
+ fprintf (ci->fh, OIDL_C_WARNING);
+ fprintf (ci->fh, "#include <string.h>\n");
+/* fprintf (ci->fh, "#define FORB2_STUBS_API\n"); */
+ fprintf (ci->fh, "#include <forb/forb-internal.h>\n");
+ fprintf (ci->fh, "#include <forb/request.h>\n");
+ fprintf (ci->fh, "#include <forb/iop.h>\n");
+ fprintf (ci->fh, "#include <forb/cdr.h>\n");
+ fprintf (ci->fh, "#include <forb/object.h>\n\n");
+ fprintf (ci->fh, "#include \"%s.h\"\n\n", ci->base_name);
+
+ fprintf (ci->fh, "#define ex_on_fail(command, ex) if (!(command)) do { ev->major = (ex); goto exception; } while(0)\n");
+ fprintf (ci->fh, "#define FORB_REQEST_HDR_SIZE (forb_iop_MESSAGE_HEADER_SIZE + forb_iop_REQUEST_HEADER_SIZE)\n\n");
+
+ cs_output_stubs (tree, ci, NULL);
+}
--- /dev/null
+#include "forb-idl-c-backend.h"
+
+#include <string.h>
+#include <inttypes.h>
+
+typedef struct {
+ IDL_tree ts;
+ char *structname;
+ char *substructname;
+ int array_gen_ctr;
+} CBETCGenInfo;
+
+static int random_id = 0;
+
+static char *forb_generate_tcstruct_name (IDL_tree ts);
+static void cbe_tc_generate (OIDL_C_Info *ci, CBETCGenInfo *tci);
+
+void
+forb_output_typecode (OIDL_C_Info *ci,
+ IDL_tree node)
+{
+ CBETCGenInfo tci;
+
+ switch (IDL_NODE_TYPE (node)) {
+ case IDLN_TYPE_DCL:
+ case IDLN_TYPE_STRUCT:
+ case IDLN_TYPE_UNION:
+ case IDLN_TYPE_ENUM:
+ case IDLN_EXCEPT_DCL:
+ case IDLN_TYPE_SEQUENCE:
+ case IDLN_INTERFACE:
+ break;
+ default:
+ g_error ("You can't produce a typecode for a %s",
+ IDL_tree_type_names[IDL_NODE_TYPE (node)]);
+ }
+
+ tci.ts = node;
+ tci.structname = forb_generate_tcstruct_name (node);
+ tci.substructname = NULL;
+ tci.array_gen_ctr = 0;
+
+ cbe_tc_generate (ci, &tci);
+
+ g_free (tci.structname);
+}
+
+static char *
+forb_generate_tcstruct_name (IDL_tree node)
+{
+ GString *tmpstr;
+ char *retval;
+
+ tmpstr = g_string_new (NULL);
+
+ switch (IDL_NODE_TYPE (node)) {
+ case IDLN_TYPE_INTEGER:
+ case IDLN_TYPE_ANY:
+ case IDLN_TYPE_STRING:
+ case IDLN_TYPE_WIDE_STRING:
+ case IDLN_TYPE_CHAR:
+ case IDLN_TYPE_WIDE_CHAR:
+ case IDLN_TYPE_FLOAT:
+ case IDLN_TYPE_BOOLEAN:
+ case IDLN_TYPE_OCTET:
+ case IDLN_TYPE_SEQUENCE:
+ case IDLN_TYPE_STRUCT:
+ case IDLN_TYPE_UNION:
+ case IDLN_TYPE_ENUM:
+ case IDLN_IDENT:
+ case IDLN_EXCEPT_DCL:
+ case IDLN_INTERFACE:
+ case IDLN_FORWARD_DCL:
+ case IDLN_TYPE_OBJECT: {
+ char *typespec = forb_cbe_get_typespec_str (node);
+
+ g_string_printf (tmpstr, "TC_%s", typespec);
+
+ g_free (typespec);
+ }
+ break;
+ default:
+ g_string_printf (tmpstr, "anonTC_%d", random_id++);
+ break;
+ }
+
+ retval = tmpstr->str;
+ g_string_free (tmpstr, FALSE);
+
+ return retval;
+}
+
+static void
+forb_output_tcstruct_anon_subnames_array (FILE *fh, IDL_tree node, int subnames_id)
+{
+ IDL_tree l;
+
+ switch (IDL_NODE_TYPE (node)) {
+ case IDLN_TYPE_ENUM:
+ if (!IDL_TYPE_ENUM (node).enumerator_list)
+ break;
+
+ fprintf (fh, "static const char *anon_subnames_array%d[] = {", subnames_id);
+
+ for (l = IDL_TYPE_ENUM (node).enumerator_list; l; l = IDL_LIST (l).next) {
+ g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_IDENT);
+
+ fprintf (fh, "\"%s\"", IDL_IDENT (IDL_LIST (l).data).str );
+ if (IDL_LIST (l).next)
+ fprintf (fh, ", ");
+ }
+
+ fprintf (fh, "};\n");
+ break;
+ case IDLN_EXCEPT_DCL:
+ case IDLN_TYPE_STRUCT:
+ if (!IDL_TYPE_STRUCT (node).member_list)
+ break;
+
+ fprintf (fh, "static const char *anon_subnames_array%d[] = {", subnames_id);
+
+ for (l = IDL_TYPE_STRUCT (node).member_list; l; l = IDL_LIST (l).next) {
+ IDL_tree dcl;
+
+ g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_MEMBER);
+
+ for (dcl = IDL_MEMBER (IDL_LIST (l).data).dcls; dcl;
+ dcl = IDL_LIST (dcl).next) {
+ IDL_tree p = IDL_LIST (dcl).data;
+
+ g_assert (IDL_NODE_TYPE (p) == IDLN_IDENT ||
+ IDL_NODE_TYPE (p) == IDLN_TYPE_ARRAY);
+
+ if (IDL_NODE_TYPE (p) == IDLN_IDENT)
+ fprintf (fh, "\"%s\"", IDL_IDENT (p).str);
+
+ else /* IDLN_TYPE_ARRAY */
+ fprintf (fh, "\"%s\"",
+ IDL_IDENT (IDL_TYPE_ARRAY (p).ident).str);
+
+ if (IDL_LIST (dcl).next || IDL_LIST (l).next)
+ fprintf (fh, ", ");
+ }
+ }
+
+ fprintf (fh, "};\n");
+ break;
+ case IDLN_TYPE_UNION:
+ if (!IDL_TYPE_UNION (node).switch_body)
+ break;
+
+ fprintf (fh, "static const char * anon_subnames_array%d[] = {", subnames_id);
+
+ for (l = IDL_TYPE_UNION (node).switch_body; l; l = IDL_LIST (l).next) {
+ IDL_tree dcl, label;
+ const char *subname;
+
+ g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_CASE_STMT);
+
+ dcl = IDL_LIST (IDL_MEMBER (
+ IDL_CASE_STMT (IDL_LIST (l).data).element_spec).dcls).data;
+
+ g_assert (IDL_NODE_TYPE (dcl) == IDLN_IDENT ||
+ IDL_NODE_TYPE (dcl) == IDLN_TYPE_ARRAY);
+
+ if (IDL_NODE_TYPE (dcl) == IDLN_IDENT)
+ subname = IDL_IDENT (dcl).str;
+ else /* IDLN_TYPE_ARRAY */
+ subname = IDL_IDENT (IDL_TYPE_ARRAY (dcl).ident).str;
+
+ /* output the name once for each label */
+ for (label = IDL_CASE_STMT (IDL_LIST (l).data).labels;
+ label != NULL; label = IDL_LIST (label).next) {
+ fprintf (fh, "\"%s\"", subname);
+ if (IDL_LIST (label).next)
+ fprintf (fh, ", ");
+ }
+
+ if (IDL_LIST (l).next)
+ fprintf (fh, ", ");
+ }
+ fprintf (fh, "};\n");
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+forb_output_tcstruct_anon_subtypes_array (FILE *fh,
+ IDL_tree node,
+ int subtypes_id,
+ char *substructname)
+{
+ IDL_tree l;
+
+ switch (IDL_NODE_TYPE (node)) {
+ case IDLN_EXCEPT_DCL:
+ case IDLN_TYPE_STRUCT:
+ if (!IDL_TYPE_STRUCT (node).member_list)
+ break;
+
+ fprintf (fh, "static FORB2_MAYBE_CONST CORBA_TypeCode anon_subtypes_array%d[] = {",
+ subtypes_id);
+
+ for (l = IDL_TYPE_STRUCT (node).member_list; l; l = IDL_LIST (l).next) {
+ IDL_tree dcl;
+ char *tmpstr;
+
+ dcl = IDL_MEMBER (IDL_LIST (l).data).type_spec;
+
+ switch (IDL_NODE_TYPE (dcl)) {
+ case IDLN_IDENT:
+ case IDLN_INTERFACE:
+ case IDLN_TYPE_OBJECT:
+ case IDLN_FORWARD_DCL:
+ dcl = forb_cbe_get_typespec (dcl);
+
+ if (IDL_NODE_DECLSPEC (dcl) & IDLF_DECLSPEC_PIDL &&
+ (IDL_NODE_TYPE (dcl) == IDLN_INTERFACE ||
+ IDL_NODE_TYPE (dcl) == IDLN_FORWARD_DCL))
+ tmpstr = g_strdup ("Object");
+ else
+ tmpstr = forb_cbe_get_typespec_str (
+ IDL_MEMBER (IDL_LIST (l).data).type_spec);
+ break;
+ default:
+ tmpstr = forb_cbe_get_typespec_str (
+ IDL_MEMBER (IDL_LIST (l).data).type_spec);
+ break;
+ }
+
+ g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_MEMBER);
+
+ for (dcl = IDL_MEMBER (IDL_LIST (l).data).dcls; dcl;
+ dcl = IDL_LIST (dcl).next) {
+
+ fprintf (fh, "(CORBA_TypeCode)&TC_%s_struct", tmpstr);
+
+ if (IDL_LIST (dcl).next || IDL_LIST (l).next)
+ fprintf (fh, ", ");
+ }
+
+ g_free (tmpstr);
+ }
+
+ fprintf (fh, "};\n");
+
+ break;
+ case IDLN_TYPE_UNION:
+ if (!IDL_TYPE_UNION (node).switch_body)
+ break;
+
+ fprintf (fh, "static FORB2_MAYBE_CONST CORBA_TypeCode anon_subtypes_array%d[] = {", subtypes_id);
+
+ for (l = IDL_TYPE_UNION (node).switch_body; l; l = IDL_LIST (l).next) {
+ IDL_tree label, dcl;
+ char *tmpstr;
+
+ g_assert (IDL_NODE_TYPE (IDL_LIST (l).data) == IDLN_CASE_STMT);
+
+ dcl = IDL_MEMBER (IDL_CASE_STMT (IDL_LIST (l).data).element_spec).type_spec;
+
+ switch (IDL_NODE_TYPE (forb_cbe_get_typespec (dcl))) {
+ case IDLN_INTERFACE:
+ case IDLN_FORWARD_DCL:
+ if (IDL_NODE_DECLSPEC (dcl) & IDLF_DECLSPEC_PIDL)
+ tmpstr = g_strdup ( "Object");
+ else
+ tmpstr = forb_cbe_get_typespec_str (dcl);
+ break;
+ default:
+ tmpstr = forb_cbe_get_typespec_str (dcl);
+ break;
+ }
+
+ for (label = IDL_CASE_STMT (IDL_LIST (l).data).labels; label;
+ label = IDL_LIST (label).next) {
+ fprintf (fh, "(CORBA_TypeCode)&TC_%s_struct", tmpstr);
+
+ if (IDL_LIST (label).next || IDL_LIST (l).next)
+ fprintf (fh, ", ");
+ }
+
+ g_free (tmpstr);
+ }
+
+ fprintf (fh, "};\n");
+
+ break;
+ case IDLN_TYPE_SEQUENCE: {
+ IDL_tree seqts;
+ char *tmpstr;
+
+ seqts = forb_cbe_get_typespec (IDL_TYPE_SEQUENCE (node).simple_type_spec);
+
+ fprintf (fh, "static FORB2_MAYBE_CONST CORBA_TypeCode anon_subtypes_array%d[] = ", subtypes_id);
+
+ switch (IDL_NODE_TYPE (seqts)) {
+ case IDLN_INTERFACE:
+ case IDLN_FORWARD_DCL:
+ if (IDL_NODE_DECLSPEC (seqts) && IDLF_DECLSPEC_PIDL)
+ tmpstr = g_strdup ("Object");
+ else
+ tmpstr = forb_cbe_get_typespec_str (
+ IDL_TYPE_SEQUENCE (node).simple_type_spec);
+ break;
+ default:
+ tmpstr = forb_cbe_get_typespec_str (
+ IDL_TYPE_SEQUENCE (node).simple_type_spec);
+ break;
+ }
+
+ fprintf (fh, "{(CORBA_TypeCode)&TC_%s_struct};\n", tmpstr);
+ g_free (tmpstr);
+
+ }
+ break;
+ case IDLN_TYPE_ARRAY:
+ case IDLN_IDENT:
+ fprintf (fh, "static FORB2_MAYBE_CONST CORBA_TypeCode anon_subtypes_array%d[] = ", subtypes_id);
+ fprintf (fh, "{(CORBA_TypeCode)&%s_struct};\n", substructname);
+ break;
+ default:
+ break;
+ }
+}
+
+static int
+forb_output_tcstruct_anon_sublabels_array (FILE *fh,
+ IDL_tree node,
+ int sublabels_id)
+{
+ IDL_tree l, label;
+ int index = 0;
+ int default_index = -1;
+
+ if (IDL_NODE_TYPE (node) != IDLN_TYPE_UNION ||
+ !IDL_TYPE_UNION (node).switch_body)
+ return default_index;
+
+ fprintf (fh, "static FORB2_MAYBE_CONST CORBA_long anon_sublabels_array%d[] = {", sublabels_id);
+
+ for (l = IDL_TYPE_UNION (node).switch_body; l; l = IDL_LIST (l).next)
+ for (label = IDL_CASE_STMT (IDL_LIST (l).data).labels; label;
+ label = IDL_LIST (label).next, index++) {
+
+ if (IDL_LIST (label).data) {
+ fprintf (fh, "(CORBA_long) ");
+
+ forb_cbe_write_const (fh, IDL_LIST (label).data);
+
+ } else { /* default case */
+ fprintf (fh, "-1");
+ default_index = index;
+ }
+
+ if (IDL_LIST (label).next || IDL_LIST (l).next)
+ fprintf (fh, ", ");
+ }
+
+ fprintf (fh, "};\n");
+
+ return default_index;
+}
+
+static void
+forb_output_tcstruct_parent (FILE *fh)
+{
+ fprintf (fh, "{&Forb_TypeCode_epv, FORB_REFCOUNT_STATIC}");
+}
+
+static void
+forb_output_tcstruct_kind (FILE *fh, IDL_tree node, int array_gen_ctr)
+{
+ switch (IDL_NODE_TYPE (node)) {
+ case IDLN_TYPE_ARRAY:
+ if (array_gen_ctr)
+ fprintf (fh, "CORBA_tk_array");
+ else
+ fprintf (fh, "CORBA_tk_alias");
+ break;
+ case IDLN_IDENT:
+ fprintf (fh, "CORBA_tk_alias");
+ break;
+ case IDLN_TYPE_STRUCT:
+ fprintf (fh, "CORBA_tk_struct");
+ break;
+ case IDLN_TYPE_UNION:
+ fprintf (fh, "CORBA_tk_union");
+ break;
+ case IDLN_TYPE_ENUM:
+ fprintf (fh, "CORBA_tk_enum");
+ break;
+ case IDLN_TYPE_OBJECT:
+ case IDLN_INTERFACE:
+ case IDLN_FORWARD_DCL:
+ fprintf (fh, "CORBA_tk_objref");
+ break;
+ case IDLN_EXCEPT_DCL:
+ fprintf (fh, "CORBA_tk_except");
+ break;
+ case IDLN_TYPE_INTEGER:
+ fprintf (fh, "CORBA_tk_");
+
+ if (!IDL_TYPE_INTEGER (node).f_signed)
+ fprintf (fh, "u");
+
+ switch (IDL_TYPE_INTEGER (node).f_type) {
+ case IDL_INTEGER_TYPE_SHORT:
+ fprintf (fh, "short");
+ break;
+ case IDL_INTEGER_TYPE_LONG:
+ fprintf (fh, "long");
+ break;
+ case IDL_INTEGER_TYPE_LONGLONG:
+ fprintf (fh, "longlong");
+ break;
+ }
+ break;
+ case IDLN_TYPE_FLOAT:
+ fprintf (fh, "CORBA_tk_");
+
+ switch (IDL_TYPE_FLOAT (node).f_type) {
+ case IDL_FLOAT_TYPE_FLOAT:
+ fprintf (fh, "float");
+ break;
+ case IDL_FLOAT_TYPE_DOUBLE:
+ fprintf (fh, "double");
+ break;
+ case IDL_FLOAT_TYPE_LONGDOUBLE:
+ fprintf (fh, "longdouble");
+ break;
+ }
+ break;
+ case IDLN_TYPE_BOOLEAN:
+ fprintf (fh, "CORBA_tk_boolean");
+ break;
+ case IDLN_TYPE_OCTET:
+ fprintf (fh, "CORBA_tk_octet");
+ break;
+ case IDLN_TYPE_STRING:
+ fprintf (fh, "CORBA_tk_string");
+ break;
+ case IDLN_TYPE_WIDE_STRING:
+ fprintf (fh, "CORBA_tk_wstring");
+ break;
+ case IDLN_TYPE_CHAR:
+ fprintf (fh, "CORBA_tk_char");
+ break;
+ case IDLN_TYPE_WIDE_CHAR:
+ fprintf (fh, "CORBA_tk_wchar");
+ break;
+ case IDLN_TYPE_ANY:
+ fprintf (fh, "CORBA_tk_any");
+ break;
+ case IDLN_TYPE_SEQUENCE:
+ fprintf (fh, "CORBA_tk_sequence");
+ break;
+ default:
+ g_message ("Type %s has no tk constant!",
+ IDL_tree_type_names[IDL_NODE_TYPE (node)]);
+ }
+}
+
+static void
+forb_output_tcstruct_name (FILE *fh, IDL_tree node, int array_gen_ctr)
+{
+ switch (IDL_NODE_TYPE (node)) {
+ case IDLN_TYPE_STRUCT:
+ fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_STRUCT (node).ident).str);
+ break;
+ case IDLN_TYPE_UNION:
+ fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_UNION (node).ident).str);
+ break;
+ case IDLN_TYPE_ENUM:
+ fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_ENUM (node).ident).str);
+ break;
+ case IDLN_INTERFACE:
+ case IDLN_FORWARD_DCL:
+ fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_INTERFACE (node).ident).str);
+ break;
+ case IDLN_EXCEPT_DCL:
+ fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_EXCEPT_DCL (node).ident).str);
+ break;
+ case IDLN_IDENT:
+ fprintf (fh, "(char *)\"%s\"", IDL_IDENT (node).str);
+ break;
+ case IDLN_TYPE_ARRAY:
+ if (!array_gen_ctr)
+ fprintf (fh, "(char *)\"%s\"",
+ IDL_IDENT (IDL_TYPE_ARRAY (node).ident).str);
+ else
+ fprintf (fh, "NULL");
+ break;
+ default:
+ fprintf (fh, "NULL");
+ break;
+ }
+}
+
+static void
+forb_output_tcstruct_repo_id (FILE *fh, IDL_tree node, int array_gen_ctr)
+{
+ switch (IDL_NODE_TYPE (node)) {
+ case IDLN_TYPE_STRUCT:
+ fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_STRUCT (node).ident).repo_id);
+ break;
+ case IDLN_TYPE_UNION:
+ fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_UNION (node).ident).repo_id);
+ break;
+ case IDLN_TYPE_ENUM:
+ fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_ENUM (node).ident).repo_id);
+ break;
+ case IDLN_INTERFACE:
+ case IDLN_FORWARD_DCL:
+ fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_INTERFACE (node).ident).repo_id);
+ break;
+ case IDLN_EXCEPT_DCL:
+ fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_EXCEPT_DCL (node).ident).repo_id);
+ break;
+ case IDLN_IDENT:
+ fprintf (fh, "(char *)\"%s\"", IDL_IDENT (node).repo_id);
+ break;
+ case IDLN_TYPE_ARRAY:
+ if (!array_gen_ctr)
+ fprintf (fh, "(char *)\"%s\"", IDL_IDENT (IDL_TYPE_ARRAY (node).ident).repo_id);
+ else
+ fprintf (fh, "NULL");
+ break;
+ default:
+ fprintf (fh, "NULL");
+ break;
+ }
+}
+
+static void
+forb_output_tcstruct_length (FILE *fh, IDL_tree node, int array_gen_ctr)
+{
+ int length = 0;
+
+ switch (IDL_NODE_TYPE (node)) {
+ case IDLN_TYPE_SEQUENCE:
+ if (IDL_TYPE_SEQUENCE (node).positive_int_const)
+ length = IDL_INTEGER (IDL_TYPE_SEQUENCE (node).positive_int_const).value;
+ break;
+ case IDLN_TYPE_STRING:
+ if (IDL_TYPE_STRING (node).positive_int_const)
+ length = IDL_INTEGER (IDL_TYPE_STRING (node).positive_int_const).value;
+ break;
+ case IDLN_TYPE_WIDE_STRING:
+ if (IDL_TYPE_WIDE_STRING (node).positive_int_const)
+ length = IDL_INTEGER (IDL_TYPE_STRING (node).positive_int_const).value;
+ break;
+ case IDLN_TYPE_ARRAY:
+ if (array_gen_ctr) {
+ IDL_tree sizer;
+
+ sizer = IDL_list_nth (IDL_TYPE_ARRAY (node).size_list,
+ array_gen_ctr - 1);
+
+ g_assert (IDL_NODE_TYPE (IDL_LIST (sizer).data) == IDLN_INTEGER);
+
+ length = IDL_INTEGER (IDL_LIST (sizer).data).value;
+ }
+ break;
+ default:
+ length = 0;
+ break;
+ }
+
+ fprintf (fh, "%d", length);
+}
+
+static void
+forb_output_tcstruct_sub_parts (FILE *fh, IDL_tree node)
+{
+ int length = 0;
+
+ switch (IDL_NODE_TYPE (node)) {
+ case IDLN_TYPE_STRUCT:
+ case IDLN_EXCEPT_DCL: {
+ IDL_tree l;
+
+ for (l = IDL_TYPE_STRUCT (node).member_list; l; l = IDL_LIST (l).next) {
+ IDL_tree member;
+
+ member = IDL_LIST (l).data;
+
+ g_assert (IDL_NODE_TYPE (member) == IDLN_MEMBER);
+
+ length += IDL_list_length (IDL_MEMBER (member).dcls);
+ }
+ }
+ break;
+ case IDLN_TYPE_UNION: {
+ IDL_tree l;
+
+ for (l = IDL_TYPE_UNION (node).switch_body; l; l = IDL_LIST (l).next) {
+ IDL_tree case_stmt;
+
+ case_stmt = IDL_LIST (l).data;
+
+ g_assert (IDL_NODE_TYPE (case_stmt) == IDLN_CASE_STMT);
+
+ length += IDL_list_length (IDL_CASE_STMT (case_stmt).labels);
+ }
+ }
+ break;
+ case IDLN_TYPE_ENUM:
+ length = IDL_list_length (IDL_TYPE_ENUM (node).enumerator_list);
+ break;
+ case IDLN_IDENT:
+ case IDLN_TYPE_SEQUENCE:
+ case IDLN_TYPE_ARRAY:
+ length = 1;
+ break;
+ default:
+ length = 0;
+ break;
+ }
+
+ fprintf (fh, "%d\n", length);
+}
+
+static void
+forb_output_tcstruct_subnames (FILE *fh, IDL_tree node, int subnames_id)
+{
+ switch (IDL_NODE_TYPE (node)) {
+ case IDLN_TYPE_ENUM:
+ if (IDL_TYPE_ENUM (node).enumerator_list)
+ fprintf (fh, "(char **)anon_subnames_array%d", subnames_id);
+ else
+ fprintf (fh, "NULL");
+ break;
+ case IDLN_TYPE_UNION:
+ if (IDL_TYPE_UNION (node).switch_body)
+ fprintf (fh, "(char **)anon_subnames_array%d", subnames_id);
+ else
+ fprintf (fh, "NULL");
+ break;
+ case IDLN_TYPE_STRUCT:
+ case IDLN_EXCEPT_DCL:
+ if (IDL_TYPE_STRUCT (node).member_list)
+ fprintf (fh, "(char **)anon_subnames_array%d", subnames_id);
+ else
+ fprintf (fh, "NULL");
+ break;
+ default:
+ fprintf (fh, "NULL");
+ break;
+ }
+}
+
+static void
+forb_output_tcstruct_subtypes (FILE *fh, IDL_tree node, int subtypes_id)
+{
+ switch (IDL_NODE_TYPE (node)) {
+ case IDLN_EXCEPT_DCL:
+ case IDLN_TYPE_STRUCT:
+ if (IDL_TYPE_STRUCT (node).member_list)
+ fprintf (fh, "(CORBA_TypeCode *)anon_subtypes_array%d", subtypes_id);
+ else
+ fprintf (fh, "NULL");
+ break;
+ case IDLN_TYPE_UNION:
+ if (IDL_TYPE_UNION (node).switch_body)
+ fprintf (fh, "(CORBA_TypeCode *)anon_subtypes_array%d", subtypes_id);
+ else
+ fprintf (fh, "NULL");
+ break;
+ case IDLN_TYPE_SEQUENCE:
+ case IDLN_TYPE_ARRAY:
+ case IDLN_IDENT:
+ fprintf (fh, "(CORBA_TypeCode *)anon_subtypes_array%d", subtypes_id);
+ break;
+ default:
+ fprintf (fh, "NULL");
+ break;
+ }
+}
+
+static void
+forb_output_tcstruct_sublabels (FILE *fh, IDL_tree node, int sublabels_id)
+{
+ switch (IDL_NODE_TYPE (node)) {
+ case IDLN_TYPE_UNION:
+ fprintf (fh, "(CORBA_long *)anon_sublabels_array%d", sublabels_id);
+ break;
+ default:
+ fprintf (fh, "NULL");
+ break;
+ }
+}
+
+static void
+forb_output_tcstruct_discriminator (FILE *fh, IDL_tree node)
+{
+ switch (IDL_NODE_TYPE (node)) {
+ case IDLN_TYPE_UNION: {
+ char *switch_type_spec_str;
+
+ switch_type_spec_str =
+ forb_cbe_get_typespec_str (IDL_TYPE_UNION (node).switch_type_spec);
+
+ fprintf (fh, "(CORBA_TypeCode)&TC_%s_struct", switch_type_spec_str);
+
+ g_free (switch_type_spec_str);
+ }
+ break;
+ default:
+ fprintf (fh, "CORBA_OBJECT_NIL");
+ break;
+ }
+}
+
+static void
+forb_output_tcstruct_recurse_depth (FILE *fh)
+{
+ fprintf (fh, "0");
+}
+
+static void
+forb_output_tcstruct_default_index (FILE *fh, int union_default_index)
+{
+ fprintf (fh, "%d", union_default_index);
+}
+
+static void
+forb_output_tcstruct_digits_scale (FILE *fh, IDL_tree node)
+{
+ if (IDL_NODE_TYPE (node) == IDLN_TYPE_FIXED) {
+ fprintf (fh, "%" PRId64 ", %" PRId64 ,
+ IDL_INTEGER (IDL_TYPE_FIXED (node).positive_int_const).value,
+ IDL_INTEGER (IDL_TYPE_FIXED (node).integer_lit).value);
+ }
+ else
+ fprintf (fh, "0, 0");
+}
+
+static void
+forb_add_align (GSList **max, const char *str)
+{
+ GSList *l;
+
+ for (l = *max; l; l = l->next) {
+ if (!strcmp (l->data, str))
+ return;
+ }
+ *max = g_slist_prepend (*max, (gpointer) str);
+}
+
+static GSList *
+forb_find_c_align (GSList *max, IDL_tree node)
+{
+ node = forb_cbe_get_typespec (node);
+
+ switch (IDL_NODE_TYPE (node)) {
+ case IDLN_TYPE_INTEGER:
+ switch (IDL_TYPE_INTEGER (node).f_type) {
+ case IDL_INTEGER_TYPE_SHORT:
+ forb_add_align (&max, "FORB_ALIGNOF_CORBA_SHORT");
+ break;
+ case IDL_INTEGER_TYPE_LONG:
+ forb_add_align (&max, "FORB_ALIGNOF_CORBA_LONG");
+ break;
+ case IDL_INTEGER_TYPE_LONGLONG:
+ forb_add_align (&max, "FORB_ALIGNOF_CORBA_LONG_LONG");
+ break;
+ }
+ break;
+ case IDLN_TYPE_FLOAT:
+ switch (IDL_TYPE_FLOAT (node).f_type) {
+ case IDL_FLOAT_TYPE_FLOAT:
+ forb_add_align (&max, "FORB_ALIGNOF_CORBA_FLOAT");
+ break;
+ case IDL_FLOAT_TYPE_DOUBLE:
+ forb_add_align (&max, "FORB_ALIGNOF_CORBA_DOUBLE");
+ break;
+ case IDL_FLOAT_TYPE_LONGDOUBLE:
+ forb_add_align (&max, "FORB_ALIGNOF_CORBA_LONG_DOUBLE");
+ break;
+ }
+ break;
+ case IDLN_TYPE_ENUM:
+ forb_add_align (&max, "FORB_ALIGNOF_CORBA_LONG");
+ break;
+ case IDLN_TYPE_CHAR: /* drop through */
+ case IDLN_TYPE_BOOLEAN:
+ case IDLN_TYPE_OCTET:
+ forb_add_align (&max, "FORB_ALIGNOF_CORBA_CHAR");
+ break;
+ case IDLN_TYPE_WIDE_CHAR:
+ forb_add_align (&max, "FORB_ALIGNOF_CORBA_SHORT");
+ break;
+ case IDLN_TYPE_UNION: {
+ IDL_tree l = IDL_TYPE_UNION (node).switch_body;
+
+ forb_add_align (&max, "FORB_ALIGNOF_CORBA_STRUCT");
+
+ for (; l; l = IDL_LIST (l).next) {
+ IDL_tree subtype = IDL_MEMBER (IDL_CASE_STMT (
+ IDL_LIST (l).data).element_spec).type_spec;
+ max = forb_find_c_align (max, subtype);
+ }
+ break;
+ }
+ case IDLN_EXCEPT_DCL: /* drop through */
+ case IDLN_TYPE_STRUCT: {
+ IDL_tree l = IDL_TYPE_STRUCT (node).member_list;
+
+ for (; l; l = IDL_LIST (l).next) {
+ IDL_tree member = IDL_MEMBER (IDL_LIST (l).data).type_spec;
+
+ max = forb_find_c_align (max, member);
+ }
+ break;
+ }
+ case IDLN_TYPE_STRING: /* drop through */
+ case IDLN_TYPE_WIDE_STRING:
+ case IDLN_TYPE_OBJECT:
+ case IDLN_TYPE_TYPECODE:
+ case IDLN_FORWARD_DCL:
+ case IDLN_INTERFACE:
+ forb_add_align (&max, "FORB_ALIGNOF_CORBA_POINTER");
+ break;
+ case IDLN_TYPE_ARRAY: {
+ IDL_tree subtype = IDL_TYPE_DCL (
+ IDL_get_parent_node (node, IDLN_TYPE_DCL, NULL)).type_spec;
+ max = forb_find_c_align (max, subtype);
+ break;
+ }
+ case IDLN_TYPE_SEQUENCE:
+ forb_add_align (&max, "FORB_ALIGNOF_CORBA_STRUCT");
+ forb_add_align (&max, "FORB_ALIGNOF_CORBA_LONG");
+ forb_add_align (&max, "FORB_ALIGNOF_CORBA_POINTER");
+ break;
+ case IDLN_TYPE_ANY:
+ forb_add_align (&max, "FORB_ALIGNOF_CORBA_STRUCT");
+ forb_add_align (&max, "FORB_ALIGNOF_CORBA_POINTER");
+ break;
+ default:
+ g_error ("Can't find alignment %s\n",
+ IDL_tree_type_names[IDL_NODE_TYPE (node)]);
+ break;
+ }
+
+ return max;
+}
+
+static void
+forb_output_tcstruct_c_align (FILE *fh, IDL_tree node)
+{
+ GSList *max;
+ GString *str = g_string_sized_new (120);
+
+ max = forb_find_c_align (NULL, node);
+
+ if (!max)
+ g_string_append (str, "1");
+
+ else if (!max->next)
+ g_string_append (str, max->data);
+
+ else {
+ int i = 0;
+ GSList *l;
+
+ for (l = max; l; l = l->next) {
+ g_string_append (str, "MAX (");
+ g_string_append (str, l->data);
+ g_string_append (str, ", ");
+ i++;
+ }
+
+ g_string_append (str, "1");
+ for (; i > 0; i--)
+ g_string_append_c (str, ')');
+ }
+
+ fprintf (fh, "%s", str->str);
+
+ g_string_free (str, TRUE);
+}
+
+static void
+cbe_tc_generate (OIDL_C_Info *ci,
+ CBETCGenInfo *tci)
+{
+ CBETCGenInfo subtci;
+ IDL_tree curitem;
+ char *ctmp;
+ int union_default_index = -1,
+ subnames_id = random_id++,
+ subtypes_id = random_id++,
+ sublabels_id = random_id++;
+
+ if (strncmp (tci->structname, "anon", 4)) {
+ fprintf (ci->fh, "#if ");
+ forb_cbe_id_cond_hack (ci->fh, "TC_IMPL",
+ tci->structname, ci->c_base_name);
+ fprintf (ci->fh, " && !defined(TC_DEF_%s)\n", tci->structname);
+ fprintf (ci->fh, "#define TC_DEF_%s 1\n", tci->structname);
+ }
+
+ if (IDL_NODE_TYPE (tci->ts) == IDLN_TYPE_DCL) {
+ subtci = *tci;
+
+ curitem = IDL_TYPE_DCL (tci->ts).type_spec;
+ subtci.substructname = ctmp = forb_generate_tcstruct_name (curitem);
+
+ /*
+ * The only type not already defined elsewhere
+ * that can be in the left half of a TypeCode.
+ */
+ if (IDL_NODE_TYPE (curitem) == IDLN_TYPE_SEQUENCE) {
+ subtci.structname = ctmp;
+ subtci.ts = curitem;
+ cbe_tc_generate (ci, &subtci);
+ }
+
+ for (curitem = IDL_TYPE_DCL (tci->ts).dcls; curitem;
+ curitem = IDL_LIST (curitem).next) {
+ subtci.ts = IDL_LIST (curitem).data;
+
+ if (IDL_NODE_TYPE (subtci.ts) == IDLN_TYPE_ARRAY)
+ subtci.structname = forb_generate_tcstruct_name (
+ IDL_TYPE_ARRAY (subtci.ts).ident);
+ else
+ subtci.structname = forb_generate_tcstruct_name (subtci.ts);
+
+ cbe_tc_generate (ci, &subtci);
+ g_free (subtci.structname);
+ }
+
+ g_free (ctmp);
+ return;
+ }
+
+ /* Do magic here - nesting of typecodes for arrays */
+ if (IDL_NODE_TYPE (tci->ts) == IDLN_TYPE_ARRAY &&
+ (IDL_list_length (IDL_TYPE_ARRAY (tci->ts).size_list) > tci->array_gen_ctr)) {
+
+ curitem = IDL_list_nth (IDL_TYPE_ARRAY (tci->ts).size_list,
+ tci->array_gen_ctr - 1);
+
+ subtci = *tci;
+ subtci.structname = ctmp = forb_generate_tcstruct_name (curitem);
+ subtci.array_gen_ctr++;
+
+ cbe_tc_generate (ci, &subtci);
+
+ tci->substructname = ctmp; /* FIXME: memory leak */
+ }
+
+ forb_output_tcstruct_anon_subnames_array (ci->fh, tci->ts, subnames_id);
+ forb_output_tcstruct_anon_subtypes_array (ci->fh, tci->ts, subtypes_id,
+ tci->substructname);
+
+ union_default_index = forb_output_tcstruct_anon_sublabels_array (
+ ci->fh, tci->ts, sublabels_id);
+
+ if (!strncmp (tci->structname, "anon", 4))
+ fprintf (ci->fh, "static ");
+ else {
+ fprintf (ci->fh, "#ifdef FORB_IDL_C_IMODULE_%s\n",
+ ci->c_base_name);
+ fprintf (ci->fh, "static\n");
+ fprintf (ci->fh, "#endif\n");
+ }
+
+ fprintf (ci->fh, "FORB2_MAYBE_CONST struct CORBA_TypeCode_struct %s_struct = {\n",
+ tci->structname);
+
+ forb_output_tcstruct_parent (ci->fh);
+
+ fprintf (ci->fh, ",\n");
+
+ forb_output_tcstruct_kind (ci->fh, tci->ts, tci->array_gen_ctr);
+
+ fprintf (ci->fh, ",\n");
+
+ /* flags */
+ fprintf (ci->fh, "0,\n");
+
+ /* c_length */
+ fprintf (ci->fh, "0,\n");
+
+ forb_output_tcstruct_c_align (ci->fh, tci->ts);
+
+ fprintf (ci->fh, ",\n");
+
+ forb_output_tcstruct_length (ci->fh, tci->ts, tci->array_gen_ctr);
+
+ fprintf (ci->fh, ",\n");
+
+ forb_output_tcstruct_sub_parts (ci->fh, tci->ts);
+
+ fprintf (ci->fh, ",\n");
+
+ forb_output_tcstruct_subtypes (ci->fh, tci->ts, subtypes_id);
+
+ fprintf (ci->fh, ",\n");
+
+ forb_output_tcstruct_discriminator (ci->fh, tci->ts);
+
+ fprintf (ci->fh, ",\n");
+
+ forb_output_tcstruct_name (ci->fh, tci->ts, tci->array_gen_ctr);
+
+ fprintf (ci->fh, ",\n");
+
+ forb_output_tcstruct_repo_id (ci->fh, tci->ts, tci->array_gen_ctr);
+
+ fprintf (ci->fh, ",\n");
+
+ forb_output_tcstruct_subnames (ci->fh, tci->ts, subnames_id);
+
+ fprintf (ci->fh, ",\n");
+
+ forb_output_tcstruct_sublabels (ci->fh, tci->ts, sublabels_id);
+
+ fprintf (ci->fh, ",\n");
+
+ forb_output_tcstruct_default_index (ci->fh, union_default_index);
+
+ fprintf (ci->fh, ",\n");
+
+ forb_output_tcstruct_recurse_depth (ci->fh);
+
+ fprintf (ci->fh, ",\n");
+
+ forb_output_tcstruct_digits_scale (ci->fh, tci->ts);
+
+ fprintf (ci->fh, "\n};\n");
+
+ if (strncmp (tci->structname, "anon", 4))
+ fprintf (ci->fh, "#endif\n");
+}
--- /dev/null
+#include "config.h"
+
+#include "forb-idl-c-backend.h"
+
+#include <string.h>
+#include <inttypes.h>
+
+/**
+ *
+ *
+ * @param of
+ * @param ts Type spec.
+ * @param name decl
+ * @param use_name use identifier from name
+ * @param var_prefix prefix for identifier taken from name
+ * @param serialization
+ */
+void
+forb_cbe_write_ser_var(FILE *of, IDL_tree ts, IDL_tree name,
+ bool use_name,
+ char *var_prefix,
+ enum forb_ser serialization)
+{
+ int indent = 0, i;
+ GString *id = g_string_new("");
+ char *serialize = (serialization == SERIALIZE) ? "serialize" : "deserialize";
+ gboolean use_ampersand = TRUE;
+
+ switch(IDL_NODE_TYPE(name)) {
+ case IDLN_IDENT:
+ fprintf(of, " ");
+ if (use_name)
+ g_string_assign(id, IDL_IDENT(name).str);
+
+ if (IDL_NODE_TYPE(forb_cbe_get_typespec(ts)) == IDLN_TYPE_ARRAY)
+ use_ampersand = FALSE;
+
+/* printf("%s%s:\n", var_prefix, use_name ? id->str:""); */
+/* forb_idl_print_node(forb_cbe_get_typespec(ts), 2); */
+
+ break;
+ case IDLN_TYPE_ARRAY:
+ {
+ IDL_tree curitem;
+ char var;
+ if (use_name)
+ g_string_assign(id, IDL_IDENT(IDL_TYPE_ARRAY(name).ident).str);
+
+ var = 'i';
+ fprintf(of, " {\n CORBA_unsigned_long ");
+ for(curitem = IDL_TYPE_ARRAY(name).size_list; curitem; curitem = IDL_LIST(curitem).next) {
+ fprintf(of, "%c", var);
+ if (IDL_LIST(curitem).next)
+ fprintf(of, ", ");
+ g_string_append_printf(id, "[%c]", var);
+ var++;
+ }
+ fprintf(of, ";\n");
+
+ var = 'i';
+ for(curitem = IDL_TYPE_ARRAY(name).size_list; curitem; curitem = IDL_LIST(curitem).next) {
+ indent++;
+ for (i=0; i<indent+1; i++)
+ fprintf(of, " ");
+ fprintf(of, "for (%c=0; %c<%" PRId64 "; %c++) \n",
+ var, var, IDL_INTEGER(IDL_LIST(curitem).data).value, var);
+ var++;
+ }
+
+
+ for (i=0; i<indent+2; i++)
+ fprintf(of, " ");
+
+ }
+ break;
+ default:
+ g_error("Weird varname - %s", IDL_tree_type_names[IDL_NODE_TYPE(name)]);
+ break;
+ }
+ fprintf(of, "if (!");
+ forb_cbe_write_typespec(of, ts);
+ fprintf(of, "_%s(codec, %s%s%s)) goto ser_exception;\n",
+ serialize, use_ampersand ? "&":"", var_prefix, id->str);
+ if (indent)
+ fprintf(of, " }\n");
+
+ g_string_free(id, TRUE);
+}
+
+
+char *
+forb_cbe_get_typecode_name (IDL_tree tree)
+{
+ if (!tree)
+ return g_strdup ("TC_FIXME");
+ else
+ return g_strconcat ("TC_", forb_cbe_get_typespec_str (tree), NULL);
+}
+
+gboolean
+forb_cbe_type_is_builtin(IDL_tree tree)
+{
+/* return FALSE; */
+ switch(IDL_NODE_TYPE(tree)) {
+ case IDLN_LIST:
+ case IDLN_GENTREE:
+ case IDLN_MEMBER:
+ case IDLN_CASE_STMT:
+ case IDLN_MODULE:
+ case IDLN_BINOP:
+ case IDLN_UNARYOP:
+ case IDLN_CODEFRAG:
+ g_error("Strange type for being a builtin");
+ break;
+ case IDLN_INTEGER:
+ case IDLN_STRING:
+ case IDLN_WIDE_STRING:
+ case IDLN_CHAR:
+ case IDLN_WIDE_CHAR:
+ case IDLN_FIXED:
+ case IDLN_FLOAT:
+ case IDLN_BOOLEAN:
+ case IDLN_CONST_DCL:
+ case IDLN_TYPE_INTEGER:
+ case IDLN_TYPE_FLOAT:
+ case IDLN_TYPE_CHAR:
+ case IDLN_TYPE_WIDE_CHAR:
+ case IDLN_TYPE_STRING:
+ case IDLN_TYPE_WIDE_STRING:
+ case IDLN_TYPE_BOOLEAN:
+ case IDLN_TYPE_OCTET:
+ case IDLN_TYPE_ANY:
+ case IDLN_TYPE_OBJECT:
+ case IDLN_TYPE_TYPECODE:
+ case IDLN_TYPE_ENUM:
+ case IDLN_TYPE_SEQUENCE:
+ return TRUE;
+ break;
+ case IDLN_TYPE_DCL:
+ case IDLN_EXCEPT_DCL:
+ case IDLN_ATTR_DCL:
+ case IDLN_OP_DCL:
+ case IDLN_PARAM_DCL:
+ case IDLN_TYPE_FIXED:
+ case IDLN_TYPE_ARRAY:
+ case IDLN_TYPE_STRUCT:
+ case IDLN_TYPE_UNION:
+ case IDLN_IDENT:
+ case IDLN_INTERFACE:
+ case IDLN_FORWARD_DCL:
+ case IDLN_NATIVE:
+ default:
+ return FALSE;
+ break;
+ }
+
+ return FALSE;
+}
+
+/**
+ Gets the "type" of {tree} as known in C.
+ The return value was alloc'd via g_malloc, and must be g_free'd.
+**/
+char *
+forb_cbe_get_typespec_str(IDL_tree tree)
+{
+ char *retval = NULL;
+ GString *tmpstr = NULL;
+
+ if(!tree) {
+ return g_strdup("void");
+ }
+
+ switch(IDL_NODE_TYPE(tree)) {
+ case IDLN_MEMBER:
+ return forb_cbe_get_typespec_str(IDL_MEMBER(tree).type_spec);
+ break;
+ case IDLN_TYPE_ANY:
+ retval = "CORBA_any";
+ break;
+ case IDLN_TYPE_FLOAT:
+ switch(IDL_TYPE_FLOAT(tree).f_type) {
+ case IDL_FLOAT_TYPE_FLOAT:
+ retval = "CORBA_float";
+ break;
+ case IDL_FLOAT_TYPE_DOUBLE:
+ retval = "CORBA_double";
+ break;
+ case IDL_FLOAT_TYPE_LONGDOUBLE:
+ retval = "CORBA_long_double";
+ break;
+ }
+ break;
+ case IDLN_TYPE_FIXED:
+ return g_strdup_printf( "CORBA_fixed_%" PRId64 "_%" PRId64 "",
+ IDL_INTEGER(IDL_TYPE_FIXED(tree).positive_int_const).value,
+ IDL_INTEGER(IDL_TYPE_FIXED(tree).integer_lit).value);
+ break;
+ case IDLN_TYPE_INTEGER:
+ tmpstr = g_string_new(NULL);
+ g_string_append(tmpstr, "CORBA_");
+ if(!IDL_TYPE_INTEGER(tree).f_signed)
+ g_string_append(tmpstr, "unsigned_");
+
+ switch(IDL_TYPE_INTEGER(tree).f_type) {
+ case IDL_INTEGER_TYPE_SHORT:
+ g_string_append(tmpstr, "short");
+ break;
+ case IDL_INTEGER_TYPE_LONGLONG:
+ g_string_append(tmpstr, "long_");
+ /* FALLTHROUGH */
+ case IDL_INTEGER_TYPE_LONG:
+ g_string_append(tmpstr, "long");
+ break;
+ }
+ break;
+ case IDLN_TYPE_STRING:
+ retval = "CORBA_string"; /* this is non-standard! */
+ break;
+ case IDLN_TYPE_OCTET:
+ retval = "CORBA_octet";
+ break;
+ case IDLN_TYPE_WIDE_STRING:
+ retval = "CORBA_wstring"; /* this is non-standard! */
+ break;
+ case IDLN_TYPE_CHAR:
+ retval = "CORBA_char";
+ break;
+ case IDLN_TYPE_WIDE_CHAR:
+ retval = "CORBA_wchar";
+ break;
+ case IDLN_TYPE_BOOLEAN:
+ retval = "CORBA_boolean";
+ break;
+ case IDLN_TYPE_STRUCT:
+ return forb_cbe_get_typespec_str(IDL_TYPE_STRUCT(tree).ident);
+ case IDLN_EXCEPT_DCL:
+ return forb_cbe_get_typespec_str(IDL_EXCEPT_DCL(tree).ident);
+ case IDLN_TYPE_ARRAY:
+ return forb_cbe_get_typespec_str(IDL_TYPE_ARRAY(tree).ident);
+ case IDLN_TYPE_UNION:
+ return forb_cbe_get_typespec_str(IDL_TYPE_UNION(tree).ident);
+ case IDLN_TYPE_ENUM:
+ return forb_cbe_get_typespec_str(IDL_TYPE_ENUM(tree).ident);
+ case IDLN_IDENT:
+ return IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(tree), "_", 0);
+ case IDLN_PARAM_DCL:
+ return forb_cbe_get_typespec_str(IDL_PARAM_DCL(tree).param_type_spec);
+ case IDLN_TYPE_SEQUENCE:
+ {
+ IDL_tree subtype = IDL_TYPE_SEQUENCE(tree).simple_type_spec;
+ char *ctmp, *base;
+ ctmp = forb_cbe_get_typespec_str(subtype);
+ /* We should have built-in alias to make this next line not needed */
+ base = forb_cbe_type_is_builtin(subtype)
+ ? ctmp + strlen("CORBA_") : ctmp;
+ retval = g_strdup_printf( "CORBA_sequence_%s", base);
+ g_free(ctmp);
+ return retval;
+ }
+ break;
+ case IDLN_NATIVE:
+ retval = forb_cbe_get_typespec_str(IDL_NATIVE(tree).ident);
+ break;
+ case IDLN_FORWARD_DCL:
+ case IDLN_INTERFACE:
+ return forb_cbe_get_typespec_str(IDL_INTERFACE(tree).ident);
+ case IDLN_TYPE_OBJECT:
+ retval = "CORBA_Object";
+ break;
+ case IDLN_TYPE_TYPECODE:
+ retval = "CORBA_TypeCode";
+ break;
+ default:
+ g_error("We were asked to get a typename for a %s",
+ IDL_tree_type_names[IDL_NODE_TYPE(tree)]);
+ break;
+ }
+
+ if (retval)
+ return g_strdup (retval);
+ else
+ return g_string_free (tmpstr, FALSE);
+}
+
+void
+forb_cbe_write_typespec(FILE *of, IDL_tree tree)
+{
+ char *name = forb_cbe_get_typespec_str(tree);
+ fprintf( of, name);
+ g_free(name);
+}
+
+/**
+ Parameters (e.g., arguments to methods, and the return value
+ have some complicated rules in the C mapping for how many
+ levels of pointer and the exact type involved. This function
+ generates the externally visible parameter type.
+
+ Note the hack below because "const CORBA_string" is not
+ promotable to "const CORBA_char*" (the later the standard
+ to which apps are written, while the former is what would
+ be produced without the hack).
+**/
+static char *
+forb_cbe_write_param_typespec_str(IDL_tree ts, IDL_ParamRole role)
+{
+ int i, n;
+ gboolean isSlice;
+ char *name;
+ GString *str = g_string_sized_new (23);
+ IDL_tree typedef_spec;
+ char *typedef_name;
+
+ n = oidl_param_info (ts, role, &isSlice);
+ name = forb_cbe_get_typespec_str (ts);
+
+ if ( role == DATA_IN ) {
+ /* We want to check if this is a typedef for CORBA_string so we can do special handling
+ * in that case.
+ */
+ typedef_spec = forb_cbe_get_typespec (ts);
+ typedef_name = forb_cbe_get_typespec_str (typedef_spec);
+
+ g_string_printf (str, "const %s",
+ !strcmp (typedef_name, "CORBA_string") ?
+ "CORBA_char *" : name);
+
+ g_free (typedef_name);
+ } else
+ g_string_printf (str, "%s", name);
+
+ g_free (name);
+
+ if ( isSlice )
+ g_string_append (str, "_slice");
+
+ for (i = 0; i < n; i++)
+ g_string_append_c (str, '*');
+
+ return g_string_free (str, FALSE);
+}
+
+static void
+forb_cbe_write_param_typespec_raw (FILE *of, IDL_tree ts, IDL_ParamRole role)
+{
+ char *str;
+ str = forb_cbe_write_param_typespec_str (ts, role);
+ fprintf (of, str);
+ g_free (str);
+}
+
+void
+forb_cbe_write_param_typespec(FILE *of, IDL_tree tree) {
+ IDL_tree ts = NULL /* Quiet gcc */;
+ IDL_ParamRole role = 0 /* Quiet gcc */;
+
+ switch ( IDL_NODE_TYPE(tree) ) {
+ case IDLN_OP_DCL: /* means return value of method */
+ ts = IDL_OP_DCL(tree).op_type_spec;
+ role = DATA_RETURN;
+ break;
+ case IDLN_PARAM_DCL: /* one of the parameters */
+ ts = IDL_PARAM_DCL(tree).param_type_spec;
+ role = oidl_attr_to_paramrole(IDL_PARAM_DCL(tree).attr);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ forb_cbe_write_param_typespec_raw(of, ts, role);
+}
+
+void
+forb_cbe_op_write_proto (FILE *of,
+ IDL_tree op,
+ const char *nom_prefix,
+ gboolean for_epv)
+{
+ IDL_tree sub;
+ char *id;
+
+ g_assert (IDL_NODE_TYPE(op) == IDLN_OP_DCL);
+
+ forb_cbe_write_param_typespec (of, op);
+
+ id = IDL_ns_ident_to_qstring (
+ IDL_IDENT_TO_NS (IDL_INTERFACE (
+ IDL_get_parent_node (op, IDLN_INTERFACE, NULL)).ident), "_", 0);
+
+ if (for_epv)
+ fprintf (of, "\t(*%s%s)", nom_prefix ? nom_prefix : "",
+ IDL_IDENT(IDL_OP_DCL(op).ident).str);
+ else
+ fprintf (of, " %s%s_%s", nom_prefix ? nom_prefix : "",
+ id, IDL_IDENT (IDL_OP_DCL (op).ident).str);
+
+ fprintf (of, "(");
+
+/* if (for_epv) */
+/* fprintf (of, "PortableServer_Servant _servant, "); */
+/* else */
+ fprintf (of, "%s _obj, ", id);
+
+ g_free (id);
+
+ for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+ IDL_tree parm = IDL_LIST (sub).data;
+
+ forb_cbe_write_param_typespec (of, parm);
+
+ fprintf (of, " %s, ", IDL_IDENT (IDL_PARAM_DCL (parm).simple_declarator).str);
+ }
+
+ if (IDL_OP_DCL (op).context_expr)
+ fprintf (of, "CORBA_Context _ctx, ");
+
+ fprintf (of, "CORBA_Environment *ev)");
+}
+
+/* Writes the value of the constant in 'tree' to file handle 'of' */
+static char *
+forb_cbe_get_const(IDL_tree tree)
+{
+ char *opc = NULL, *retval, *ctmp;
+ GString *tmpstr = g_string_new(NULL);
+
+ switch(IDL_NODE_TYPE(tree)) {
+ case IDLN_BOOLEAN:
+ g_string_printf(tmpstr, "%s", IDL_BOOLEAN(tree).value?"CORBA_TRUE":"CORBA_FALSE");
+ break;
+ case IDLN_CHAR:
+ g_string_printf(tmpstr, "'\\x%X'", *(unsigned char *)IDL_CHAR(tree).value);
+ break;
+ case IDLN_FLOAT:
+ g_string_printf(tmpstr, "%f", IDL_FLOAT(tree).value);
+ break;
+ case IDLN_INTEGER:
+ g_string_printf(tmpstr, "%" PRId64 "", IDL_INTEGER(tree).value);
+ break;
+ case IDLN_STRING:
+ g_string_printf(tmpstr, "\"%s\"", IDL_STRING(tree).value);
+ break;
+ case IDLN_WIDE_CHAR:
+ g_string_printf(tmpstr, "L'%ls'", IDL_WIDE_CHAR(tree).value);
+ break;
+ case IDLN_WIDE_STRING:
+ g_string_printf(tmpstr, "L\"%ls\"", IDL_WIDE_STRING(tree).value);
+ break;
+ case IDLN_BINOP:
+ g_string_printf(tmpstr, "(");
+ ctmp = forb_cbe_get_const(IDL_BINOP(tree).left);
+ g_string_append(tmpstr, ctmp);
+ g_free(ctmp);
+ switch(IDL_BINOP(tree).op) {
+ case IDL_BINOP_OR:
+ opc = "|";
+ break;
+ case IDL_BINOP_XOR:
+ opc = "^";
+ break;
+ case IDL_BINOP_AND:
+ opc = "&";
+ break;
+ case IDL_BINOP_SHR:
+ opc = ">>";
+ break;
+ case IDL_BINOP_SHL:
+ opc = "<<";
+ break;
+ case IDL_BINOP_ADD:
+ opc = "+";
+ break;
+ case IDL_BINOP_SUB:
+ opc = "-";
+ break;
+ case IDL_BINOP_MULT:
+ opc = "*";
+ break;
+ case IDL_BINOP_DIV:
+ opc = "/";
+ break;
+ case IDL_BINOP_MOD:
+ opc = "%";
+ break;
+ }
+ g_string_append_printf(tmpstr, " %s ", opc);
+ ctmp = forb_cbe_get_const(IDL_BINOP(tree).right);
+ g_string_append_printf(tmpstr, "%s)", ctmp);
+ g_free(ctmp);
+ break;
+ case IDLN_UNARYOP:
+ switch(IDL_UNARYOP(tree).op) {
+ case IDL_UNARYOP_PLUS: opc = "+"; break;
+ case IDL_UNARYOP_MINUS: opc = "-"; break;
+ case IDL_UNARYOP_COMPLEMENT: opc = "~"; break;
+ }
+ ctmp = forb_cbe_get_const(IDL_UNARYOP(tree).operand);
+ g_string_printf(tmpstr, "%s%s", opc, ctmp);
+ g_free(ctmp);
+ break;
+ case IDLN_IDENT:
+ {
+ char *id;
+ id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(tree), "_", 0);
+ g_string_printf(tmpstr, "%s", id);
+ g_free(id);
+ }
+ break;
+ default:
+ g_error("We were asked to print a constant for %s", IDL_tree_type_names[tree->_type]);
+ break;
+ }
+
+ retval = tmpstr->str;
+
+ g_string_free(tmpstr, FALSE);
+
+ return retval;
+}
+
+void
+forb_cbe_write_const(FILE *of, IDL_tree tree)
+{
+ char *ctmp;
+
+ ctmp = forb_cbe_get_const(tree);
+ fprintf(of, "%s", ctmp);
+ g_free(ctmp);
+}
+
+/* This is the WORST HACK in the WORLD, really truly, but the C preprocessor doesn't allow us to use
+ strings, so we have to work around it by using individual characters. */
+void
+forb_cbe_id_define_hack(FILE *fh, const char *def_prefix, const char *def_name, const char *def_value)
+{
+ int i, n;
+ n = strlen(def_value);
+ for(i = 0; i < n; i++)
+ fprintf(fh, "#define %s_%s_%d '%c'\n", def_prefix, def_name, i, def_value[i]);
+}
+
+void
+forb_cbe_id_cond_hack(FILE *fh, const char *def_prefix, const char *def_name, const char *def_value)
+{
+ int i, n;
+ n = strlen(def_value);
+ if(n <= 0)
+ return;
+
+ fprintf(fh, "(");
+
+ for(i = 0; i < n; i++)
+ fprintf(fh, "%s (%s_%s_%d == '%c') \\\n", i?"&&":"", def_prefix, def_name, i, def_value[i]);
+ fprintf(fh, ")");
+}
+
+#define BASE_TYPES \
+ IDLN_TYPE_INTEGER: \
+ case IDLN_TYPE_FLOAT: \
+ case IDLN_TYPE_ENUM: \
+ case IDLN_TYPE_BOOLEAN: \
+ case IDLN_TYPE_CHAR: \
+ case IDLN_TYPE_WIDE_CHAR: \
+ case IDLN_TYPE_OCTET
+
+#define STRING_TYPES \
+ IDLN_TYPE_STRING: \
+ case IDLN_TYPE_WIDE_STRING
+
+#define OBJREF_TYPES \
+ IDLN_TYPE_OBJECT: \
+ case IDLN_INTERFACE: \
+ case IDLN_FORWARD_DCL
+
+static const char *
+forb_cbe_flatten_ref (IDL_ParamRole role, IDL_tree typespec)
+{
+ gboolean is_fixed;
+
+ is_fixed = forb_cbe_type_is_fixed_length (typespec);
+
+ switch (role) {
+ case DATA_IN:
+ switch (IDL_NODE_TYPE (typespec)) {
+ case BASE_TYPES:
+ case STRING_TYPES:
+ case OBJREF_TYPES:
+ case IDLN_TYPE_TYPECODE:
+ case IDLN_NATIVE:
+ return "(gpointer)&";
+
+ case IDLN_TYPE_STRUCT:
+ case IDLN_TYPE_UNION:
+ case IDLN_TYPE_ANY:
+ case IDLN_TYPE_SEQUENCE:
+ case IDLN_TYPE_ARRAY:
+ return "(gpointer)";
+
+ default:
+ case IDLN_TYPE_FIXED:
+ g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
+ };
+ return NULL;
+
+ case DATA_INOUT:
+ switch (IDL_NODE_TYPE (typespec)) {
+ case BASE_TYPES:
+ case STRING_TYPES:
+ case OBJREF_TYPES:
+ case IDLN_TYPE_TYPECODE:
+ case IDLN_TYPE_STRUCT:
+ case IDLN_TYPE_UNION:
+ case IDLN_TYPE_ARRAY:
+ case IDLN_NATIVE:
+ case IDLN_TYPE_ANY:
+ case IDLN_TYPE_SEQUENCE:
+ return "";
+
+ default:
+ case IDLN_TYPE_FIXED:
+ g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
+ };
+ return NULL;
+
+ case DATA_OUT:
+ switch (IDL_NODE_TYPE (typespec)) {
+ case BASE_TYPES:
+ case STRING_TYPES:
+ case OBJREF_TYPES:
+ case IDLN_TYPE_TYPECODE:
+ case IDLN_NATIVE:
+ return "&";
+
+ case IDLN_TYPE_STRUCT:
+ case IDLN_TYPE_UNION:
+ case IDLN_TYPE_ARRAY:
+ if (is_fixed)
+ return "&";
+ else /* drop through */
+
+ case IDLN_TYPE_SEQUENCE:
+ case IDLN_TYPE_ANY:
+ return "";
+
+ default:
+ case IDLN_TYPE_FIXED:
+ g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
+ };
+ return NULL;
+
+ case DATA_RETURN:
+ g_error ("No data return handler");
+ return NULL;
+ }
+
+ return NULL;
+}
+
+void
+forb_cbe_flatten_args (IDL_tree tree, FILE *of, const char *name)
+{
+ int i = 0;
+ IDL_tree l;
+
+ for (l = IDL_OP_DCL(tree).parameter_dcls; l;
+ l = IDL_LIST(l).next)
+ i++;
+
+ fprintf (of, "gpointer %s[%d];\n", name, i);
+
+ i = 0;
+ for (l = IDL_OP_DCL(tree).parameter_dcls; l;
+ l = IDL_LIST(l).next) {
+ IDL_tree decl = IDL_LIST (l).data;
+ IDL_tree tspec = forb_cbe_get_typespec (decl);
+ IDL_ParamRole r = 0;
+
+ switch(IDL_PARAM_DCL(decl).attr) {
+ case IDL_PARAM_IN: r = DATA_IN; break;
+ case IDL_PARAM_INOUT: r = DATA_INOUT; break;
+ case IDL_PARAM_OUT: r = DATA_OUT; break;
+ default:
+ g_error("Unknown IDL_PARAM type");
+ }
+
+ fprintf (of, "%s[%d] = %s%s;\n",
+ name, i,
+ forb_cbe_flatten_ref (r, tspec),
+ IDL_IDENT (IDL_PARAM_DCL (decl).simple_declarator).str);
+ i++;
+ }
+}
+
+static char *
+forb_cbe_unflatten_ref (IDL_ParamRole role, IDL_tree typespec)
+{
+ gboolean is_fixed;
+ char *typestr;
+ char *retval;
+
+ is_fixed = forb_cbe_type_is_fixed_length (typespec);
+
+ typestr = forb_cbe_write_param_typespec_str (typespec, role);
+
+ switch (role) {
+ case DATA_IN:
+ switch (IDL_NODE_TYPE (typespec)) {
+ case BASE_TYPES:
+ case STRING_TYPES:
+ case OBJREF_TYPES:
+ case IDLN_TYPE_TYPECODE:
+ case IDLN_NATIVE:
+ retval = g_strdup_printf ("*(%s *)", typestr);
+ break;
+
+
+ case IDLN_TYPE_ARRAY:
+ retval = g_strdup_printf ("(%s_slice *)", typestr);
+ break;
+
+ case IDLN_TYPE_STRUCT:
+ case IDLN_TYPE_UNION:
+ case IDLN_TYPE_ANY:
+ case IDLN_TYPE_SEQUENCE:
+ retval = g_strdup_printf ("(%s)", typestr);
+ break;
+
+ default:
+ case IDLN_TYPE_FIXED:
+ g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
+ retval = NULL;
+ break;
+ };
+ break;
+
+ case DATA_INOUT:
+ switch (IDL_NODE_TYPE (typespec)) {
+ case IDLN_TYPE_ARRAY:
+ retval = g_strdup_printf ("(%s_slice *)", typestr);
+ break;
+
+ case BASE_TYPES:
+ case STRING_TYPES:
+ case OBJREF_TYPES:
+ case IDLN_TYPE_TYPECODE:
+ case IDLN_TYPE_STRUCT:
+ case IDLN_TYPE_UNION:
+ case IDLN_NATIVE:
+ case IDLN_TYPE_ANY:
+ case IDLN_TYPE_SEQUENCE:
+ retval = g_strdup_printf ("(%s)", typestr);
+ break;
+
+ default:
+ case IDLN_TYPE_FIXED:
+ g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
+ retval = NULL;
+ break;
+ };
+ break;
+
+ case DATA_OUT:
+ switch (IDL_NODE_TYPE (typespec)) {
+ case BASE_TYPES:
+ case STRING_TYPES:
+ case OBJREF_TYPES:
+ case IDLN_TYPE_TYPECODE:
+ case IDLN_NATIVE:
+ retval = g_strdup_printf ("*(%s *)", typestr);
+ break;
+
+ case IDLN_TYPE_ARRAY:
+ if (is_fixed) {
+ retval = g_strdup_printf ("*(%s_slice **)", typestr);
+ break;
+ }
+ /* drop through */
+
+ case IDLN_TYPE_STRUCT:
+ case IDLN_TYPE_UNION:
+ if (is_fixed) {
+ retval = g_strdup_printf ("*(%s *)", typestr);
+ break;
+ }
+ /* drop through */
+
+ case IDLN_TYPE_SEQUENCE:
+ case IDLN_TYPE_ANY:
+ retval = g_strdup_printf ("(%s)", typestr);
+ break;
+
+ default:
+ case IDLN_TYPE_FIXED:
+ g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
+ retval = NULL;
+ break;
+ };
+ break;
+
+ case DATA_RETURN:
+ default:
+ g_error ("No data return handler");
+ retval = NULL;
+ break;
+ }
+
+ g_free (typestr);
+
+ return retval;
+}
+
+void
+forb_cbe_unflatten_args (IDL_tree tree, FILE *of, const char *name)
+{
+ IDL_tree l;
+ int i = 0;
+
+ for (l = IDL_OP_DCL(tree).parameter_dcls; l;
+ l = IDL_LIST(l).next) {
+ IDL_tree decl = IDL_LIST (l).data;
+ IDL_tree tspec = forb_cbe_get_typespec (decl);
+ IDL_ParamRole r = 0;
+ char *unflatten;
+
+ switch(IDL_PARAM_DCL(decl).attr) {
+ case IDL_PARAM_IN: r = DATA_IN; break;
+ case IDL_PARAM_INOUT: r = DATA_INOUT; break;
+ case IDL_PARAM_OUT: r = DATA_OUT; break;
+ default:
+ g_error("Unknown IDL_PARAM type");
+ }
+
+ unflatten = forb_cbe_unflatten_ref (r, tspec);
+ fprintf (of, "%s%s[%d], ", unflatten, name, i++);
+ g_free (unflatten);
+ }
+}
--- /dev/null
+/**************************************************************************
+
+ forb-idl-driver.c (Dispatch parsed tree to various backends)
+
+ Copyright (C) 1999 Elliot Lee
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: forb-idl-driver.c 1302 2002-09-04 10:38:18Z mmclouglin $
+
+***************************************************************************/
+
+#include "config.h"
+
+#include "forb-idl2.h"
+#include "forb-idl-backend.h"
+#include "forb-idl-c-backend.h"
+
+#include <string.h>
+
+static void
+forb_idl_tree_fake_ops (IDL_tree tree, IDL_ns ns)
+{
+ IDL_tree node;
+
+ if (!tree)
+ return;
+
+ switch(IDL_NODE_TYPE(tree)) {
+ case IDLN_MODULE:
+ forb_idl_tree_fake_ops (IDL_MODULE (tree).definition_list, ns);
+ break;
+ case IDLN_INTERFACE:
+ forb_idl_tree_fake_ops (IDL_INTERFACE (tree).body, ns);
+ break;
+ case IDLN_LIST:
+ for (node = tree; node; node = IDL_LIST (node).next)
+ forb_idl_tree_fake_ops (IDL_LIST (node).data, ns);
+ break;
+ case IDLN_ATTR_DCL:
+ forb_idl_attr_fake_ops (tree, ns);
+ break;
+ default:
+ break;
+ }
+}
+
+gboolean
+forb_idl_to_backend (const char *filename,
+ OIDL_Run_Info *rinfo)
+{
+ IDL_ns ns;
+ IDL_tree tree;
+ int errcode;
+ gboolean retval;
+
+ errcode = IDL_parse_filename (
+ filename, rinfo->cpp_args, NULL,
+ &tree, &ns,
+ (rinfo->show_cpp_errors ? IDLF_SHOW_CPP_ERRORS : 0) |
+ (rinfo->is_pidl ? IDLF_XPIDL : 0) |
+ (rinfo->onlytop ? IDLF_INHIBIT_INCLUDES : 0) |
+ IDLF_TYPECODES |
+ IDLF_SRCFILES |
+ IDLF_CODEFRAGS,
+ rinfo->idl_warn_level);
+
+ rinfo->ns = ns;
+
+ if (rinfo->debug_level > 3)
+ forb_idl_print_node (tree, 0);
+
+ if (errcode != IDL_SUCCESS) {
+ if (errcode == -1)
+ g_warning ("Parse of %s failed: %s", filename, g_strerror (errno));
+
+ return 0;
+ }
+
+ forb_idl_tree_fake_ops (tree, ns);
+
+ if (!strcmp (rinfo->output_language, "c"))
+ retval = forb_idl_output_c (tree, rinfo);
+// else
+// retval = forb_idl_backend_output (rinfo, tree);
+
+ return retval;
+}
--- /dev/null
+/**************************************************************************
+
+ forb-idl-main.c (Driver program for the IDL parser & backend)
+
+ Copyright (C) 1999 Elliot Lee
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: forb-idl-main.c 2060 2008-05-19 21:11:07Z tml $
+
+***************************************************************************/
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <glib.h>
+#include <libIDL/IDL.h>
+#include <glib/goption.h>
+#include <glib/gi18n.h>
+#include "forb_config.h"
+
+#include "forb-idl2.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* FIXME: this program doesn't seem to support i18n? */
+#ifndef GETTEXT_PACKAGE
+#define GETTEXT_PACKAGE NULL
+#endif
+
+/* Settings made from the command line (prefaced with cl_) */
+static gboolean cl_disable_stubs = FALSE,
+ cl_disable_skels = FALSE,
+ cl_disable_common = FALSE,
+ cl_disable_headers = FALSE;
+ /* cl_enable_skeleton_impl = FALSE */
+static int cl_idlwarnlevel = 2;
+static int cl_debuglevel = 0;
+static int cl_is_pidl = 0;
+static int cl_disable_idata = 0;
+/* static int cl_enable_imodule = 0; */
+/* static int cl_add_imodule = 0; */
+static gboolean cl_disable_defs_skels = FALSE;
+static gboolean cl_showcpperrors = FALSE;
+static char *cl_output_lang = "c";
+static char *cl_include = NULL;
+static char *cl_header_guard_prefix = "";
+static char *cl_backend_dir = NULL;
+static gboolean cl_onlytop = TRUE;
+static char *cl_deps_file = NULL;
+static char *cl_output_directory = "";
+static char **idl_files = NULL;
+
+#define BASE_CPP_ARGS "-D__FORB_IDL__ "
+static GString *cl_cpp_args;
+
+/* Callbacks for goption */
+
+static gboolean
+cl_libIDL_version_callback (const char *option_name,
+ const char *value,
+ gpointer data,
+ GError **error)
+{
+ g_print("libIDL %s (CORBA %s)\n",
+ IDL_get_libver_string(),
+ IDL_get_IDLver_string());
+ exit(0);
+}
+
+static gboolean
+cl_cpp_define_callback (const char *option_name,
+ const char *value,
+ gpointer data,
+ GError **error)
+{
+ g_string_append_printf (cl_cpp_args, "-D%s ", value);
+ return TRUE;
+}
+
+static gboolean
+cl_cpp_include_callback (const char *option_name,
+ const char *value,
+ gpointer data,
+ GError **error)
+{
+ g_string_append_printf (cl_cpp_args, "-I%s ", value);
+ return TRUE;
+}
+
+static gboolean
+cl_version_callback (const char *option_name,
+ const char *value,
+ gpointer data,
+ GError **error)
+{
+ g_print ("forb-idl-2 %s - serial %d\n",
+ VERSION, FORB_CONFIG_SERIAL);
+ exit(0);
+}
+
+/* static gboolean */
+/* cl_c_output_formatter_callback (const char *option_name, */
+/* const char *value, */
+/* gpointer data, */
+/* GError **error) */
+/* { */
+/* g_warning ("Do not use the 'c-output-formatter' option. It is ignored and will soon go away."); */
+/* return TRUE; */
+/* } */
+
+static const GOptionEntry cl_libIDL_goptions[] = {
+ { "libIDL-version", 0, 0, G_OPTION_ARG_CALLBACK, cl_libIDL_version_callback, N_("Show version of libIDL used"), NULL },
+ { NULL }
+};
+
+static const GOptionEntry cl_cpp_goptions[] = {
+ { "define", 'D', G_OPTION_FLAG_FILENAME, G_OPTION_ARG_CALLBACK, cl_cpp_define_callback, N_("Define value in preprocessor"), N_("DEFINE") },
+ { "include", 'I', G_OPTION_FLAG_FILENAME, G_OPTION_ARG_CALLBACK, cl_cpp_include_callback, N_("Add search path for include files"), N_("DIR") },
+ { NULL }
+};
+
+static const GOptionEntry goptions[] = {
+ { "version", 'v', 0, G_OPTION_ARG_CALLBACK, cl_version_callback, N_("Output compiler version and serial"), NULL },
+ { "lang", 'l', 0, G_OPTION_ARG_STRING, &cl_output_lang, N_("Output language (default is C)"), N_("LANG") },
+ { "debug", 'd', 0, G_OPTION_ARG_INT, &cl_debuglevel, N_("Debug level (0 to 4)"), N_("LEVEL") },
+ { "idlwarnlevel", 0, 0, G_OPTION_ARG_INT, &cl_idlwarnlevel, N_("IDL warning level (0 to 4, default is 2)"), N_("LEVEL") },
+ { "showcpperrors", 0, 0, G_OPTION_ARG_NONE, &cl_showcpperrors, N_("Show CPP errors"), NULL },
+ { "nostubs", 0, 0, G_OPTION_ARG_NONE, &cl_disable_stubs, N_("Don't output stubs"), NULL },
+ { "noskels", 0, 0, G_OPTION_ARG_NONE, &cl_disable_skels, N_("Don't output skels"), NULL },
+ { "nocommon", 0, 0, G_OPTION_ARG_NONE, &cl_disable_common, N_("Don't output common"), NULL },
+ { "noheaders", 0, 0, G_OPTION_ARG_NONE, &cl_disable_headers, N_("Don't output headers"), NULL },
+ { "include", 0, 0, G_OPTION_ARG_STRING, &cl_include, N_("Put #include <FILE> to the generated header (for native types)"), N_("FILE") },
+/* { "noidata", 0, 0, G_OPTION_ARG_NONE, &cl_disable_idata, N_("Don't generate Interface type data"), NULL }, */
+/* { "imodule", 'i', 0, G_OPTION_ARG_NONE, &cl_enable_imodule, N_("Output only an imodule file"), NULL }, */
+/* { "add-imodule", 0, 0, G_OPTION_ARG_NONE, &cl_add_imodule, N_("Output an imodule file"), NULL }, */
+/* { "skeleton-impl", 0, 0, G_OPTION_ARG_NONE, &cl_enable_skeleton_impl, N_("Output skeleton implementation"), NULL }, */
+ { "backenddir", 0, 0, G_OPTION_ARG_FILENAME, &cl_backend_dir, N_("Override IDL backend library directory"), N_("DIR") },
+/* { "c-output-formatter", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_CALLBACK, &cl_c_output_formatter_callback, "DEPRECATED and IGNORED", "PROGRAM" }, */
+ { "onlytop", 0, 0, G_OPTION_ARG_NONE, &cl_onlytop, N_("Inhibit includes"), NULL },
+ { "pidl", 0, 0, G_OPTION_ARG_NONE, &cl_is_pidl, N_("Treat as Pseudo IDL"), NULL },
+ { "nodefskels", 0, 0, G_OPTION_ARG_NONE, &cl_disable_defs_skels, N_("Don't output defs for skels in header"), NULL },
+ { "deps", 0, 0, G_OPTION_ARG_FILENAME, &cl_deps_file, N_("Generate dependency info suitable for inclusion in Makefile"), N_("FILENAME") },
+ { "headerguardprefix", 0, 0, G_OPTION_ARG_STRING, &cl_header_guard_prefix, N_("Prefix for #ifdef header guards. Sometimes useful to avoid conflicts."), N_("PREFIX") },
+ { "output-dir", 0, 0, G_OPTION_ARG_FILENAME, &cl_output_directory, N_("Where to put generated files. This directory must exist."), N_("DIR") },
+ { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &idl_files, NULL, N_("<IDL files>") },
+ { NULL }
+};
+
+/********** main routines **********/
+int main(int argc, char *argv[])
+{
+ GOptionContext *context;
+ GOptionGroup *group;
+ GError *error = NULL;
+ OIDL_Run_Info rinfo;
+ GPtrArray *args;
+ int retval = 0;
+ gboolean result;
+ gpointer freeme;
+ guint i;
+
+ /* Argument parsing, etc. */
+ cl_cpp_args = g_string_new("-D__FORB_IDL__ ");
+
+ /* GOption cannot parse single-letter options without space
+ * between option and argument (-I../dir) or single-dash options.
+ * So fix those up before parsing, to retain command line compatibility
+ * with previous popt based versions of forb-idl-2
+ */
+ args = g_ptr_array_sized_new (2 * argc);
+ g_ptr_array_add (args, g_strdup (argv[0]));
+
+ for (i = 1; i < argc; ++i) {
+ if (argv[i][0] == '-' &&
+ (argv[i][1] == 'D' || argv[i][1] == 'I') &&
+ argv[i][2] != '\0') {
+ g_ptr_array_add (args, g_strndup (argv[i], 2));
+ g_ptr_array_add (args, g_strdup (argv[i] + 2));
+ } else if (strcmp (argv[i], "-define") == 0 ||
+ strcmp (argv[i], "-include") == 0) {
+ g_ptr_array_add (args, g_strdup_printf ("-%s", argv[i]));
+ } else {
+ g_ptr_array_add (args, g_strdup (argv[i]));
+ }
+ }
+
+ /* Parsing will modify the array; memdup it beforehand
+ * so we can free it correctly
+ */
+ argc = args->len;
+ argv = freeme = g_memdup (args->pdata, argc * sizeof (gpointer));
+ g_ptr_array_add (args, NULL); /* so we can use g_strfreev */
+
+ /* Now parse the options */
+ context = g_option_context_new ("");
+ g_option_context_add_main_entries (context, goptions, GETTEXT_PACKAGE);
+
+ group = g_option_group_new ("libIDL", N_("libIDL options"), N_("Show libIDL options"), NULL, NULL);
+ g_option_group_set_translation_domain (group, GETTEXT_PACKAGE);
+ g_option_group_add_entries (group, cl_libIDL_goptions);
+ g_option_context_add_group (context, group);
+
+ group = g_option_group_new ("cpp", N_("Preprocessor options"), N_("Show preprocessor options"), NULL, NULL);
+ g_option_group_set_translation_domain (group, GETTEXT_PACKAGE);
+ g_option_group_add_entries (group, cl_cpp_goptions);
+ g_option_context_add_group (context, group);
+
+ result = g_option_context_parse (context, &argc, &argv, &error);
+
+ g_option_context_free (context);
+ g_strfreev ((char **) g_ptr_array_free (args, FALSE));
+ g_free (freeme);
+
+ if (!result) {
+ g_print ("forb-idl-2: %s\n", error->message);
+ g_error_free (error);
+ exit (1);
+ }
+
+ if (!idl_files) {
+ g_print ("No input files given!\n");
+ exit (1);
+ }
+
+ /* Prep our run info for the backend */
+ rinfo.cpp_args = cl_cpp_args->str;
+ rinfo.debug_level = cl_debuglevel;
+ rinfo.idl_warn_level = cl_idlwarnlevel;
+ rinfo.show_cpp_errors = cl_showcpperrors;
+ rinfo.is_pidl = cl_is_pidl;
+ rinfo.do_skel_defs = !cl_disable_defs_skels;
+ rinfo.enabled_passes =
+ (cl_disable_stubs?0:OUTPUT_STUBS)
+ |(cl_disable_skels?0:OUTPUT_SKELS)
+ |(cl_disable_common?0:OUTPUT_COMMON)
+ |(cl_disable_headers?0:OUTPUT_HEADERS)
+/* |(cl_enable_skeleton_impl?OUTPUT_SKELIMPL:0) */
+/* |(cl_add_imodule?OUTPUT_IMODULE:0) */
+ |(cl_deps_file != NULL?OUTPUT_DEPS:0)
+ ;
+
+ rinfo.deps_file = cl_deps_file;
+
+/* if (cl_enable_imodule) /\* clobber *\/ */
+/* rinfo.enabled_passes = */
+/* OUTPUT_COMMON | OUTPUT_HEADERS | OUTPUT_IMODULE; */
+
+ rinfo.output_language = cl_output_lang;
+ rinfo.header_guard_prefix = cl_header_guard_prefix;
+ rinfo.include = cl_include;
+ rinfo.output_directory = cl_output_directory;
+ rinfo.backend_directory = cl_backend_dir;
+ rinfo.onlytop = cl_onlytop;
+ rinfo.idata = !cl_disable_idata;
+
+ if (cl_debuglevel) {
+ printf ("forb-idl-2 " VERSION " compiling\n");
+ printf (" %s mode, %s preprocessor errors, passes: %s%s%s%s%s%s\n\n",
+ rinfo.is_pidl ? "pidl" : "",
+ rinfo.show_cpp_errors ? "show" : "hide",
+ rinfo.enabled_passes&OUTPUT_STUBS ? "stubs " : "",
+ rinfo.enabled_passes&OUTPUT_SKELS ? "skels " : "",
+ rinfo.enabled_passes&OUTPUT_COMMON ? "common " : "",
+ rinfo.enabled_passes&OUTPUT_HEADERS ? "headers " : "",
+ rinfo.enabled_passes&OUTPUT_SKELIMPL ? "skel_impl " : "",
+ rinfo.enabled_passes&OUTPUT_IMODULE ? "imodule" : "");
+ }
+
+ /* Do it */
+ for (i = 0; idl_files[i]; ++i) {
+ if (cl_debuglevel) g_print ("Processing file %s\n", idl_files[i]);
+ rinfo.input_filename = idl_files[i];
+ if (!forb_idl_to_backend(idl_files[i], &rinfo)) {
+ g_warning("%s compilation failed", idl_files[i]);
+ retval = 1;
+ }
+ }
+
+ exit (retval);
+}
--- /dev/null
+#include "config.h"
+#include "forb-idl2.h"
+#include <string.h>
+#include <inttypes.h>
+
+void
+forb_idl_check_oneway_op (IDL_tree op)
+{
+ g_assert (IDL_NODE_TYPE(op) == IDLN_OP_DCL);
+
+ if (IDL_OP_DCL (op).f_oneway) {
+ IDL_tree sub;
+
+ for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
+ IDL_tree param = IDL_LIST (sub).data;
+
+ if (IDL_PARAM_DCL (param).attr == IDL_PARAM_OUT ||
+ IDL_PARAM_DCL (param).attr == IDL_PARAM_INOUT) {
+ g_warning ("Out or Inout parameter in declaration of oneway '%s'",
+ IDL_IDENT(IDL_OP_DCL(op).ident).str);
+ break;
+ }
+ }
+
+ if (IDL_OP_DCL (op).op_type_spec)
+ g_warning ("Return value in declaration of oneway '%s'",
+ IDL_IDENT(IDL_OP_DCL(op).ident).str);
+ }
+}
+
+void
+forb_idl_attr_fake_ops(IDL_tree attr, IDL_ns ns)
+{
+ IDL_tree attr_name, ident, curnode, op1, op2, intf;
+ GString *attrname;
+ OIDL_Attr_Info *setme;
+
+ g_assert(attr && IDL_NODE_TYPE(attr) == IDLN_ATTR_DCL);
+
+ attrname = g_string_new(NULL);
+
+ for(curnode = IDL_ATTR_DCL(attr).simple_declarations; curnode; curnode = IDL_LIST(curnode).next) {
+ op1 = op2 = NULL;
+
+ attr_name = IDL_LIST(curnode).data;
+
+ g_string_printf(attrname, "_get_%s",
+ IDL_IDENT(attr_name).str);
+ ident = IDL_ident_new(g_strdup(attrname->str));
+ IDL_IDENT_TO_NS(ident) = IDL_IDENT_TO_NS(attr_name);
+ op1 = IDL_op_dcl_new(0, IDL_ATTR_DCL(attr).param_type_spec, ident, NULL, NULL, NULL);
+ IDL_NODE_UP(op1) = IDL_NODE_UP(attr);
+ intf = IDL_NODE_UP (IDL_NODE_UP (op1));
+ IDL_NS(ns).current = IDL_IDENT_TO_NS (IDL_INTERFACE (intf).ident);
+ IDL_ns_place_new(ns, ident);
+
+ if(!IDL_ATTR_DCL(attr).f_readonly) {
+ g_string_printf(attrname, "_set_%s",
+ IDL_IDENT(attr_name).str);
+ ident = IDL_ident_new(g_strdup(attrname->str));
+ IDL_IDENT_TO_NS(ident) = IDL_IDENT_TO_NS(attr_name);
+ op2 = IDL_op_dcl_new(0, NULL, ident, NULL, NULL, NULL);
+ IDL_NODE_UP(op2) = IDL_NODE_UP(attr);
+ intf = IDL_NODE_UP (IDL_NODE_UP (op2));
+ IDL_NS(ns).current = IDL_IDENT_TO_NS (IDL_INTERFACE (intf).ident);
+ IDL_ns_place_new(ns, ident);
+ IDL_OP_DCL(op2).parameter_dcls = IDL_list_new(
+ IDL_param_dcl_new(IDL_PARAM_IN,
+ IDL_ATTR_DCL(attr).param_type_spec,
+ IDL_ident_new(g_strdup("value"))));
+ }
+
+ setme = g_new0(OIDL_Attr_Info, 1);
+ setme->op1 = op1;
+ setme->op2 = op2;
+ attr_name->data = setme;
+ }
+
+ g_string_free(attrname, TRUE);
+}
+
+#define INDENT_INCREMENT_1 2
+#define INDENT_INCREMENT_2 4
+
+static void do_indent(int level) {
+ int i;
+ for(i = 0; i < level; i++) g_print(" ");
+}
+
+void
+forb_idl_print_node(IDL_tree node, int indent_level)
+{
+ IDL_tree curnode;
+ char *s;
+
+ do_indent(indent_level);
+
+ if(node == NULL) {
+ g_print("(null)\n");
+ return;
+ }
+
+ g_print("[%d] ", IDL_NODE_REFS(node));
+
+ switch(IDL_NODE_TYPE(node)) {
+
+ case IDLN_NONE:
+ g_print("NONE\n");
+ break;
+
+ case IDLN_LIST:
+ g_print("LIST:\n");
+ for(curnode = node; curnode;
+ curnode = IDL_LIST(curnode).next) {
+ forb_idl_print_node(IDL_LIST(curnode).data, indent_level + INDENT_INCREMENT_1);
+ }
+ break;
+
+ case IDLN_GENTREE:
+ break;
+
+ case IDLN_INTEGER:
+ g_print("INTEGER: %" PRId64 "\n", IDL_INTEGER(node).value);
+ break;
+
+ case IDLN_STRING:
+ g_print("STRING: %s\n", IDL_STRING(node).value);
+ break;
+
+ case IDLN_WIDE_STRING:
+ g_print("WIDE STRING: %ls\n", IDL_WIDE_STRING(node).value);
+ break;
+
+ case IDLN_CHAR:
+ g_print("CHAR: %s\n", IDL_CHAR(node).value);
+ break;
+
+ case IDLN_WIDE_CHAR:
+ g_print("WIDE CHAR: %ls\n", IDL_WIDE_CHAR(node).value);
+ break;
+
+ case IDLN_FIXED:
+ g_print("FIXED: %s\n", IDL_FIXED(node).value);
+ break;
+
+ case IDLN_FLOAT:
+ g_print("FLOAT: %f\n", IDL_FLOAT(node).value);
+ break;
+
+ case IDLN_BOOLEAN:
+ g_print("BOOLEAN: %s\n", (IDL_BOOLEAN(node).value)?"True":"False");
+ break;
+
+ case IDLN_IDENT:
+ s = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(node), "_", 0);
+ g_print("IDENT: %s NSQ: %s RID: \"%s\"\n",
+ IDL_IDENT(node).str, s,
+ IDL_IDENT_REPO_ID(node) ? IDL_IDENT_REPO_ID(node) : "");
+ g_free(s);
+ break;
+
+ case IDLN_TYPE_DCL:
+ g_print("TYPE DCL:\n");
+ forb_idl_print_node(IDL_TYPE_DCL(node).type_spec, indent_level + INDENT_INCREMENT_1);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("decls:\n");
+ forb_idl_print_node(IDL_TYPE_DCL(node).dcls, indent_level + INDENT_INCREMENT_2);
+ break;
+
+ case IDLN_CONST_DCL:
+ g_print("CONST DCL:\n");
+ forb_idl_print_node(IDL_CONST_DCL(node).const_type, indent_level + INDENT_INCREMENT_1);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("ident:\n");
+ forb_idl_print_node(IDL_CONST_DCL(node).ident, indent_level + INDENT_INCREMENT_2);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("const_exp:\n");
+ forb_idl_print_node(IDL_CONST_DCL(node).const_exp, indent_level + INDENT_INCREMENT_2);
+ break;
+
+ case IDLN_EXCEPT_DCL:
+ g_print("EXCEPT DCL:\n");
+ forb_idl_print_node(IDL_EXCEPT_DCL(node).ident, indent_level + INDENT_INCREMENT_1);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("members:\n");
+ forb_idl_print_node(IDL_EXCEPT_DCL(node).members, indent_level + INDENT_INCREMENT_2);
+ break;
+
+ case IDLN_ATTR_DCL:
+ g_print("ATTR_DCL (%s):\n", (IDL_ATTR_DCL(node).f_readonly)?"readonly":"rw");
+ forb_idl_print_node(IDL_ATTR_DCL(node).param_type_spec, indent_level + INDENT_INCREMENT_1);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("simple_declarations:\n");
+ forb_idl_print_node(IDL_ATTR_DCL(node).simple_declarations, indent_level + INDENT_INCREMENT_2);
+ break;
+
+ case IDLN_OP_DCL:
+ g_print("OP DCL (%s):\n", (IDL_OP_DCL(node).f_oneway)?"oneway":"normal");
+ forb_idl_print_node(IDL_OP_DCL(node).ident, indent_level + INDENT_INCREMENT_1);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("op_type_spec:\n");
+ forb_idl_print_node(IDL_OP_DCL(node).op_type_spec, indent_level + INDENT_INCREMENT_2);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("parameter_dcls:\n");
+ forb_idl_print_node(IDL_OP_DCL(node).parameter_dcls, indent_level + INDENT_INCREMENT_2);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("raises_expr:\n");
+ forb_idl_print_node(IDL_OP_DCL(node).raises_expr, indent_level + INDENT_INCREMENT_2);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("context_expr:\n");
+ forb_idl_print_node(IDL_OP_DCL(node).context_expr, indent_level + INDENT_INCREMENT_2);
+ break;
+
+ case IDLN_PARAM_DCL:
+ g_print("PARAM DCL: ");
+ switch(IDL_PARAM_DCL(node).attr) {
+ case IDL_PARAM_IN: g_print("(in)\n"); break;
+ case IDL_PARAM_OUT: g_print("(out)\n"); break;
+ case IDL_PARAM_INOUT: g_print("(inout)\n"); break;
+ }
+ forb_idl_print_node(IDL_PARAM_DCL(node).param_type_spec, indent_level + INDENT_INCREMENT_1);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("simple_declarator:\n");
+ forb_idl_print_node(IDL_PARAM_DCL(node).simple_declarator, indent_level + INDENT_INCREMENT_2);
+ break;
+ case IDLN_FORWARD_DCL:
+ g_print("FORWARD DCL:\n");
+ forb_idl_print_node(IDL_FORWARD_DCL(node).ident, indent_level + INDENT_INCREMENT_1);
+ break;
+ case IDLN_INTERFACE:
+ g_print("INTERFACE:\n");
+ forb_idl_print_node(IDL_INTERFACE(node).ident, indent_level + INDENT_INCREMENT_1);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("inheritance_spec:\n");
+ forb_idl_print_node(IDL_INTERFACE(node).inheritance_spec, indent_level + INDENT_INCREMENT_2);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("body:\n");
+ forb_idl_print_node(IDL_INTERFACE(node).body, indent_level + INDENT_INCREMENT_2);
+ break;
+ case IDLN_MODULE:
+ g_print("MODULE:\n");
+ forb_idl_print_node(IDL_MODULE(node).ident, indent_level + INDENT_INCREMENT_1);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("definition_list:\n");
+ forb_idl_print_node(IDL_MODULE(node).definition_list, indent_level + INDENT_INCREMENT_2);
+ break;
+
+ case IDLN_TYPE_INTEGER:
+ if(!IDL_TYPE_INTEGER(node).f_signed) g_print("TYPE unsigned ");
+ switch(IDL_TYPE_INTEGER(node).f_type) {
+ case IDL_INTEGER_TYPE_SHORT: g_print("short\n"); break;
+ case IDL_INTEGER_TYPE_LONG: g_print("long\n"); break;
+ case IDL_INTEGER_TYPE_LONGLONG: g_print("long long\n"); break;
+ }
+ break;
+ case IDLN_TYPE_FLOAT:
+ switch(IDL_TYPE_FLOAT(node).f_type) {
+ case IDL_FLOAT_TYPE_FLOAT: g_print("TYPE float\n"); break;
+ case IDL_FLOAT_TYPE_DOUBLE: g_print("TYPE double\n"); break;
+ case IDL_FLOAT_TYPE_LONGDOUBLE: g_print("TYPE long double\n"); break;
+ }
+ break;
+ case IDLN_TYPE_FIXED:
+ g_print("TYPE fixed:\n");
+ forb_idl_print_node(IDL_TYPE_FIXED(node).positive_int_const, indent_level + INDENT_INCREMENT_1);
+ forb_idl_print_node(IDL_TYPE_FIXED(node).integer_lit, indent_level + INDENT_INCREMENT_1);
+ break;
+ case IDLN_TYPE_STRING:
+ g_print("TYPE string:\n");
+ forb_idl_print_node(IDL_TYPE_STRING(node).positive_int_const, indent_level + INDENT_INCREMENT_1);
+ break;
+ case IDLN_TYPE_WIDE_STRING:
+ g_print("TYPE wide string:\n");
+ forb_idl_print_node(IDL_TYPE_WIDE_STRING(node).positive_int_const, indent_level + INDENT_INCREMENT_1);
+ break;
+ case IDLN_TYPE_ENUM:
+ g_print("TYPE enum:\n");
+ forb_idl_print_node(IDL_TYPE_ENUM(node).ident, indent_level + INDENT_INCREMENT_1);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("enumerator_list:\n");
+ forb_idl_print_node(IDL_TYPE_ENUM(node).enumerator_list, indent_level + INDENT_INCREMENT_2);
+ break;
+ case IDLN_TYPE_ARRAY:
+ g_print("TYPE array:\n");
+ forb_idl_print_node(IDL_TYPE_ARRAY(node).ident, indent_level + INDENT_INCREMENT_1);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("size_list:\n");
+ forb_idl_print_node(IDL_TYPE_ARRAY(node).size_list, indent_level + INDENT_INCREMENT_2);
+ break;
+ case IDLN_TYPE_SEQUENCE:
+ g_print("TYPE sequence:\n");
+ forb_idl_print_node(IDL_TYPE_SEQUENCE(node).simple_type_spec, indent_level + INDENT_INCREMENT_1);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("positive_int_const:\n");
+ forb_idl_print_node(IDL_TYPE_SEQUENCE(node).positive_int_const, indent_level + INDENT_INCREMENT_2);
+ break;
+ case IDLN_TYPE_STRUCT:
+ g_print("TYPE struct:\n");
+ forb_idl_print_node(IDL_TYPE_STRUCT(node).ident, indent_level + INDENT_INCREMENT_1);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("member_list:\n");
+ forb_idl_print_node(IDL_TYPE_STRUCT(node).member_list, indent_level + INDENT_INCREMENT_2);
+ break;
+ case IDLN_TYPE_UNION:
+ g_print("TYPE union:\n");
+ forb_idl_print_node(IDL_TYPE_UNION(node).ident, indent_level + INDENT_INCREMENT_1);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("switch_type_spec:\n");
+ forb_idl_print_node(IDL_TYPE_UNION(node).switch_type_spec, indent_level + INDENT_INCREMENT_2);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("switch_body:\n");
+ forb_idl_print_node(IDL_TYPE_UNION(node).switch_body, indent_level + INDENT_INCREMENT_2);
+ break;
+ case IDLN_MEMBER:
+ g_print("MEMBER:\n");
+ forb_idl_print_node(IDL_MEMBER(node).type_spec, indent_level + INDENT_INCREMENT_1);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("dcls:\n");
+ forb_idl_print_node(IDL_MEMBER(node).dcls, indent_level + INDENT_INCREMENT_2);
+ break;
+ case IDLN_CASE_STMT:
+ g_print("CASE_STMT:\n");
+ forb_idl_print_node(IDL_CASE_STMT(node).labels, indent_level + INDENT_INCREMENT_1);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("element_spec:\n");
+ forb_idl_print_node(IDL_CASE_STMT(node).element_spec, indent_level + INDENT_INCREMENT_2);
+ break;
+ case IDLN_BINOP:
+ g_print("BINOP ");
+ switch(IDL_BINOP(node).op) {
+ case IDL_BINOP_OR: g_print("or:\n"); break;
+ case IDL_BINOP_XOR: g_print("xor:\n"); break;
+ case IDL_BINOP_AND: g_print("and:\n"); break;
+ case IDL_BINOP_SHR: g_print("shr:\n"); break;
+ case IDL_BINOP_SHL: g_print("shl:\n"); break;
+ case IDL_BINOP_ADD: g_print("add:\n"); break;
+ case IDL_BINOP_SUB: g_print("sub:\n"); break;
+ case IDL_BINOP_MULT: g_print("mult:\n"); break;
+ case IDL_BINOP_DIV: g_print("div:\n"); break;
+ case IDL_BINOP_MOD: g_print("mod:\n"); break;
+ }
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("left:\n");
+ forb_idl_print_node(IDL_BINOP(node).left, indent_level + INDENT_INCREMENT_2);
+ do_indent(indent_level + INDENT_INCREMENT_1); g_print("right:\n");
+ forb_idl_print_node(IDL_BINOP(node).right, indent_level + INDENT_INCREMENT_2);
+ break;
+ case IDLN_UNARYOP:
+ g_print("UNARYOP ");
+ switch(IDL_UNARYOP(node).op) {
+ case IDL_UNARYOP_PLUS: g_print("plus:\n"); break;
+ case IDL_UNARYOP_MINUS: g_print("minus:\n"); break;
+ case IDL_UNARYOP_COMPLEMENT: g_print("complement:\n"); break;
+ }
+ forb_idl_print_node(IDL_UNARYOP(node).operand, indent_level + INDENT_INCREMENT_1);
+ break;
+ case IDLN_TYPE_CHAR:
+ g_print("TYPE char\n");
+ break;
+ case IDLN_TYPE_WIDE_CHAR:
+ g_print("TYPE wide char\n");
+ break;
+ case IDLN_TYPE_BOOLEAN:
+ g_print("TYPE boolean\n");
+ break;
+ case IDLN_TYPE_OCTET:
+ g_print("TYPE octet\n");
+ break;
+ case IDLN_TYPE_OBJECT:
+ g_print("TYPE object\n");
+ break;
+ case IDLN_TYPE_ANY:
+ g_print("TYPE any\n");
+ break;
+ case IDLN_TYPE_TYPECODE:
+ g_print("TYPE TypeCode\n");
+ break;
+ case IDLN_CODEFRAG:
+ g_print("CODEFRAG\n");
+ break;
+ case IDLN_SRCFILE:
+ g_print("SRCFILE %s\n", IDL_SRCFILE(node).filename);
+ break;
+ default:
+ g_print("unhandled %d\n", IDL_NODE_TYPE(node));
+ }
+}
+
+static void
+IDL_tree_traverse_helper(IDL_tree p, GFunc f,
+ gconstpointer func_data,
+ GHashTable *visited_nodes,
+ gboolean include_self)
+{
+ IDL_tree curitem;
+
+ if (g_hash_table_lookup (visited_nodes, p))
+ return;
+
+ g_hash_table_insert (visited_nodes, p, ((gpointer)1));
+
+ for (curitem = IDL_INTERFACE (p).inheritance_spec; curitem;
+ curitem = IDL_LIST (curitem).next) {
+ IDL_tree_traverse_helper (IDL_get_parent_node
+ (IDL_LIST (curitem).data, IDLN_INTERFACE, NULL), f, func_data, visited_nodes, TRUE);
+ }
+
+ if (include_self)
+ f(p, (gpointer)func_data);
+}
+
+void
+IDL_tree_traverse_parents_full (IDL_tree p,
+ GFunc f,
+ gconstpointer func_data,
+ gboolean include_self)
+{
+ GHashTable *visited_nodes = g_hash_table_new (NULL, g_direct_equal);
+
+ if (!(p && f))
+ return;
+
+ if (IDL_NODE_TYPE(p) != IDLN_INTERFACE)
+ p = IDL_get_parent_node (p, IDLN_INTERFACE, NULL);
+
+ if (!p)
+ return;
+
+ IDL_tree_traverse_helper (p, f, func_data, visited_nodes, include_self);
+
+ g_hash_table_destroy (visited_nodes);
+}
+
+void
+IDL_tree_traverse_parents (IDL_tree p,
+ GFunc f,
+ gconstpointer func_data)
+{
+ IDL_tree_traverse_parents_full (p, f, func_data, TRUE);
+}
+
+/* For use by below function */
+static const int *
+forb_cbe_get_typeoffsets_table (void)
+{
+ static int typeoffsets[IDLN_LAST];
+ static gboolean initialized = FALSE;
+
+ if (!initialized) {
+ int i;
+
+ for (i = 0; i < IDLN_LAST; ++i)
+ typeoffsets[i] = -1;
+
+ typeoffsets[IDLN_FORWARD_DCL] = 8; /* (same as objref) */
+ typeoffsets[IDLN_TYPE_INTEGER] = 0;
+ typeoffsets[IDLN_TYPE_FLOAT] = 0;
+ typeoffsets[IDLN_TYPE_FIXED] = 3;
+ typeoffsets[IDLN_TYPE_CHAR] = 5;
+ typeoffsets[IDLN_TYPE_WIDE_CHAR] = 6;
+ typeoffsets[IDLN_TYPE_STRING] = 12;
+ typeoffsets[IDLN_TYPE_WIDE_STRING] = 13;
+ typeoffsets[IDLN_TYPE_BOOLEAN] = 4;
+ typeoffsets[IDLN_TYPE_OCTET] = 7;
+ typeoffsets[IDLN_TYPE_ANY] = 16;
+ typeoffsets[IDLN_TYPE_OBJECT] = 9;
+ typeoffsets[IDLN_TYPE_TYPECODE] = 9;
+ typeoffsets[IDLN_TYPE_ENUM] = 8;
+ typeoffsets[IDLN_TYPE_SEQUENCE] = 14;
+ typeoffsets[IDLN_TYPE_ARRAY] = 15;
+ typeoffsets[IDLN_TYPE_STRUCT] = 10;
+ typeoffsets[IDLN_TYPE_UNION] = 11;
+ typeoffsets[IDLN_NATIVE] = 15; /* no pointers ever, same as fixed array */
+ typeoffsets[IDLN_INTERFACE] = 9; /* (same as objref) */
+
+ initialized = TRUE;
+ }
+
+ return typeoffsets;
+}
+
+
+/**
+ This is a rather hairy function. Its purpose is to output the
+ required number of *'s that indicate the amount of indirection
+ for input, output, & input-output parameters, and return
+ values. We do this by having a table of the number of *'s for
+ each type and purpose (nptrrefs_required), taken from 19.20
+ of the CORBA 2.2 spec, and then having a table that translates
+ from the IDLN_* enums into an index into nptrrefs_required (typeoffsets)
+**/
+gint
+oidl_param_info(IDL_tree in_param, IDL_ParamRole role, gboolean *isSlice)
+{
+ IDL_tree param;
+ const int * const typeoffsets = forb_cbe_get_typeoffsets_table ();
+ const int nptrrefs_required[][4] = {
+ {0,1,1,0} /* float */,
+ {0,1,1,0} /* double */,
+ {0,1,1,0} /* long double */,
+ {1,1,1,0} /* fixed_d_s 3 */,
+ {0,1,1,0} /* boolean */,
+ {0,1,1,0} /* char */,
+ {0,1,1,0} /* wchar */,
+ {0,1,1,0} /* octet */,
+ {0,1,1,0} /* enum */,
+ {0,1,1,0} /* objref */,
+ {1,1,1,0} /* fixed struct 10 */,
+ {1,1,1,0} /* fixed union */,
+ {0,1,1,0} /* string */,
+ {0,1,1,0} /* wstring */,
+ {1,1,2,1} /* sequence */,
+ {0,0,0,0} /* fixed array */,
+ {1,1,2,1} /* any 16 */
+ };
+ int retval = 0;
+ int typeidx;
+
+ *isSlice = FALSE;
+
+ if(!in_param)
+ return 0; /* void */
+
+ /* Now, how do we use this table? :) */
+ param = forb_cbe_get_typespec (in_param);
+
+ g_assert (param);
+
+ switch (IDL_NODE_TYPE (param)) {
+ case IDLN_TYPE_STRUCT:
+ case IDLN_TYPE_UNION:
+ if (((role == DATA_RETURN) || (role == DATA_OUT)) &&
+ !forb_cbe_type_is_fixed_length(param))
+ retval++;
+ break;
+
+ case IDLN_TYPE_ARRAY:
+ if ( role == DATA_RETURN ) {
+ *isSlice = TRUE;
+ retval = 1;
+
+ } else if (role == DATA_OUT &&
+ !forb_cbe_type_is_fixed_length (param)) {
+ *isSlice = TRUE;
+ retval = 2;
+ }
+ break;
+
+ case IDLN_NATIVE:
+ if ( IDL_NATIVE (param).user_type
+ && strcmp (IDL_NATIVE (param).user_type,
+ "IDL_variable_length_struct") == 0 ) {
+ return role == DATA_OUT ? 2 : 1;
+ }
+ else {
+ return role == DATA_IN ? 0 : 1;
+
+ }
+ break;
+
+ case IDLN_EXCEPT_DCL:
+ fprintf (stderr, "Error: exception declared at '%s:%d' cannot be "
+ "used as a method parameter\n", in_param->_file,
+ in_param->_line);
+ exit (1);
+ break;
+ default:
+ break;
+ }
+
+ /* ERROR ! */
+ typeidx = typeoffsets [IDL_NODE_TYPE (param)];
+ g_assert (typeidx >= 0);
+
+ switch (role) {
+ case DATA_IN:
+ role = 0;
+ break;
+ case DATA_INOUT:
+ role = 1;
+ break;
+ case DATA_OUT:
+ role = 2;
+ break;
+ case DATA_RETURN:
+ role = 3;
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ retval += nptrrefs_required [typeidx] [role];
+
+ return retval;
+}
+
+/**
+ Fixed-length-ness is a property that CORBA defines, and it is
+ a property of each type, not each kind. Furthermore, it doesnt
+ depend on the language mapping. Generally, the GIOP coding
+ a fixed length variable will be a known length (determined by the TC),
+ regardless of the data within the variable.
+
+ With the C mapping, fixed --> nothing to free in this node
+ Note that in the C mapping, everything is a struct and is
+ fixed length in that sense. Thus variable length types show
+ up in C as pointers.
+
+ Recursive types introduced by sequences are not a problem for this
+ func, because sequences are not fixed length, and terminate
+ the recursion.
+**/
+
+gboolean
+forb_cbe_type_is_fixed_length(IDL_tree ts)
+{
+ gboolean is_fixed = TRUE;
+ IDL_tree curitem;
+
+ ts = forb_cbe_get_typespec(ts);
+ switch(IDL_NODE_TYPE(ts)) {
+ case IDLN_TYPE_FLOAT:
+ case IDLN_TYPE_INTEGER:
+ case IDLN_TYPE_ENUM:
+ case IDLN_TYPE_CHAR:
+ case IDLN_TYPE_WIDE_CHAR:
+ case IDLN_TYPE_OCTET:
+ case IDLN_TYPE_BOOLEAN:
+ return TRUE;
+ break;
+ case IDLN_TYPE_SEQUENCE:
+ case IDLN_TYPE_STRING:
+ case IDLN_TYPE_WIDE_STRING:
+ case IDLN_TYPE_OBJECT:
+ case IDLN_FORWARD_DCL:
+ case IDLN_INTERFACE:
+ case IDLN_TYPE_ANY:
+ case IDLN_NATIVE:
+ case IDLN_TYPE_TYPECODE:
+ return FALSE;
+ break;
+ case IDLN_TYPE_UNION:
+ for(curitem = IDL_TYPE_UNION(ts).switch_body; curitem;
+ curitem = IDL_LIST(curitem).next) {
+ is_fixed &= forb_cbe_type_is_fixed_length(IDL_LIST(IDL_CASE_STMT(IDL_LIST(curitem).data).element_spec).data);
+ }
+ return is_fixed;
+ break;
+ case IDLN_EXCEPT_DCL:
+ case IDLN_TYPE_STRUCT:
+ for(curitem = IDL_TYPE_STRUCT(ts).member_list; curitem;
+ curitem = IDL_LIST(curitem).next) {
+ is_fixed &= forb_cbe_type_is_fixed_length(IDL_LIST(curitem).data);
+ }
+ return is_fixed;
+ break;
+ case IDLN_TYPE_ARRAY:
+ return forb_cbe_type_is_fixed_length(IDL_TYPE_DCL(IDL_get_parent_node(ts, IDLN_TYPE_DCL, NULL)).type_spec);
+ break;
+ case IDLN_TYPE_DCL:
+ return forb_cbe_type_is_fixed_length(IDL_TYPE_DCL(ts).type_spec);
+ break;
+ case IDLN_IDENT:
+ case IDLN_LIST:
+ return forb_cbe_type_is_fixed_length(IDL_NODE_UP(ts));
+ break;
+ case IDLN_MEMBER:
+ return forb_cbe_type_is_fixed_length(IDL_MEMBER(ts).type_spec);
+ break;
+ default:
+ g_warning("I'm not sure if type %s is fixed-length", IDL_tree_type_names[IDL_NODE_TYPE(ts)]);
+ return FALSE;
+ }
+}
+
+IDL_tree
+forb_cbe_get_typespec(IDL_tree node)
+{
+ if(node == NULL)
+ return NULL;
+
+ switch(IDL_NODE_TYPE(node)) {
+ case IDLN_TYPE_INTEGER:
+ case IDLN_TYPE_FLOAT:
+ case IDLN_TYPE_FIXED:
+ case IDLN_TYPE_CHAR:
+ case IDLN_TYPE_WIDE_CHAR:
+ case IDLN_TYPE_STRING:
+ case IDLN_TYPE_WIDE_STRING:
+ case IDLN_TYPE_BOOLEAN:
+ case IDLN_TYPE_OCTET:
+ case IDLN_TYPE_ANY:
+ case IDLN_TYPE_OBJECT:
+ case IDLN_TYPE_ENUM:
+ case IDLN_TYPE_SEQUENCE:
+ case IDLN_TYPE_ARRAY:
+ case IDLN_TYPE_STRUCT:
+ case IDLN_TYPE_UNION:
+ case IDLN_EXCEPT_DCL:
+ case IDLN_FORWARD_DCL:
+ case IDLN_INTERFACE:
+ case IDLN_NATIVE:
+ case IDLN_TYPE_TYPECODE:
+ return node;
+ break;
+ case IDLN_TYPE_DCL:
+ return forb_cbe_get_typespec(IDL_TYPE_DCL(node).type_spec);
+ break;
+ case IDLN_PARAM_DCL:
+ return forb_cbe_get_typespec(IDL_PARAM_DCL(node).param_type_spec);
+ break;
+ case IDLN_MEMBER:
+ return forb_cbe_get_typespec(IDL_MEMBER(node).type_spec);
+ break;
+ case IDLN_LIST:
+ case IDLN_IDENT:
+ return forb_cbe_get_typespec(IDL_get_parent_node(node, IDLN_ANY, NULL));
+ break;
+ default:
+ g_error("Unhandled node type %s!", IDL_tree_type_names[IDL_NODE_TYPE(node)]);
+ return NULL;
+ }
+}
+
+IDL_ParamRole
+oidl_attr_to_paramrole(enum IDL_param_attr attr)
+{
+ switch(attr) {
+ case IDL_PARAM_IN:
+ return DATA_IN;
+ case IDL_PARAM_OUT:
+ return DATA_OUT;
+ case IDL_PARAM_INOUT:
+ return DATA_INOUT;
+ default:
+ g_warning("Unknown IDL_param_attr %d", attr);
+ return -1;
+ }
+}
--- /dev/null
+#ifndef FORB_IDL2_H
+#define FORB_IDL2_H 1
+
+#include "forb-idl3-types.h"
+
+gboolean forb_idl_to_backend (const char *filename,
+ OIDL_Run_Info *rinfo);
+
+gboolean forb_idl_backend_output (OIDL_Run_Info *rinfo,
+ IDL_tree tree);
+
+/* Utils */
+void forb_idl_attr_fake_ops (IDL_tree attr,
+ IDL_ns ns);
+void forb_idl_print_node (IDL_tree node,
+ int indent_level);
+void IDL_tree_traverse_parents (IDL_tree p,
+ GFunc f,
+ gconstpointer func_data);
+void IDL_tree_traverse_parents_full (IDL_tree p,
+ GFunc f,
+ gconstpointer func_data,
+ gboolean include_self);
+gboolean forb_cbe_type_contains_complex (IDL_tree ts);
+void forb_idl_check_oneway_op (IDL_tree op);
+
+typedef enum { DATA_IN=1, DATA_INOUT=2, DATA_OUT=4, DATA_RETURN=8 } IDL_ParamRole;
+gint oidl_param_info(IDL_tree param, IDL_ParamRole role, gboolean *isSlice);
+
+gboolean forb_cbe_type_is_fixed_length(IDL_tree ts);
+IDL_tree forb_cbe_get_typespec(IDL_tree node);
+IDL_ParamRole oidl_attr_to_paramrole(enum IDL_param_attr attr);
+
+#define FORB_RETVAL_VAR_NAME "_forb_retval"
+#define FORB_EPV_VAR_NAME "_FORB_epv"
+
+#endif /* FORB_IDL2_H */
--- /dev/null
+#ifndef ORBIT_IDL3_TYPES_H
+#define ORBIT_IDL3_TYPES_H 1
+
+#include <errno.h>
+#include <stdio.h>
+#include <libIDL/IDL.h>
+/* #include <orbit/util/orbit-util.h> */
+/* #include <orbit/orbit-config.h> */
+
+typedef struct _OIDL_Marshal_Context OIDL_Marshal_Context;
+
+#define OUTPUT_NUM_PASSES 7
+
+typedef struct {
+ char *cpp_args;
+ int debug_level;
+ int idl_warn_level;
+ int show_cpp_errors;
+ int is_pidl;
+ int do_skel_defs; /* gen defs within the header file */
+
+ enum { OUTPUT_STUBS=1<<0,
+ OUTPUT_SKELS=1<<1,
+ OUTPUT_COMMON=1<<2,
+ OUTPUT_HEADERS=1<<3,
+ OUTPUT_SKELIMPL=1<<4,
+ OUTPUT_IMODULE=1<<5,
+ OUTPUT_DEPS=1<<6 /* Make sure this is always the last pass or dep output will break. */
+ } enabled_passes;
+
+ char *output_language;
+ char *input_filename;
+ char *include;
+ char *backend_directory;
+ char *deps_file;
+ char *header_guard_prefix;
+ char *output_directory;
+ gboolean onlytop;
+ gboolean idata;
+
+ IDL_ns ns; /* Use ns instead of namespace because that's a C++ reserved keyword */
+} OIDL_Run_Info;
+
+typedef struct {
+ IDL_tree op1;
+ IDL_tree op2;
+} OIDL_Attr_Info;
+
+#endif
--- /dev/null
+#ifndef FORB_CONFIG_H
+#define FORB_CONFIG_H
+
+/* #define WORDS_BIGENDIAN */
+#undef WORDS_BIGENDIAN
+
+#define FORB_CONFIG_SERIAL 0
+
+#endif
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+SUBDIRS = tests
+
+CFLAGS += -I.
+
+# IDL_COMPILER += --pidl
+
+shared_LIBRARIES += forb
+forb_SOURCES = forb.c cdr.c sha1.c uuid.c iop.c proto.c syncobj.c \
+ request.c executor.c object.c peer.c port.c refcnt.c \
+ exec_req.c regref.c discovery.c daemon.c
+forb_CLIENT_IDL = types.idl iop-idl.idl forb-idl.idl
+forb_SERVER_IDL = forb-idl.idl
+
+to_forb_subdir=$(1)->forb/$(strip $(1))
+
+ifeq ($(CONFIG_FORB_PROTO_UNIX),y)
+forb_SOURCES += proto_unix.c
+renamed_include_HEADERS += $(call to_forb_subdir, proto_unix.h)
+endif
+
+# TODO: proto_inet should be a separate library as it should be used
+# only by FCB
+forb_SOURCES += proto_inet.c
+renamed_include_HEADERS += $(call to_forb_subdir, proto_inet.h)
+
+
+include_HEADERS = forb.h
+renamed_include_HEADERS += \
+ $(call to_forb_subdir, basic_types.h) \
+ $(call to_forb_subdir, cdr.h) \
+ $(call to_forb_subdir, cdr_codec.h) \
+ $(call to_forb_subdir, executor.h) \
+ $(call to_forb_subdir, exec_req.h) \
+ $(call to_forb_subdir, forb-internal.h) \
+ $(call to_forb_subdir, iop.h) \
+ $(call to_forb_subdir, object.h) \
+ $(call to_forb_subdir, object_type.h) \
+ $(call to_forb_subdir, port.h) \
+ $(call to_forb_subdir, refcnt.h) \
+ $(call to_forb_subdir, request.h) \
+ $(call to_forb_subdir, syncobj.h) \
+ $(call to_forb_subdir, server_id.h) \
+ $(call to_forb_subdir, peer.h) \
+ $(call to_forb_subdir, uuid.h)
+
+renamed_include_GEN_HEADERS = \
+ $(call to_forb_subdir,forb-idl.h) \
+ $(call to_forb_subdir,iop-idl.h) \
+ $(call to_forb_subdir,types.h)
+
+default_CONFIG = CONFIG_FORB_PROTO_UNIX=y \
+ CONFIG_FORB_RECV_BUF_SIZE=4096 \
+ CONFIG_FORB_PROTO_INET_DEFAULT=n
+
+config_include_HEADERS = forb/config.h
+config_DEFINES = CONFIG_FORB_PROTO_UNIX \
+ CONFIG_FORB_RECV_BUF_SIZE \
+ CONFIG_FORB_PROTO_INET_DEFAULT \
+ CONFIG_FCB # To see whether we are compiled with FRSH_FORB
+
+include-pass_HOOKS = log_domains.inc #request_gavl.inc
+
+log_domains.inc: $(addprefix $(SOURCES_DIR)/,ul_log_domains $(forb_SOURCES))
+ @echo " UL_LOG $@"
+ $(Q)$(SOURCES_DIR)/ul_log_domains --array forb_logreg_domains_array \
+ $(SOURCES_DIR) > $@
+
+clean-custom:
+ -$(Q)rm log_domains.inc
+
+# request_gavl.inc: $(SOURCES_DIR)/request_gavl.c
+# @echo " CPP $@"
+# $(Q)$(c_o_COMPILE) -o $@.tmp -E $<
+# $(Q)tail -n 1 $@.tmp|indent > $@
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+#ifndef BASIC_TYPES_H
+#define BASIC_TYPES_H 1
+
+#include <stdint.h>
+#include <string.h>
+
+enum {
+ CORBA_FALSE = 0,
+ CORBA_TRUE = 1
+};
+
+typedef int16_t CORBA_short;
+typedef int32_t CORBA_long;
+typedef int64_t CORBA_long_long;
+typedef uint16_t CORBA_unsigned_short;
+typedef uint32_t CORBA_unsigned_long;
+typedef uint64_t CORBA_unsigned_long_long;
+typedef float CORBA_float;
+typedef double CORBA_double;
+typedef char CORBA_char;
+typedef int16_t CORBA_wchar;
+typedef uint8_t CORBA_boolean;
+typedef uint8_t CORBA_octet;
+typedef double CORBA_long_double;
+
+/*
+ * Bad hack, oh well
+ */
+
+typedef CORBA_char *CORBA_string;
+typedef CORBA_wchar *CORBA_wstring;
+
+#define CORBA_sequence_get_release(seq) ((seq)->_release)
+/**
+ * CORBA_sequence_set_release can be used to set the state of the release flag.
+ *
+ * @param seq
+ *
+ * @param val The value of the release flag. If the flag is set to
+ * TRUE, the sequence effectively "owns" the storage pointed to by
+ * _buffer; if FALSE, the programmer is responsible for the storage
+ * [99-07-35.pdf].
+ */
+#define CORBA_sequence_set_release(seq, val) ((seq)->_release = (val))
+
+CORBA_boolean
+__forb_sequence_alloc_buf_internal(void *seq, size_t seq_size,
+ void **buf_pptr, CORBA_unsigned_long *maximum_ptr,
+ CORBA_unsigned_long num_elements, size_t elem_size);
+
+/** @name Sequence helper macros */
+/**@{*/
+/**
+ *
+ *
+ * @param seq
+ * @param num_elements
+ *
+ * @return CORBA_TRUE if the allocation was sucessfull, CORBA_FALSE if wasn't.
+ */
+#define forb_sequence_alloc_buf(seq, num_elements) \
+ __forb_sequence_alloc_buf_internal((seq), sizeof(*(seq)), \
+ (void**)&(seq)->_buffer, &(seq)->_maximum, \
+ (num_elements), sizeof(*(seq)->_buffer))
+
+#define forb_sequence_alloc(seq, num_elements) do { \
+ (seq) = forb_malloc(sizeof(*(seq))); \
+ memset((seq), 0, sizeof(*(seq))); \
+ forb_sequence_alloc_buf((seq), (num_elements)); \
+ } while(0)
+
+static inline void forb_no_destructor() {}
+
+#define forb_sequence_free_buf(seq, elem_destructor) do { \
+ if (CORBA_sequence_get_release(seq)) { \
+ CORBA_unsigned_long i; \
+ for (i=0; i<(seq)->_length; i++) { \
+ elem_destructor(&(seq)->_buffer[i]); \
+ } \
+ forb_free((seq)->_buffer); \
+ } \
+ } while(0)
+
+#define forb_sequence_free(seq, elem_destructor) do { \
+ forb_sequence_free_buf((seq), (elem_destructor)); \
+ forb_free(seq); \
+ } while(0)
+
+#define forb_sequence_elem(seq, index) ((seq)->_buffer[(index)])
+
+#define forb_sequence_length(seq) ((seq)->_length)
+#define forb_sequence_allocated(seq) ((seq)->_maximum)
+#define forb_sequence_ensure_allocated(seq, num) \
+ ((seq)->_buffer = \
+ (forb_sequence_allocated(seq) < (num)) ? \
+ (forb_sequence_allocated(seq) = (num), \
+ realloc((seq)->_buffer, (num)*sizeof(*(seq)->_buffer))) : \
+ (seq)->_buffer)
+
+#define forb_sequence_foreach(seq, elemptr) \
+ for ((elemptr)=&forb_sequence_elem((seq), 0); \
+ (elemptr)<&forb_sequence_elem((seq), forb_sequence_length(seq)); \
+ (elemptr)++)
+
+/**@}*/
+
+#endif
--- /dev/null
+/*
+ * $Id: cdr.c,v 0.0.0.1 2004/11/26
+ *
+ * CDR codeing
+ *
+ * -------------------------------------------------------------------
+ * ORTE
+ * Open Real-Time Ethernet
+ *
+ * Copyright (C) 2001-2006
+ * Department of Control Engineering FEE CTU Prague, Czech Republic
+ * http://dce.felk.cvut.cz
+ * http://www.ocera.org
+ *
+ * Author: Petr Smolik petr.smolik@wo.cz
+ * Advisor: Pavel Pisa
+ * Project Responsible: Zdenek Hanzalek
+ *
+ * Modified for FORB by Michal Sojka <sojkam1@fel.cvut.cz>, 2008
+ * --------------------------------------------------------------------
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Original of source was from ORBit: A CORBA v2.2 ORB
+ *
+ */
+
+#include <forb/cdr.h>
+#include "forb.h"
+#include "forb_endian.h"
+#include <string.h>
+
+#define ALIGN_ADDRESS(this, boundary) \
+ ((void*)((( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))))
+
+#define FORB_CDR_GROW_AMOUNT 128
+
+CORBA_boolean
+FORB_CDR_buffer_init(FORB_CDR_Codec *codec, const unsigned int size, const unsigned int first)
+{
+
+ if(codec->release_buffer) {
+ forb_free(codec->buffer);
+ }
+
+ if (first > size) {
+ return CORBA_FALSE;
+ }
+ codec->buffer=(CORBA_octet *)forb_malloc(size);
+ if (!codec->buffer) {
+ return CORBA_FALSE;
+ }
+ codec->buf_len=size;
+ codec->wptr_max=size;
+ FORB_CDR_buffer_reset(codec, first);
+ codec->release_buffer=CORBA_TRUE;
+
+ return CORBA_TRUE;
+}
+
+CORBA_boolean
+FORB_CDR_buffer_reset(FORB_CDR_Codec *codec, const unsigned int first)
+{
+ if (first > codec->buf_len) {
+ return CORBA_FALSE;
+ }
+ codec->rptr = codec->wptr = codec->wptr_last = first;
+ return CORBA_TRUE;
+}
+
+CORBA_boolean
+FORB_CDR_buffer_prepend(FORB_CDR_Codec *codec, const unsigned int len)
+{
+ if (codec->rptr < len) {
+ return CORBA_FALSE;
+ }
+ codec->rptr -= len;
+
+ codec->wptr = codec->rptr;
+
+ return CORBA_TRUE;
+}
+
+/*
+CORBA_boolean
+FORB_CDR_buffer_grow(FORB_CDR_Codec *codec, const unsigned int growth)
+{
+ unsigned int real_growth,quot;
+
+ if(codec->release_buffer) {
+ quot = growth / FORB_CDR_GROW_AMOUNT;
+ real_growth=FORB_CDR_GROW_AMOUNT * (quot+1);
+
+ codec->buffer=(CORBA_octet *)REALLOC(codec->buffer,
+ codec->buf_len
+ +real_growth);
+ }
+
+ return CORBA_TRUE;
+}
+*/
+CORBA_boolean
+FORB_CDR_buffer_puts(FORB_CDR_Codec *codec, const void *data, const unsigned int len)
+{
+ if(codec->wptr+len > codec->wptr_max) {
+ return CORBA_FALSE;
+ }
+
+ memcpy(&codec->buffer[codec->wptr], data, len);
+ codec->wptr+=len;
+ if (codec->wptr > codec->wptr_last) codec->wptr_last = codec->wptr;
+
+ return CORBA_TRUE;
+}
+
+CORBA_boolean
+FORB_CDR_buffer_gets(FORB_CDR_Codec *codec, void *dest, const unsigned int len)
+{
+ if(codec->rptr+len > codec->buf_len) {
+ return CORBA_FALSE;
+ }
+
+ memcpy(dest, &codec->buffer[codec->rptr], len);
+ codec->rptr+=len;
+
+ return CORBA_TRUE;
+}
+
+CORBA_boolean
+FORB_CDR_buffer_put(FORB_CDR_Codec *codec, void *datum)
+{
+ if(codec->wptr+1 > codec->wptr_max) {
+ return(CORBA_FALSE);
+ }
+
+ codec->buffer[codec->wptr++]=*(unsigned char *)datum;
+ if (codec->wptr > codec->wptr_last) codec->wptr_last = codec->wptr;
+ return CORBA_TRUE;
+}
+
+CORBA_boolean
+FORB_CDR_buffer_get(FORB_CDR_Codec *codec, void *dest)
+{
+ if(codec->rptr+1 > codec->buf_len) {
+ return(CORBA_FALSE);
+ }
+
+ *(CORBA_octet *)dest=codec->buffer[codec->rptr++];
+ return CORBA_TRUE;
+}
+
+#define FORB_CDR_buffer_put2(codec, datum) FORB_CDR_buffer_putn(codec, datum, 2)
+#define FORB_CDR_buffer_put4(codec, datum) FORB_CDR_buffer_putn(codec, datum, 4)
+#define FORB_CDR_buffer_put8(codec, datum) FORB_CDR_buffer_putn(codec, datum, 8)
+#define FORB_CDR_buffer_put16(codec, datum) FORB_CDR_buffer_putn(codec, datum, 16)
+#define FORB_CDR_buffer_get2(codec, dest) FORB_CDR_buffer_getn(codec, dest, 2)
+#define FORB_CDR_buffer_get4(codec, dest) FORB_CDR_buffer_getn(codec, dest, 4)
+#define FORB_CDR_buffer_get8(codec, dest) FORB_CDR_buffer_getn(codec, dest, 8)
+#define FORB_CDR_buffer_get16(codec, dest) FORB_CDR_buffer_getn(codec, dest, 16)
+
+static CORBA_boolean
+FORB_CDR_buffer_getn(FORB_CDR_Codec *codec, void *dest, int bsize)
+{
+ codec->rptr = (unsigned long)ALIGN_ADDRESS(codec->rptr, bsize);
+ if(codec->host_endian==codec->data_endian)
+ memcpy(dest, codec->buffer + codec->rptr, bsize);
+ else
+ forb_byteswap(dest, codec->buffer + codec->rptr, bsize);
+ codec->rptr += bsize;
+
+ return CORBA_TRUE;
+}
+
+static CORBA_boolean
+FORB_CDR_buffer_putn(FORB_CDR_Codec *codec, void *datum, int bsize)
+{
+ unsigned long forward,i;
+
+ forward = (unsigned long)ALIGN_ADDRESS(codec->wptr, bsize);
+ if (forward+bsize > codec->wptr_max) {
+ return CORBA_FALSE;
+ }
+
+ i = codec->wptr;
+ while(forward > i)
+ codec->buffer[i++] = '\0';
+
+ codec->wptr = forward;
+ if(codec->host_endian==codec->data_endian)
+ memcpy(codec->buffer + codec->wptr, datum, bsize);
+ else
+ forb_byteswap(codec->buffer + codec->wptr, datum, bsize);
+ codec->wptr += bsize;
+ if (codec->wptr > codec->wptr_last) codec->wptr_last = codec->wptr;
+
+ return CORBA_TRUE;
+}
+
+CORBA_boolean FORB_CDR_put_align(FORB_CDR_Codec *codec, unsigned bsize)
+{
+ unsigned long forward,i;
+
+ forward = (unsigned long)ALIGN_ADDRESS(codec->wptr, bsize);
+ if (forward+bsize > codec->wptr_max) {
+ return CORBA_FALSE;
+ }
+
+ i = codec->wptr;
+ while(forward > i)
+ codec->buffer[i++] = '\0';
+
+ codec->wptr = forward;
+ if (codec->wptr > codec->wptr_last) codec->wptr_last = codec->wptr;
+ return CORBA_TRUE;
+}
+
+CORBA_boolean FORB_CDR_get_align(FORB_CDR_Codec *codec, unsigned bsize)
+{
+ codec->rptr = (unsigned long)ALIGN_ADDRESS(codec->rptr, bsize);
+ return codec->rptr <= codec->wptr_max;
+}
+
+#define FORB_CDR_swap2(d,s) forb_byteswap((d), (s), 2)
+#define FORB_CDR_swap4(d,s) forb_byteswap((d), (s), 4)
+#define FORB_CDR_swap8(d,s) forb_byteswap((d), (s), 8)
+#define FORB_CDR_swap16(d,s) forb_byteswap((d), (s), 16)
+
+inline CORBA_boolean
+FORB_CDR_put_short(FORB_CDR_Codec *codec, CORBA_short s)
+{
+ return FORB_CDR_buffer_put2(codec, &s);
+}
+
+inline CORBA_boolean
+FORB_CDR_get_short(FORB_CDR_Codec *codec, CORBA_short *s)
+{
+ return FORB_CDR_buffer_get2(codec, s);
+}
+
+inline CORBA_boolean
+FORB_CDR_put_ushort(FORB_CDR_Codec *codec, CORBA_unsigned_short us)
+{
+ return FORB_CDR_buffer_put2(codec, &us);
+}
+
+inline CORBA_boolean
+FORB_CDR_get_ushort(FORB_CDR_Codec *codec, CORBA_unsigned_short *us)
+{
+ return FORB_CDR_buffer_get2(codec, us);
+}
+
+inline CORBA_boolean
+FORB_CDR_put_long(FORB_CDR_Codec *codec, CORBA_long l)
+{
+ return FORB_CDR_buffer_put4(codec, &l);
+}
+
+inline CORBA_boolean
+FORB_CDR_get_long(FORB_CDR_Codec *codec, CORBA_long *l)
+{
+ return FORB_CDR_buffer_get4(codec, l);
+}
+
+inline CORBA_boolean
+FORB_CDR_put_ulong(FORB_CDR_Codec *codec, CORBA_unsigned_long ul)
+{
+ return FORB_CDR_buffer_put4(codec, &ul);
+}
+
+inline CORBA_boolean
+FORB_CDR_get_ulong(FORB_CDR_Codec *codec, CORBA_unsigned_long *ul)
+{
+ return FORB_CDR_buffer_get4(codec, ul);
+}
+
+//#ifdef HAVE_CORBA_LONG_LONG
+inline CORBA_boolean
+FORB_CDR_get_long_long(FORB_CDR_Codec *codec, CORBA_long_long *ul)
+{
+ return FORB_CDR_buffer_get8(codec, ul);
+}
+
+inline CORBA_boolean
+FORB_CDR_put_long_long(FORB_CDR_Codec *codec, CORBA_long_long ll)
+{
+ return FORB_CDR_buffer_put8(codec, &ll);
+}
+
+inline CORBA_boolean
+FORB_CDR_put_ulong_long(FORB_CDR_Codec *codec, CORBA_unsigned_long_long ll)
+{
+ return FORB_CDR_buffer_put8(codec, &ll);
+}
+
+inline CORBA_boolean
+FORB_CDR_get_ulong_long(FORB_CDR_Codec *codec, CORBA_unsigned_long_long *ull)
+{
+ return FORB_CDR_buffer_get8(codec, ull);
+}
+//#endif /* HAVE_CORBA_LONG_LONG */
+
+inline CORBA_boolean
+FORB_CDR_put_float(FORB_CDR_Codec *codec, CORBA_float f)
+{
+ return FORB_CDR_buffer_put4(codec, &f);
+}
+
+inline CORBA_boolean
+FORB_CDR_get_float(FORB_CDR_Codec *codec, CORBA_float *f)
+{
+ return FORB_CDR_buffer_get4(codec, f);
+}
+
+inline CORBA_boolean
+FORB_CDR_put_double(FORB_CDR_Codec *codec, CORBA_double d)
+{
+ return FORB_CDR_buffer_put8(codec, &d);
+}
+
+inline CORBA_boolean
+FORB_CDR_get_double(FORB_CDR_Codec *codec, CORBA_double *d)
+{
+ return FORB_CDR_buffer_get8(codec, d);
+}
+
+inline CORBA_boolean
+FORB_CDR_put_long_double(FORB_CDR_Codec *codec, CORBA_long_double ld)
+{
+ return FORB_CDR_buffer_put16(codec, &ld);
+}
+
+inline CORBA_boolean
+FORB_CDR_put_octet(FORB_CDR_Codec *codec, CORBA_octet datum)
+{
+ return FORB_CDR_buffer_put(codec, &datum);
+}
+
+inline CORBA_boolean
+FORB_CDR_get_octet(FORB_CDR_Codec *codec, CORBA_octet *datum)
+{
+ return(FORB_CDR_buffer_get(codec, datum));
+}
+
+inline CORBA_boolean
+FORB_CDR_put_octets(FORB_CDR_Codec *codec, void *data, unsigned long len)
+{
+ return FORB_CDR_buffer_puts(codec, data, len);
+}
+
+inline CORBA_boolean
+FORB_CDR_put_char(FORB_CDR_Codec *codec, CORBA_char c)
+{
+ return FORB_CDR_buffer_put(codec, &c);
+}
+
+inline CORBA_boolean
+FORB_CDR_get_char(FORB_CDR_Codec *codec, CORBA_char *c)
+{
+ return FORB_CDR_buffer_get(codec, c);
+}
+
+inline CORBA_boolean
+FORB_CDR_put_boolean(FORB_CDR_Codec *codec, CORBA_boolean datum)
+{
+ datum = datum&&1;
+ return FORB_CDR_buffer_put(codec, &datum);
+}
+
+inline CORBA_boolean
+FORB_CDR_get_boolean(FORB_CDR_Codec *codec, CORBA_boolean *b)
+{
+ return FORB_CDR_buffer_get(codec, b);
+}
+
+CORBA_boolean
+FORB_CDR_put_string(FORB_CDR_Codec *codec, const CORBA_char *str)
+{
+ unsigned int len;
+
+ if (str)
+ len=strlen(str)+1;
+ else
+ len=0;
+
+ if (FORB_CDR_put_ulong(codec, len)==CORBA_FALSE) return -1;
+ return FORB_CDR_buffer_puts(codec, str, len);
+}
+
+CORBA_boolean
+FORB_CDR_get_string_static(FORB_CDR_Codec *codec,CORBA_char **str)
+{
+ CORBA_unsigned_long len;
+
+ if(FORB_CDR_get_ulong(codec, (CORBA_unsigned_long *)&len)==CORBA_FALSE)
+ return CORBA_FALSE;
+
+ if((codec->rptr + len) > codec->buf_len)
+ return CORBA_FALSE;
+
+ *str = ((CORBA_char *)codec->buffer) + codec->rptr;
+
+ codec->rptr += len;
+
+ return CORBA_TRUE;
+}
+
+CORBA_boolean
+FORB_CDR_get_string(FORB_CDR_Codec *codec, CORBA_char **str)
+{
+ CORBA_unsigned_long len;
+
+ if(FORB_CDR_get_ulong(codec, (CORBA_unsigned_long *)&len)==CORBA_FALSE)
+ return(CORBA_FALSE);
+
+ if(len==0)
+ return(CORBA_FALSE);
+
+ *str=forb_malloc(len);
+
+ if(FORB_CDR_buffer_gets(codec, *str, len)==CORBA_FALSE) {
+ forb_free(*str);
+ return(CORBA_FALSE);
+ }
+
+ if((*str)[len-1]!='\0') {
+ (*str)[len-1]='\0';
+ }
+
+ return(CORBA_TRUE);
+}
+
+CORBA_boolean
+FORB_CDR_get_string_buff(FORB_CDR_Codec *codec, CORBA_char *str)
+{
+ CORBA_unsigned_long len;
+
+ if(FORB_CDR_get_ulong(codec, (CORBA_unsigned_long *)&len)==CORBA_FALSE)
+ return(CORBA_FALSE);
+
+ if(len==0)
+ return(CORBA_FALSE);
+
+ if(FORB_CDR_buffer_gets(codec, str, len)==CORBA_FALSE) {
+ return(CORBA_FALSE);
+ }
+
+ if(str[len-1]!='\0') {
+ str[len-1]='\0';
+ }
+
+ return(CORBA_TRUE);
+}
+
+CORBA_boolean
+FORB_CDR_get_seq_begin(FORB_CDR_Codec *codec, CORBA_unsigned_long *ul)
+{
+ return(FORB_CDR_get_ulong(codec, (CORBA_unsigned_long *)ul));
+}
+
+FORB_CDR_Codec *
+FORB_CDR_codec_init_static(FORB_CDR_Codec *codec, forb_orb orb)
+{
+ memset(codec, 0, sizeof(FORB_CDR_Codec));
+
+ codec->host_endian = FLAG_ENDIANNESS;
+ codec->data_endian = FLAG_ENDIANNESS;
+ codec->orb = orb;
+
+ return codec;
+}
+
+FORB_CDR_Codec *
+FORB_CDR_codec_init(forb_orb orb)
+{
+ FORB_CDR_Codec *c;
+
+ c=forb_malloc(sizeof(FORB_CDR_Codec));
+ if (c) {
+ FORB_CDR_codec_init_static(c, orb);
+ }
+
+ return(c);
+}
+
+void
+FORB_CDR_codec_release_buffer(FORB_CDR_Codec *codec)
+{
+ if(codec->release_buffer) {
+ forb_free(codec->buffer);
+ codec->release_buffer = CORBA_FALSE;
+ }
+}
+
+
+void
+FORB_CDR_codec_free(FORB_CDR_Codec *codec)
+{
+ FORB_CDR_codec_release_buffer(codec);
+ forb_free(codec);
+}
--- /dev/null
+/*
+ * $Id: cdr.h,v 0.0.0.1 2004/11/26
+ *
+ * -------------------------------------------------------------------
+ * ORTE
+ * Open Real-Time Ethernet
+ *
+ * Copyright (C) 2001-2006
+ * Department of Control Engineering FEE CTU Prague, Czech Republic
+ * http://dce.felk.cvut.cz
+ * http://www.ocera.org
+ *
+ * Author: Petr Smolik petr.smolik@wo.cz
+ * Advisor: Pavel Pisa
+ * Project Responsible: Zdenek Hanzalek
+ *
+ * Modified for FORB by Michal Sojka <sojkam1@fel.cvut.cz>, 2008
+ * --------------------------------------------------------------------
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Original of source was from ORBit: A CORBA v2.2 ORB
+ */
+/**
+ * @file cdr.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 16:55:44 2008
+ *
+ * @brief Handling of serialization/deserialization.
+ *
+ * Forked from ORTE project.
+ *
+ *
+ */
+#ifndef _FORB_CDR_H_
+#define _FORB_CDR_H_
+
+#include "basic_types.h"
+#include "cdr_codec.h"
+#include "object_type.h"
+
+/*
+ * Alignment of CORBA types mapped to C.
+ * These have *nothing* to do with CDR alignment.
+ */
+#define ORTE_ALIGNOF_CORBA_OCTET 1
+#define ORTE_ALIGNOF_CORBA_BOOLEAN 1
+#define ORTE_ALIGNOF_CORBA_CHAR 1
+#define ORTE_ALIGNOF_CORBA_WCHAR 2
+#define ORTE_ALIGNOF_CORBA_SHORT 2
+#define ORTE_ALIGNOF_CORBA_LONG 4
+#define ORTE_ALIGNOF_CORBA_LONG_LONG 8
+#define ORTE_ALIGNOF_CORBA_FLOAT 4
+#define ORTE_ALIGNOF_CORBA_DOUBLE 8
+#define ORTE_ALIGNOF_CORBA_LONG_DOUBLE 16
+#define ORTE_ALIGNOF_CORBA_STRUCT 1
+#define ORTE_ALIGNOF_CORBA_POINTER 4
+
+typedef enum {
+ BigEndian=0,
+ LittleEndian=1
+} FORB_CDR_Endianness;
+
+/**
+ * Codec used for serialization/deserialization
+ *
+ * @host_endian:
+ * @data_endian:
+ * @buffer: buffer for data
+ * @buf_len: buffer length
+ * @wptr_max: maximal size of writing data
+ * @wptr: write index
+ * @wptr_last: index of the data after the last written data
+ * @rptr: read index
+ * @readonly: readonly attribute
+ * @release_buffer: use CORBA_TRUE if is necessary to free buffer memory after destruction of structure
+ * @orb: Needed for deserialization of object references.
+ *
+ * Struct @FORB_CDR_Codec is used by serialization and deserialization functions.
+ */
+struct FORB_CDR_Codec {
+ FORB_CDR_Endianness host_endian;
+ FORB_CDR_Endianness data_endian;
+ CORBA_octet *buffer;
+ unsigned int buf_len;
+ unsigned int wptr_max;
+ unsigned int wptr;
+ unsigned int wptr_last;
+ unsigned int rptr;
+ CORBA_boolean readonly;
+ CORBA_boolean release_buffer;
+ forb_orb orb;
+};
+
+#define HEXDIGIT(c) (isdigit((guchar)(c))?(c)-'0':tolower((guchar)(c))-'a'+10)
+#define HEXOCTET(a,b) ((HEXDIGIT((a)) << 4) | HEXDIGIT((b)))
+
+static inline CORBA_long FORB_CDR_data_size(FORB_CDR_Codec *codec)
+{
+ return codec->wptr_last - codec->rptr;
+}
+
+extern CORBA_boolean FORB_CDR_buffer_init(FORB_CDR_Codec *codec, const unsigned int size, const unsigned int first);
+extern CORBA_boolean FORB_CDR_buffer_reset(FORB_CDR_Codec *codec, const unsigned int first);
+extern CORBA_boolean FORB_CDR_buffer_prepend(FORB_CDR_Codec *codec, const unsigned int len);
+extern FORB_CDR_Codec *FORB_CDR_codec_init(forb_orb orb);
+extern FORB_CDR_Codec *FORB_CDR_codec_init_static(FORB_CDR_Codec *codec, forb_orb orb);
+extern void FORB_CDR_codec_release_buffer(FORB_CDR_Codec *codec);
+extern void FORB_CDR_codec_free(FORB_CDR_Codec *);
+
+extern CORBA_boolean FORB_CDR_buffer_puts(FORB_CDR_Codec *codec, const void *data, const unsigned int len);
+extern CORBA_boolean FORB_CDR_buffer_gets(FORB_CDR_Codec *codec, void *dest, const unsigned int len);
+
+extern CORBA_boolean FORB_CDR_put_short(FORB_CDR_Codec *codec, CORBA_short s);
+extern CORBA_boolean FORB_CDR_put_ushort(FORB_CDR_Codec *codec, CORBA_unsigned_short us);
+extern CORBA_boolean FORB_CDR_put_long(FORB_CDR_Codec *codec, CORBA_long l);
+extern CORBA_boolean FORB_CDR_put_ulong(FORB_CDR_Codec *codec, CORBA_unsigned_long ul);
+/* #ifdef HAVE_CORBA_LONG_LONG */
+extern CORBA_boolean FORB_CDR_put_long_long(FORB_CDR_Codec *codec, CORBA_long_long ll);
+extern CORBA_boolean FORB_CDR_put_ulong_long(FORB_CDR_Codec *codec, CORBA_unsigned_long_long ull);
+extern CORBA_boolean FORB_CDR_get_ulong_long(FORB_CDR_Codec *codec, CORBA_unsigned_long_long *ul);
+extern CORBA_boolean FORB_CDR_get_long_long(FORB_CDR_Codec *codec, CORBA_long_long *ul);
+/* #endif */
+extern CORBA_boolean FORB_CDR_put_float(FORB_CDR_Codec *codec, CORBA_float f);
+extern CORBA_boolean FORB_CDR_put_double(FORB_CDR_Codec *codec, CORBA_double d);
+extern CORBA_boolean FORB_CDR_put_long_double(FORB_CDR_Codec *codec, CORBA_long_double ld);
+extern CORBA_boolean FORB_CDR_put_octet(FORB_CDR_Codec *codec, CORBA_octet datum);
+extern CORBA_boolean FORB_CDR_put_octets(FORB_CDR_Codec *codec, void *data, unsigned long len);
+extern CORBA_boolean FORB_CDR_put_char(FORB_CDR_Codec *codec, CORBA_char c);
+extern CORBA_boolean FORB_CDR_put_boolean(FORB_CDR_Codec *codec, CORBA_boolean datum);
+extern CORBA_boolean FORB_CDR_put_string(FORB_CDR_Codec *codec, const CORBA_char *str);
+extern CORBA_boolean FORB_CDR_buffer_gets(FORB_CDR_Codec *codec, void *dest, const unsigned int len);
+extern CORBA_boolean FORB_CDR_get_short(FORB_CDR_Codec *codec, CORBA_short *us);
+extern CORBA_boolean FORB_CDR_get_ushort(FORB_CDR_Codec *codec, CORBA_unsigned_short *us);
+extern CORBA_boolean FORB_CDR_get_long(FORB_CDR_Codec *codec, CORBA_long *l);
+extern CORBA_boolean FORB_CDR_get_ulong(FORB_CDR_Codec *codec, CORBA_unsigned_long *ul);
+extern CORBA_boolean FORB_CDR_get_octet(FORB_CDR_Codec *codec, CORBA_octet *datum);
+extern CORBA_boolean FORB_CDR_get_boolean(FORB_CDR_Codec *codec, CORBA_boolean *b);
+extern CORBA_boolean FORB_CDR_get_char(FORB_CDR_Codec *codec, CORBA_char *c);
+extern CORBA_boolean FORB_CDR_get_string(FORB_CDR_Codec *codec, CORBA_char **str);
+extern CORBA_boolean FORB_CDR_get_string_buff(FORB_CDR_Codec *codec, CORBA_char *str);
+extern CORBA_boolean FORB_CDR_get_string_static(FORB_CDR_Codec *codec, CORBA_char **str);
+extern CORBA_boolean FORB_CDR_get_seq_begin(FORB_CDR_Codec *codec, CORBA_unsigned_long *ul);
+extern CORBA_boolean FORB_CDR_get_float(FORB_CDR_Codec *codec, CORBA_float *f);
+extern CORBA_boolean FORB_CDR_get_double(FORB_CDR_Codec *codec, CORBA_double *d);
+
+extern CORBA_boolean FORB_CDR_put_align(FORB_CDR_Codec *codec, unsigned bsize);
+extern CORBA_boolean FORB_CDR_get_align(FORB_CDR_Codec *codec, unsigned bsize);
+
+
+/* serialization functions */
+#define CORBA_short_serialize(x,y) FORB_CDR_put_short((x),*(y))
+#define CORBA_long_serialize(x,y) FORB_CDR_put_long((x),*(y))
+#define CORBA_long_long_serialize(x,y) FORB_CDR_put_long_long((x),*(y))
+#define CORBA_unsigned_short_serialize(x,y) FORB_CDR_put_ushort((x),*(y))
+#define CORBA_unsigned_long_serialize(x,y) FORB_CDR_put_ulong((x),*(y))
+#define CORBA_unsigned_long_long_serialize(x,y) FORB_CDR_put_ulong_long((x),*(y))
+#define CORBA_float_serialize(x,y) FORB_CDR_put_float((x),*(y))
+#define CORBA_double_serialize(x,y) FORB_CDR_put_double((x),*(y))
+#define CORBA_char_serialize(x,y) FORB_CDR_put_char((x),*(y))
+#define CORBA_boolean_serialize(x,y) FORB_CDR_put_boolean((x),*(y))
+#define CORBA_octet_serialize(x,y) FORB_CDR_put_octet((x),*(y))
+#define CORBA_long_double_serialize(x,y) FORB_CDR_put_long_double((x),*(y))
+#define CORBA_string_serialize(x,y) FORB_CDR_put_string((x),*(y))
+
+/* deserialization functions */
+#define CORBA_short_deserialize(x,y) FORB_CDR_get_short((x),(y))
+#define CORBA_long_deserialize(x,y) FORB_CDR_get_long((x),(y))
+#define CORBA_long_long_deserialize(x,y) FORB_CDR_get_long_long((x),(y))
+#define CORBA_unsigned_short_deserialize(x,y) FORB_CDR_get_ushort((x),(y))
+#define CORBA_unsigned_long_deserialize(x,y) FORB_CDR_get_ulong((x),(y))
+#define CORBA_unsigned_long_long_deserialize(x,y) FORB_CDR_get_ulong_long((x),(y))
+#define CORBA_float_deserialize(x,y) FORB_CDR_get_float((x),(y))
+#define CORBA_double_deserialize(x,y) FORB_CDR_get_double((x),(y))
+#define CORBA_char_deserialize(x,y) FORB_CDR_get_char((x),(y))
+#define CORBA_boolean_deserialize(x,y) FORB_CDR_get_boolean((x),(y))
+#define CORBA_octet_deserialize(x,y) FORB_CDR_get_octet((x),(y))
+#define CORBA_long_double_deserialize(x,y) FORB_CDR_get_long_double((x),(y))
+#define CORBA_string_deserialize(x,y) FORB_CDR_get_string((x),(y))
+
+
+#endif /* !_FORB_CDR_H_ */
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file cdr_codec.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 16:53:47 2008
+ *
+ * @brief Definition of FORB_CDR_Codec type.
+ *
+ * The definition here is incomplete, which means we can use pointers
+ * to this type without having knowledge about internal structorue of
+ * this type.
+ */
+#ifndef FORB_CDR_CODEC_H
+#define FORB_CDR_CODEC_H
+
+typedef struct FORB_CDR_Codec FORB_CDR_Codec;
+
+#endif
--- /dev/null
+#include <forb.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/* Helper functions to "daemonize" forb servers. To make debugging
+ * easier, we do not detach from terminal. The idea behind daemonizing
+ * is to exit the parent when the server is ready to receive requests,
+ * so that is is not necessary to put delays between invocation of
+ * different servers. */
+
+static int daemon_pipe[2] = { 0, 0 };
+
+void forb_daemon_prepare(const char *pid)
+{
+ pid_t child;
+ int ret;
+ FILE *f;
+ char tmp;
+
+ ret = pipe(daemon_pipe);
+ if (ret) {
+ perror("pipe");
+ exit(1);
+ }
+ child = fork();
+ if (child == -1) {
+ perror("fork");
+ exit(1);
+ }
+ if (child > 0) {
+ close(daemon_pipe[1]);
+ ret = read(daemon_pipe[0], &tmp, 1);
+ if (pid) {
+ f = fopen(pid, "w");
+ if (f) {
+ fprintf(f, "%d\n", child);
+ fclose(f);
+ }
+ }
+ exit(ret > 0 ? 0 : 1);
+ } else {
+ close(daemon_pipe[0]);
+ }
+}
+
+/**
+ * Signal the parent that the daemon is ready so that the parent can
+ * exit().
+ */
+void forb_daemon_ready()
+{
+ if (daemon_pipe[1])
+ write(daemon_pipe[1], "", 1);
+}
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file discovery.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Wed May 27 19:28:30 2009
+ *
+ * @brief Discovery functions
+ *
+ */
+
+#include "discovery.h"
+#include <ul_log.h>
+#include "object.h"
+#include <forb/config.h>
+#include "iop.h"
+
+extern UL_LOG_CUST(ulogd_forb_discovery);
+
+GAVL_CUST_NODE_INT_DEC(forb_peer_nolock,/* cust_prefix */
+ forb_t, /* cust_root_t */
+ forb_peer_t, /* cust_item_t */
+ forb_server_id, /* cust_key_t */
+ peers, /* cust_root_node */
+ gnode, /* cust_item_node */
+ server_id, /* cust_item_key */
+ forb_server_id_cmp)/* cust_cmp_fnc */
+
+GAVL_CUST_NODE_INT_IMP(forb_peer_nolock,/* cust_prefix */
+ forb_t, /* cust_root_t */
+ forb_peer_t, /* cust_item_t */
+ forb_server_id, /* cust_key_t */
+ peers, /* cust_root_node */
+ gnode, /* cust_item_node */
+ server_id, /* cust_item_key */
+ forb_server_id_cmp);/* cust_cmp_fnc */
+
+int forb_discovery_init(forb_t *forb)
+{
+ if (fosa_mutex_init(&forb->peer_mutex, 0) != 0) return -1;
+ forb_peer_nolock_init_root_field(forb);
+
+ if (fosa_mutex_init(&forb->objkey_mutex, 0) != 0) return -1;
+ forb_objects_nolock_init_root_field(forb);
+ return 0;
+}
+
+static inline void
+forb_peer_insert(forb_t *forb, forb_peer_t *peer)
+{
+ fosa_mutex_lock(&forb->peer_mutex);
+ forb_peer_get(peer);
+ forb_peer_nolock_insert(forb, peer);
+ fosa_mutex_unlock(&forb->peer_mutex);
+}
+
+static inline void
+forb_peer_delete(forb_t *forb, forb_peer_t *peer)
+{
+ fosa_mutex_lock(&forb->peer_mutex);
+ forb_peer_nolock_delete(forb, peer);
+ forb_peer_put(peer);
+ fosa_mutex_unlock(&forb->peer_mutex);
+}
+
+/**
+ * Finds peer with given @a server_id.
+ *
+ * @param forb
+ * @param server_id
+ *
+ * @return The found peer or NULL if no peer is found. You have to
+ * call forb_peer_put() after you finish working with the non NULL
+ * retuned value.
+ */
+forb_peer_t *
+forb_peer_find(forb_t *forb, forb_server_id *server_id)
+{
+ forb_peer_t *ret;
+ fosa_mutex_lock(&forb->peer_mutex);
+ ret = forb_peer_nolock_find(forb, server_id);
+ if (ret) {
+ forb_peer_get(ret);
+ }
+ fosa_mutex_unlock(&forb->peer_mutex);
+ return ret;
+}
+
+/**
+ * Finds the peer with given @a server_id. If the peer is not
+ * currently known (not yet discovered or not available), this
+ * function waits at maximum @a timeout for the peer to be discovered.
+ *
+ * @param forb
+ * @param server_id
+ * @param timeout
+ *
+ * @return The peer structure or NULL if the peer is not known even
+ * after the timeout elapses.
+ *
+ * @note After the returned peer is not needed, forb_peer_put() must
+ * called on it.
+ */
+forb_peer_t *
+forb_peer_find_timed(forb_t *forb, forb_server_id *server_id,
+ fosa_abs_time_t *timeout)
+{
+ forb_peer_t *peer;
+ bool peer_allocated = false;
+
+ fosa_mutex_lock(&forb->peer_mutex);
+ peer = forb_peer_nolock_find(forb, server_id);
+ if (!peer && !timeout) goto unlock;
+ if (peer) {
+ forb_peer_get(peer);
+ } else {
+ /* We are the first who want to contact this peer */
+ peer = forb_peer_new();
+ if (!peer) goto unlock;
+ peer->server_id = *server_id;
+ peer->state = FORB_PEER_WANTED;
+ forb_peer_nolock_insert(forb, forb_peer_get(peer));
+ peer_allocated = true;
+ }
+ while (peer->state == FORB_PEER_WANTED) {
+ int ret;
+ /* Wait for the peer to be discovered. */
+ ret = fosa_cond_timedwait(&peer->cond,
+ &forb->peer_mutex,
+ timeout);
+ if (ret == FOSA_ETIMEDOUT) {
+ /* No peer discovered within timeout */
+ if (peer_allocated) {
+ forb_peer_nolock_delete(forb, peer);
+ forb_peer_put(peer);
+ }
+ forb_peer_put(peer);
+ peer = NULL;
+ break;
+ }
+ }
+unlock:
+ fosa_mutex_unlock(&forb->peer_mutex);
+
+ return peer;
+}
+
+/**
+ *
+ * @param port
+ * @param peer
+ * @param server_id
+ * @param addr
+ * @param orb_id
+ *
+ * @warning This function has to be called either from receiver thread
+ * of when the recevier thread is not running.
+ */
+void forb_new_peer_discovered(forb_port_t *port, forb_peer_t *peer,
+ forb_server_id server_id, void *addr,
+ CORBA_string orb_id)
+{
+ forb_t *forb = port->forb;
+ bool notify_waiters = false;
+ if (peer && peer->state == FORB_PEER_WANTED) {
+ notify_waiters = true;
+ } else if (!peer) {
+ peer = forb_peer_new();
+ }
+ if (!peer)
+ return;
+
+ fosa_mutex_lock(&forb->peer_mutex);
+ peer->server_id = server_id;
+ peer->port = port;
+ peer->addr = addr;
+ peer->orb_id = orb_id;
+ peer->state = FORB_PEER_DISCOVERED;
+ if (notify_waiters) {
+ fosa_cond_broadcast(&peer->cond);
+ } else {
+ forb_peer_nolock_insert(forb, forb_peer_get(peer));
+ }
+ forb_port_peer_ins_tail(port, forb_peer_get(peer));
+ fosa_mutex_unlock(&forb->peer_mutex);
+ {
+ char str[60];
+ ul_logdeb("new peer discovered %s (orb_id '%s')\n",
+ forb_server_id_to_string(str, &peer->server_id, sizeof(str)),
+ orb_id);
+ }
+#ifdef CONFIG_FORB_PROTO_INET_DEFAULT
+ if (forb->attr.redistribute_hellos) {
+ forb_peer_t *p;
+ ul_list_for_each(forb_port_peer, port, p) {
+ if (p != peer &&
+ forb_server_id_cmp(&p->server_id, &forb->server_id) != 0) {
+ forb_iop_redistribute_hello_to(p, peer); /* Introduce new peer to others */
+ forb_iop_redistribute_hello_to(peer, p); /* Introduce other peers to the new one */
+ }
+ }
+ }
+#endif
+ if (forb->attr.peer_discovery_callback) {
+ forb_orb peer_orb = forb_object_new(forb->orb, &peer->server_id, 0);
+ forb->attr.peer_discovery_callback(peer_orb, orb_id);
+ forb_object_release(peer_orb);
+ }
+ forb_peer_put(peer);
+
+ /* Broadcast our hello packet now */
+ forb_syncobj_signal(&port->hello);
+}
+
+/**
+ *
+ *
+ * @param peer
+ *
+ * @warning This function has to be called either from receiver thread
+ * of when the recevier thread is not running.
+ */
+void forb_peer_disconnected(forb_peer_t *peer)
+{
+ forb_peer_delete(peer->port->forb, peer);
+ forb_port_peer_delete(peer->port, peer);
+ forb_peer_put(peer); /* This should release the peer and in case on proto_inet close the socker. */
+}
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+#ifndef DISCOVERY_H
+#define DISCOVERY_H
+
+#include "peer.h"
+#include "port.h"
+
+int forb_discovery_init(forb_t *forb);
+
+void forb_new_peer_discovered(forb_port_t *port, forb_peer_t *peer,
+ forb_server_id server_id, void *addr,
+ CORBA_string orb_id);
+
+
+void forb_peer_disconnected(forb_peer_t *peer);
+
+forb_peer_t *
+forb_peer_find(forb_t *forb, forb_server_id *server_id);
+
+forb_peer_t *
+forb_peer_find_timed(forb_t *forb, forb_server_id *server_id,
+ fosa_abs_time_t *timeout);
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+/**
+ * @file exec_req.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 16:47:25 2008
+ *
+ * @brief Hanlding of requests in executors.
+ *
+ */
+
+#include "exec_req.h"
+#include "executor.h"
+#include <stdbool.h>
+#include "forb-internal.h"
+#include "object.h"
+#include "iop-idl.h"
+#include <ul_log.h>
+#include "iop.h"
+
+extern UL_LOG_CUST(ulogd_forb_exec_req);
+
+void forb_exec_req_process(forb_exec_req_t *exec_req)
+{
+ FORB_CDR_Codec reply_codec;
+ struct forb_env env;
+ const forb_skel_func *skeletons;
+ forb_t *forb = forb_object_to_forb(exec_req->obj);
+ CORBA_boolean ret;
+
+ FORB_CDR_codec_init_static(&reply_codec, exec_req->obj->orb);
+ ret = FORB_CDR_buffer_init(&reply_codec, 4096,
+ forb_iop_MESSAGE_HEADER_SIZE +
+ forb_iop_REPLY_HEADER_SIZE);
+ if (!ret) {
+ /* Without codec, we cannot send any reply so return silently. */
+ ul_logerr("No memory for reply buffer\n");
+ return;
+ }
+
+ env.major = FORB_EX_NONE;
+
+ /* Allow the implementation to know about request details
+ * (e.g. source). */
+ exec_req->obj->exec_req = exec_req;
+
+ /* Invoke the skeleton */
+ skeletons = exec_req->obj->interface->skeletons;
+ skeletons[exec_req->method_index](&exec_req->codec,
+ &reply_codec,
+ exec_req->obj,
+ &env);
+
+ forb_iop_send_reply(forb, &exec_req->source,
+ &reply_codec,
+ exec_req->request_id, &env);
+ FORB_CDR_codec_release_buffer(&reply_codec);
+ forb_exec_req_destroy(exec_req);
+}
+
+void forb_exec_req_ins_tail(forb_executor_t *executor,
+ forb_exec_req_t *exec_req)
+{
+ bool was_empty;
+ fosa_mutex_lock(&executor->mutex);
+ was_empty = forb_exec_req_nolock_is_empty(executor);
+ forb_exec_req_nolock_ins_tail(executor, exec_req);
+ if (was_empty) {
+ fosa_cond_signal(&executor->new_request_in_empty_list);
+ }
+ fosa_mutex_unlock(&executor->mutex);
+}
+
+void forb_exec_req_destroy(forb_exec_req_t *exec_req)
+{
+ forb_object_release(exec_req->obj);
+ FORB_CDR_codec_release_buffer(&exec_req->codec);
+ forb_free(exec_req);
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file exec_req.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 16:21:40 2008
+ *
+ * @brief Data type and functions prototypes for requests to executors.
+ *
+ *
+ */
+
+#ifndef FORB_EXEC_REQ_H
+#define FORB_EXEC_REQ_H
+
+#include <forb.h>
+#include <forb/cdr_codec.h>
+#include <forb/cdr.h>
+#include <ul_list.h>
+#include "executor.h"
+
+/**
+ * Request for ::forb_executor_t.
+ *
+ */
+typedef struct forb_exec_req {
+ unsigned request_id; /**< Request ID. Used to prepare reply message. */
+ forb_server_id source; /**< Source of this request. */
+ forb_object obj; /**< Object which is requested */
+ unsigned method_index; /**< Mehotd number to be invoked on the object @a obj. */
+ FORB_CDR_Codec codec; /**< Bufffer with serialized request parameters. */
+ ul_list_node_t node; /**< Node for forb_executor_t::requests. */
+} forb_exec_req_t;
+
+UL_LIST_CUST_DEC(forb_exec_req_nolock, /* cust_prefix */
+ forb_executor_t, /* cust_head_t */
+ forb_exec_req_t, /* cust_item_t */
+ requests, /* cust_head_field */
+ node); /* cust_node_field */
+
+
+void forb_exec_req_process(forb_exec_req_t *exec_req);
+
+void forb_exec_req_ins_tail(forb_executor_t *executor,
+ forb_exec_req_t *exec_req);
+void forb_exec_req_destroy(forb_exec_req_t *exec_req);
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file executor.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 16:18:04 2008
+ *
+ * @brief Implementation of executors.
+ */
+
+
+#include "executor.h"
+#include "exec_req.h"
+#include "object.h"
+#include <ul_log.h>
+
+extern UL_LOG_CUST(ulogd_forb_executor);
+
+/**
+ * Initializes executor.
+ *
+ * @param executor
+ *
+ * @return Zero on success, FOSA error code on error.
+ */
+int forb_executor_init(forb_executor_t *executor)
+{
+ int ret;
+ ret = fosa_mutex_init(&executor->mutex, 0);
+ if (ret) return ret;
+
+ ret = fosa_cond_init(&executor->new_request_in_empty_list);
+ if (ret) return ret;
+
+ forb_exec_req_nolock_init_head(executor);
+ return 0;
+}
+
+void forb_executor_destroy(forb_executor_t *executor)
+{
+ /* TODO: */
+}
+
+/**
+ * Setup the object @a obj so that requests to it are executed within
+ * the thread of the @a executor.
+ *
+ * @param executor
+ * @param obj
+ *
+ * @return Zero on success, non-zero on error.
+ */
+int forb_executor_register_object(forb_executor_t *executor, forb_object obj)
+{
+ if (!obj || obj->executor)
+ return -1;
+
+ obj->executor = executor;
+ return 0;
+}
+
+/**
+ * Unregisteres the object @a obj from @a executor.
+ *
+ * @param executor
+ * @param obj
+ */
+void forb_executor_unregister_object(forb_executor_t *executor, forb_object obj)
+{
+ if (obj) {
+ obj->executor = NULL;
+ }
+}
+
+/**
+ * Executor's main loop which executes object implementation methods
+ * upon request.
+ *
+ * The requests are represented by ::forb_exec_req_t and are enqueued
+ * to the executor's request queue by receiver threads of individual
+ * ports (forb_iop_receiver_thread()).
+ *
+ * @param executor
+ *
+ * @return Zero on normal termination, non-zero error codes will be
+ * defined later.
+ */
+int forb_executor_run(forb_executor_t *executor)
+{
+ fosa_mutex_lock(&executor->mutex);
+ while (1) {
+ fosa_cond_wait(&executor->new_request_in_empty_list,
+ &executor->mutex);
+ while (!forb_exec_req_nolock_is_empty(executor)) {
+ forb_exec_req_t *exec_req;
+ exec_req = forb_exec_req_nolock_cut_first(executor);
+ fosa_mutex_unlock(&executor->mutex);
+
+ forb_exec_req_process(exec_req);
+
+ fosa_mutex_lock(&executor->mutex);
+ }
+ }
+ fosa_mutex_unlock(&executor->mutex);
+ return 0;
+}
+
+/**
+ * Convenience function for executing only one object in one executor.
+ *
+ * @param obj The object to execute.
+ *
+ * @return Zero in case of success, error code on error.
+ */
+int forb_execute_object(forb_object obj)
+{
+ forb_executor_t executor;
+ int ret;
+
+ ret = forb_executor_init(&executor);
+ if (ret) goto error;
+ ret = forb_executor_register_object(&executor, obj);
+ if (ret) goto destroy_and_error;
+
+ ret = forb_executor_run(&executor);
+
+destroy_and_error:
+ forb_executor_destroy(&executor);
+error:
+ return ret;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+/**
+ * @file executor.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 16:19:24 2008
+ *
+ * @brief Executor type and prototypes.
+ *
+ *
+ */
+
+#ifndef EXECUTOR_H
+#define EXECUTOR_H
+
+#include <fosa.h>
+#include <ul_list.h>
+#include <forb/object_type.h>
+
+/**
+ * Executor structure.
+ *
+ * Executors provide a way for applications to determine which thread
+ * will execute requests for a particular object. After the executor
+ * structure is initialized by forb_executor_init(), several objects
+ * can be registered to it by forb_executor_register_object(). Then a
+ * loop which waits for requests and executes them by calling object
+ * implementations is started by forb_executor_run().
+ */
+typedef struct forb_executor {
+ fosa_mutex_t mutex; /**< Mutex for protecting forb_executor_t::requests. */
+ fosa_cond_t new_request_in_empty_list; /**< Signaled when a request was added to the empty list. */
+ ul_list_head_t requests; /**< List of pending requests for this executor. */
+} forb_executor_t;
+
+int forb_executor_init(forb_executor_t *executor);
+void forb_executor_destroy(forb_executor_t *executor);
+int forb_executor_register_object(forb_executor_t *executor, forb_object obj);
+void forb_executor_unregister_object(forb_executor_t *executor, forb_object obj);
+int forb_executor_run(forb_executor_t *executor);
+
+int forb_execute_object(forb_object obj);
+
+
+#endif
--- /dev/null
+/**
+ * @file forb-idl.idl
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Mon Oct 13 13:41:54 2008
+ *
+ * @brief Remote interface for FORB
+ *
+ */
+
+
+module forb {
+ /**
+ * Remote interface for FORB obejcts
+ *
+ * Every FORB provides this interface to remote forbs so that
+ * other FORBs can obtain information about other FORBs.
+ */
+ interface orb {
+ void is_alive(); /**< Empty function intended to check whether the FORB is active or not. */
+ };
+};
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file forb-internal.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ *
+ * @brief Declarationd necessary for IDL-generated code and other parts of FORB.
+ *
+ * This header is not intended to be included by applications.
+ *
+ */
+
+#ifndef FORB_INTERNAL_H
+#define FORB_INTERNAL_H
+
+#include <forb/basic_types.h>
+#include <forb/cdr.h>
+#include <forb.h>
+#include <forb/uuid.h>
+#include <ul_list.h>
+#include <ul_gavlcust.h>
+#include <forb.h>
+#include <string.h>
+#include <forb/server_id.h>
+
+
+/**
+ * Temporary directory for FORB's housekeeping.
+ *
+ * It is used for proto_unix.c sockets and for registered references
+ * (forb_register_reference()).
+ */
+#define FORB_TMP_DIR "/tmp/forb"
+
+#define FORB_METHOD_INDEX(m) (m ## __method_index)
+
+/**
+ * Internal data of every FORB instance.
+ *
+ */
+typedef struct forb {
+ forb_server_id server_id;
+ char server_id_str[sizeof(forb_server_id)*2+1]; /**< Server ID string - for easier debuggin messages */
+ forb_orb orb; /**< Object reference of this forb */
+
+ forb_init_attr_t attr; /**< Initialization attributes */
+
+ fosa_mutex_t request_id_mutex; /**< Mutex for request_id */
+ CORBA_long request_id; /**< Value of next sent request_id */
+
+ fosa_mutex_t objkey_mutex; /**< Mutex for objkey and objects */
+ forb_object_key objkey; /**< Objkey value of last created object */
+ gavl_cust_root_field_t objects; /**< Tree of objects registered with this FORB. */
+
+ //forb_rt rt; /**< Routing table */
+ //gavl_cust_root_field_t types;
+
+ fosa_mutex_t request_mutex; /**< Mutex for requests */
+ gavl_cust_root_field_t requests; /**< Container for ::forb_request_t */
+
+ fosa_mutex_t port_mutex;
+ ul_list_head_t ports; /**< Container for ::forb_port_t */
+
+ fosa_mutex_t peer_mutex; /**< Mutex for @a peers */
+ gavl_cust_root_field_t peers; /**< Container for ::forb_peer_t */
+
+ fosa_mutex_t regref_mutex;
+ gavl_cust_root_field_t regrefs; /**< Container for ::forb_regref_t */
+
+ fosa_thread_id_t execution_thread; /**< Thread which executes remote requests for this forb::orb interface. */
+} forb_t;
+
+typedef void (*forb_skel_func)(FORB_CDR_Codec *cin,
+ FORB_CDR_Codec *cout,
+ struct _forb_object *obj,
+ struct forb_env *env);
+
+
+int
+forb_init_tmp_dir(void);
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file forb.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 16:57:01 2008
+ *
+ * @brief Implementation of basic FORB's functions.
+ *
+ *
+ */
+
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE /* Because of on_exit() */
+#endif
+#include "proto.h"
+#include "regref.h"
+#include <forb/config.h>
+#include <forb/forb-internal.h>
+#include <forb.h>
+#include "forb-idl.h"
+#include <forb/iop.h>
+#include <forb/object.h>
+#include <forb/uuid.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <ul_gavlcust.h>
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <unistd.h>
+#include "discovery.h"
+#ifdef CONFIG_FORB_PROTO_UNIX
+#include <forb/proto_unix.h>
+#endif
+#ifdef CONFIG_FORB_PROTO_INET_DEFAULT
+#include <forb/proto_inet.h>
+#endif
+#ifdef CONFIG_FCB
+#include <fcb.h>
+#include <fcb_contact_info.h>
+#endif
+#include <fcntl.h>
+
+#ifdef DEBUG
+#define UL_LOGL_DEF UL_LOGL_DEB
+#else
+#define UL_LOGL_DEF UL_LOGL_ERR
+#endif
+#include "log_domains.inc"
+
+extern UL_LOG_CUST(ulogd_forb);
+static int init_ul_log(void);
+
+UL_LOGREG_DOMAINS_INIT_FUNCTION(forb_logreg_domains, forb_logreg_domains_array);
+
+#if 0
+static void
+destroy_forb_on_exit(int exitcode, void *arg)
+{
+ forb_orb orb = arg;
+ forb_destroy(orb);
+}
+#endif
+
+static void
+forb_is_alive(forb_orb _obj, CORBA_Environment *ev)
+{
+ ul_logdeb("%s called\n", __FUNCTION__);
+}
+
+static struct forb_forb_orb_impl forb_implementation = {
+ .is_alive = forb_is_alive,
+};
+
+/**
+ * Prepares #FORB_TMP_DIR directory for use by forb
+ *
+ * @return Zero on succes, -1 on error and errno is set appropriately.
+ */
+int
+forb_init_tmp_dir(void)
+{
+ struct stat st;
+ int ret;
+
+ ret = stat(FORB_TMP_DIR, &st);
+
+ if (ret == 0 && !S_ISDIR(st.st_mode)) {
+ ret = unlink(FORB_TMP_DIR);
+ if (ret) return -1;
+ } else if (ret == 0) {
+ return 0;
+ }
+ return mkdir(FORB_TMP_DIR, 0777);
+}
+
+/**
+ * Thread for execution of remote requests for a FORB object.
+ *
+ * @param arg
+ *
+ * @return
+ */
+static void *
+forb_execution_thread(void *arg)
+{
+ forb_orb orb = arg;
+
+ forb_execute_object(orb);
+ return NULL;
+}
+
+#ifdef CONFIG_FCB
+void hack_register_fcb(forb_orb orb, forb_port_t *port)
+{
+ forb_object fcb = forb_object_new(orb, &FCB_SERVER_ID, 1);
+ if (!fcb) {
+ ul_logerr("Cannot allocate FCB reference\n");
+ return;
+ }
+ forb_register_reference(fcb, fres_contract_broker_reg_name);
+ forb_object_release(fcb);
+}
+#else
+#define hack_register_fcb(orb)
+#endif
+
+
+
+forb_orb
+forb_init(int *argc, char **argv[], const struct forb_init_attr *attr)
+{
+ forb_orb orb;
+ forb_t *forb;
+ int ret;
+
+ forb = forb_malloc(sizeof(*forb));
+ if (!forb) goto err;
+ memset(forb, 0, sizeof(*forb));
+
+ /* Initialize ULUT logging facility */
+ init_ul_log();
+ forb_logreg_domains();
+
+ if (attr) {
+ forb->attr = *attr;
+ } else {
+ memset(&forb->attr, 0, sizeof(forb->attr));
+ }
+
+ if (forb_server_id_empty(&forb->attr.fixed_server_id)) {
+ forb_server_id_init(&forb->server_id);
+ } else {
+ forb->server_id = forb->attr.fixed_server_id;
+ }
+ forb_server_id_to_string(forb->server_id_str, &forb->server_id,
+ sizeof(forb->server_id_str));
+ ul_logdeb("Initializing forb %s\n", forb->server_id_str);
+
+ if (fosa_mutex_init(&forb->request_id_mutex, 0) != 0) goto err2;
+ if (fosa_mutex_init(&forb->port_mutex, 0) != 0) goto err2;
+ forb_port_init_head(forb);
+
+ if (fosa_mutex_init(&forb->request_mutex, 0) != 0) goto err2;
+ forb_request_nolock_init_root_field(forb);
+
+ if (forb_discovery_init(forb) != 0) goto err2;
+
+ if (fosa_mutex_init(&forb->regref_mutex, 0) != 0) goto err2;
+ forb_regref_nolock_init_root_field(forb);
+
+ ret = forb_init_tmp_dir();
+ if (ret != 0) {
+ ul_logerr("Cannot prepare " FORB_TMP_DIR "\n");
+ return NULL;
+ }
+
+ orb = forb_forb_orb_new(NULL, &forb_implementation, forb);
+ if (!orb) goto err2;
+ /* Server ID must be assigned manualy */
+ orb->server = forb->server_id;
+
+ forb->orb = orb;
+
+ /* Insert our object reference to objects tree, so that we
+ * can accept remote request to our new ORB. */
+ forb_objects_nolock_insert(forb, orb);
+
+ ret = fosa_thread_create(&forb->execution_thread, NULL,
+ forb_execution_thread, orb);
+ if (ret != 0)
+ goto err2;
+
+ /* FIXME: I do not know how to deregister the exit handler if
+ * forb_destroy() is called manually. */
+ /* on_exit(destroy_forb_on_exit, orb); */
+
+#ifdef CONFIG_FORB_PROTO_UNIX
+ {
+ forb_port_t *port = forb_malloc(sizeof(*port));
+ if (port) {
+ memset(port, 0, sizeof(*port));
+ ret = forb_unix_port_init(&port->desc, &forb->server_id);
+ if (ret) goto err_free_unix;
+ ret = forb_register_port(orb, port);
+ if (ret) goto err_free_unix; /* TODO: forb_unix_port_done() */
+ goto unix_ok;
+ }
+ err_free_unix:
+ free(port);
+ goto err2;
+ unix_ok:;
+ }
+#endif
+#ifdef CONFIG_FORB_PROTO_INET_DEFAULT
+ {
+ forb_port_t *port = forb_malloc(sizeof(*port));
+ if (port) {
+ struct in_addr listen_on;
+
+ memset(port, 0, sizeof(*port));
+ listen_on.s_addr = INADDR_ANY;
+ ret = forb_inet_port_init(&port->desc, listen_on,
+ forb->attr.fixed_tcp_port);
+ if (ret) goto err_free_inet;
+ ret = forb_register_port(orb, port);
+ if (ret) goto err_free_inet; /* TODO: forb_inet_port_done() */
+ goto inet_ok;
+ }
+ err_free_inet:
+ free(port);
+ goto err2;
+ inet_ok:;
+ hack_register_fcb(orb, port);
+ }
+#endif
+ return orb;
+
+err2: forb_free(forb);
+err: return NULL;
+}
+
+void forb_destroy(forb_orb orb)
+{
+ forb_t *forb = forb_object_to_forb(orb);
+ forb_port_t *port;
+ forb_regref_t *regref;
+
+ pthread_cancel(forb->execution_thread.pthread_id);
+ pthread_join(forb->execution_thread.pthread_id, NULL);
+
+ /* Unregister all registered references */
+ while ((regref = forb_regref_first(forb))) {
+ forb_unregister_reference(orb, regref->name.str);
+ }
+
+ ul_list_for_each_cut(forb_port, forb, port) {
+ forb_destroy_port(port);
+ }
+ forb_object_release(orb);
+ forb_free(forb);
+}
+
+/* void */
+/* forb_register_interface(const struct forb_interface *interface) */
+/* { */
+/* gavl_insert(&type_registry, &interface->node); */
+/* } */
+
+/**
+ * Initializes server ID variable.
+ *
+ * @param server_id Serer ID to initialize.
+ */
+void
+forb_server_id_init(forb_server_id *server_id)
+{
+ forb_uuid_generate((forb_uuid_t*)server_id->uuid);
+}
+
+/**
+ * Checks whether the @a object is stale. Stale object is an object
+ * reference whose server cannot be contacted to handle requests.
+ *
+ * @param object Object reference to check.
+ *
+ * @return True if the object is stale, false otherwise.
+ */
+bool forb_object_is_stale(forb_object object)
+{
+ forb_orb remote_orb;
+ struct forb_env env;
+ bool stale = true;
+
+ remote_orb = forb_get_orb_of(object);
+ if (!remote_orb) { /* This shohuld never happen */
+ goto err;
+ }
+ /* TODO: Check not only the ORB, but also whether the object
+ * is still registered with the remote orb. */
+ forb_orb_is_alive(remote_orb, &env);
+ if (env.major == FORB_EX_COMM_FAILURE) {
+ /* Orb is not alive */
+ stale = true;
+ } else {
+ if (forb_exception_occurred(&env)) {
+ ul_logerr("%s: unexpected exception: %s\n", __FUNCTION__, forb_strerror(&env));
+ }
+ stale = false;
+ }
+
+ forb_object_release(remote_orb);
+err:
+ return stale;
+}
+
+
+/**
+ * Returns object reference of forb::orb object associated with the
+ * given object.
+ *
+ * @param obj
+ *
+ * @return
+ */
+forb_orb
+forb_get_orb_of(const forb_object obj)
+{
+ forb_orb orb;
+
+ if (forb_server_id_cmp(&obj->server, &obj->orb->server) == 0) {
+ orb = forb_object_duplicate(obj->orb);
+ } else {
+ orb = forb_object_new(obj->orb, &obj->server, 0);
+ }
+ return orb;
+}
+
+/**
+ * Returns server ID of an object reference.
+ *
+ * @param obj
+ * @param dest
+ */
+void
+forb_get_server_id(const forb_object obj, forb_server_id *dest)
+{
+ if (obj) {
+ *dest = obj->server;
+ }
+}
+
+
+/**
+ * Return instance data registered when the object was created by
+ * forb_XXX_new().
+ *
+ * @param obj Object reference
+ *
+ * @return Pointer to the registered data.
+ */
+void *
+forb_instance_data(const forb_object obj)
+{
+ return forb_object_instance_data(obj);
+}
+
+/**
+ * Returns error message correspondings FORB exception.
+ *
+ * @param env Environemnt
+ *
+ * @return Non-NULL pointer to a string.
+ */
+const char *
+forb_strerror(CORBA_Environment *env)
+{
+ if (!env) {
+ return "Invalid environemnt";
+ }
+#define ex(e) case FORB_EX_##e: return #e; break;
+ switch (env->major) {
+ ex(NONE);
+ ex(UNKNOWN);
+ ex(BAD_PARAM);
+ ex(NO_MEMORY);
+ ex(IMP_LIMIT);
+ ex(COMM_FAILURE);
+ ex(INV_OBJREF);
+ ex(NO_PERMISSION);
+ ex(INTERNAL);
+ ex(MARSHAL);
+ ex(INITIALIZE);
+ ex(NO_IMPLEMENT);
+ ex(BAD_OPERATION);
+ ex(NO_RESOURCES);
+ ex(NO_RESPONSE);
+ ex(TRANSIENT);
+ ex(FREE_MEM);
+ ex(INV_IDENT);
+ ex(INV_FLAG);
+ ex(DATA_CONVERSION);
+ ex(OBJECT_NOT_EXIST);
+ ex(TIMEOUT);
+ ex(APPLICATION);
+ }
+#undef ex
+ return "Invalid error number";
+}
+
+/**
+ * Return server id of the requesting application.
+ *
+ * This function should be only called from within interface
+ * implementation,
+ *
+ * @param[in] obj Object being requested
+ * @param[out] req_source Server ID of the requesting application
+ */
+void
+forb_get_req_source(const forb_object obj, forb_server_id *req_source)
+{
+ if (req_source) {
+ if (obj && obj->exec_req) {
+ *req_source = obj->exec_req->source;
+ } else {
+ memset(req_source, 0, sizeof(*req_source));
+ }
+ }
+}
+
+/**
+ * Internal function for allocation of sequence bufers. Used by
+ * forb_sequence_alloc_buf().
+ *
+ * @param seq
+ * @param seq_size
+ * @param buf_pptr
+ * @param maximum_ptr
+ * @param num_elements
+ * @param elem_size
+ *
+ * @return CORBA_TRUE if the allocation was sucessfull, CORBA_FALSE if
+ * it wasn't.
+ */
+CORBA_boolean
+__forb_sequence_alloc_buf_internal(void *seq, size_t seq_size,
+ void **buf_pptr, CORBA_unsigned_long *maximum_ptr,
+ unsigned num_elements, size_t elem_size)
+{
+ memset(seq, 0, seq_size);
+ /*(seq)._length = 0;*/
+ if (num_elements && elem_size) *buf_pptr = forb_malloc(num_elements * elem_size);
+ else *buf_pptr = NULL;
+ *maximum_ptr = *buf_pptr ? num_elements : 0;
+ return (*buf_pptr != NULL) || (num_elements == 0);
+}
+
+static FILE *forb_ul_log_file;
+static char progname[64] = "";
+
+void
+forb_ul_log_fnc(ul_log_domain_t *domain, int level,
+ const char *format, va_list ap)
+{
+ struct timespec now;
+ if(!(level&UL_LOGL_CONT)) {
+ level&=UL_LOGL_MASK;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ fprintf(forb_ul_log_file,"%ld.%6ld: ", now.tv_sec, now.tv_nsec/1000);
+ if (progname[0])
+ fprintf(forb_ul_log_file,"%s: ", progname);
+ if(domain && domain->name)
+ fprintf(forb_ul_log_file,"%s: ",domain->name);
+ }
+ vfprintf(forb_ul_log_file, format, ap);
+ fflush(forb_ul_log_file);
+}
+
+static int init_ul_log(void)
+{
+ char *s;
+ char *log_fname;
+ int fd;
+ int flg = 0;
+ char path[128];
+
+/* if(ul_log_output != NULL) */
+/* return 0; */
+
+ fd = open("/proc/self/cmdline", O_RDONLY);
+ if (fd >= 0) {
+ int ret;
+ ret = read(fd, path, sizeof(path)-1);
+ if (ret > 0) {
+ path[ret]=0;
+ s = strrchr(path, '/');
+ if (s) s++;
+ else s = path;
+ strncpy(progname, s, sizeof(progname)-1);
+ }
+ close(fd);
+ }
+
+ if((log_fname=getenv("UL_LOG_FILENAME"))!=NULL){
+ forb_ul_log_file=fopen(log_fname,"a");
+ }
+ if(forb_ul_log_file==NULL)
+ forb_ul_log_file=stderr;
+
+ if((s=getenv("UL_DEBUG_FLG")) != NULL){
+ flg=atoi(s);
+ }
+
+ ul_log_redir(forb_ul_log_fnc, flg);
+
+ if((s = getenv("UL_LOG_LEVELS")) != NULL)
+ ul_log_domain_arg2levels(s);
+
+ return 0;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file forb.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Fri Aug 29 09:37:27 2008
+ *
+ * @brief Public interface to FORB. To be used by applications (both servers and clients).
+ *
+ *
+ */
+
+/**
+@mainpage
+
+@section Introduction
+
+FORB is a CORBA-like middleware build on top of FOSA (FRESCOR
+Operating System Adaptation). Its main purpose is to provide unified
+in-process, inter-process and inter-node communication mechanism
+needed for implementation of FRESCOR in modular way. FORB is heavily
+inspired by CORBA, but provides only a very limited number of CORBA
+features.
+
+FORB supports one communication primitive, which is synchronous call
+of a remote method. This operation is mapped to a local function call,
+so that programmer cannot see the difference between the local and
+remote invocation. FORB implements all of the operations needed for
+such kind of communication which is:
+
+- serialization and deserialization of parameters and return values,
+- communication protocol to pass requests and replies between
+ processes,
+- finding the process, where the remote operation is implemented.
+
+FORB is composed of the two following components:
+- IDL compiler (called @c forb-idl) and
+- FORB runtime represented by @c libforb library.
+
+This documentation documents the @c libforb library. The IDL compiler
+is derived form Orbit project, and its documentation is out of scope
+of this document.
+
+@section Compilation
+
+See README file.
+
+@section Usage
+
+To use FORB in an application, an IDL (Interface Description Language)
+file has to be created first. This IDL file describes the interfaces
+used in the the application, their methods, parameters and types. The
+IDL language is similar to a subset of C language and is defined in <a
+href="http://www.omg.org/spec/CORBA/3.1/Interfaces/PDF/">OMG CORBA
+specification version 3.1, part 1</a> (chapter 7: OMG IDL Syntax and
+Semantics).
+
+An example IDL file called @c myinterface.idl can look like this:
+@include tests-idl/myinterface.idl
+
+It defines the interface called @c myinterface and some other
+(non-basic) types used in interface methods. To implement this
+interface, we process this file with the IDL compiler:
+
+\verbatim
+$ forb-idl myinterface.idl
+\endverbatim
+
+It generates four files: @c myinterface.h, @c myinterface-stubs.c, @c
+myinterface-skels.c and @c myinterface-common.c.
+
+The code of a server which implements the first two methods of this
+interface could look like this:
+
+@include tests-idl/example_server.c
+
+We have to compile this file and link it with @c -skels.c and @c
+-common.c files and the following libraries (under Linux): forb fosa
+pthread rt ulut.
+
+The client code which uses our implementation of @c myinterface could
+look like this:
+
+@include tests-idl/example_client.c
+
+It has to be compiled and linked with @c myinterface-stubs.c and @c
+myinterface-common.c files and with the following libraries (under
+Linux): forb fosa pthread rt ulut.
+
+Note that in these examples we intentionally skipped checking for
+errors to achieve more readable code.
+*/
+
+
+#ifndef FORB_H
+#define FORB_H
+
+#include <forb/forb-idl.h>
+#include <forb/basic_types.h>
+#include <fosa.h>
+#include <forb/types.h>
+#include <forb/executor.h>
+#include <forb/object_type.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Incomplete types - declared in forb-internal.h */
+struct forb_interface;
+typedef struct forb_interface forb_interface_t;
+
+typedef struct forb_init_attr {
+ const char *orb_id; /**< Name of the FORB used for debugging purposes */
+ void (*peer_discovery_callback)(const forb_orb peer_orb, const char *orb_id);
+ void (*peer_dead_callback)(const forb_orb peer_orb, const char *orb_id);
+ uint16_t fixed_tcp_port; /**< If we want FORB's inet protocol to listen on a fixed port... */
+ forb_server_id fixed_server_id; /**< If we do not want the ID to be random. (HACK) */
+ bool redistribute_hellos;
+
+} forb_init_attr_t;
+
+/**
+ * Initializes FORB. This function has to be called before any other
+ * FORB function.
+ *
+ * Any command line arguments used by FORB are removed from the array
+ * and @a argc and @a argv are updated accordingly.
+ *
+ * @param argc a pointer to the number of command line arguments.
+ * @param argv a pointer to the array of command line arguments.
+ * @param attr attributes that control FORB initialization.
+ *
+ * @return FORB object reference of NULL in case of error.
+ */
+forb_orb forb_init(int *argc, char **argv[], const forb_init_attr_t *attr);
+
+/**
+ * Deallocates all resources consumed by FORB.
+ *
+ * @note Called automatically on application exit.
+ *
+ * @param orb FORB object reference to destroy.
+ */
+void forb_destroy(forb_orb orb);
+
+void
+forb_object_release(forb_object obj);
+
+forb_object
+forb_object_duplicate(const forb_object obj);
+
+void *
+forb_instance_data(const forb_object obj);
+
+int
+forb_register_reference(forb_object object, const char *name);
+
+int
+forb_unregister_reference(forb_orb orb, const char *name);
+
+forb_object
+forb_resolve_reference(const forb_orb orb, const char *name);
+
+forb_object
+forb_string_to_object(const forb_orb orb, const char *string);
+
+char *
+forb_object_to_string(const forb_object obj);
+
+bool forb_object_is_stale(forb_object object);
+
+forb_orb
+forb_get_orb_of(const forb_object obj);
+
+void
+forb_get_server_id(const forb_object obj, forb_server_id *dest);
+
+void
+forb_get_req_source(const forb_object obj, forb_server_id *req_source);
+
+const char *
+forb_strerror(CORBA_Environment *env);
+
+void
+forb_daemon_prepare(const char *pid);
+
+void
+forb_daemon_ready();
+
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+#ifndef FORB_ENDIAN_H
+#define FORB_ENDIAN_H 1
+
+#include <endian.h>
+#ifdef __BYTE_ORDER
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define WORDS_BIGENDIAN 1
+#endif
+#endif
+
+
+#define FLAG_BIG_ENDIAN 0
+#define FLAG_LITTLE_ENDIAN 1
+
+#if WORDS_BIGENDIAN
+
+# define FLAG_ENDIANNESS FLAG_BIG_ENDIAN
+# define conversion_needed(to_endianness) ((to_endianness)!=FLAG_BIG_ENDIAN)
+
+#else
+
+# define FLAG_ENDIANNESS FLAG_LITTLE_ENDIAN
+# define conversion_needed(to_endianness) ((to_endianness)!=FLAG_LITTLE_ENDIAN)
+
+#endif
+
+static inline
+void forb_byteswap(uint8_t *outdata,
+ const uint8_t *data,
+ uint32_t datalen)
+{
+ const uint8_t *source_ptr = data;
+ uint8_t *dest_ptr = outdata + datalen - 1;
+ while(dest_ptr >= outdata)
+ *dest_ptr-- = *source_ptr++;
+}
+
+
+#endif /* FLAG_ENDIANNESS */
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file forb_utils.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 16:59:57 2008
+ *
+ * @brief Miscellaneous FORB utilites.
+ *
+ *
+ */
+
+#ifndef FORB_UTILS_H
+#define FORB_UTILS_H
+
+#include <stdlib.h>
+
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
+/**
+ * Cast a member of a structure out to the containing structure.
+ *
+ * @param ptr the pointer to the member.
+ * @param type the type of the container struct this is embedded in.
+ * @param member the name of the member within the struct.
+ */
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
+
+#endif
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------------------- //
+// Copyright (C) 2006 - 2008 FRESCOR consortium partners: //
+// //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// Scuola Superiore Sant'Anna, ITALY //
+// Kaiserslautern University, GERMANY //
+// Univ. Politécnica Valencia, SPAIN //
+// Czech Technical University in Prague, CZECH REPUBLIC //
+// ENEA SWEDEN //
+// Thales Communication S.A. FRANCE //
+// Visual Tools S.A. SPAIN //
+// Rapita Systems Ltd UK //
+// Evidence ITALY //
+// //
+// See http://www.frescor.org for a link to partners' websites //
+// //
+// FRESCOR project (FP6/2005/IST/5-034026) is funded //
+// in part by the European Union Sixth Framework Programme //
+// The European Union is not liable of any use that may be //
+// made of this code. //
+// //
+// //
+// This file is part of FORB (Frescor Object Request Broker) //
+// //
+// FORB is free software; you can redistribute it and/or modify it //
+// under terms of the GNU General Public License as published by the //
+// Free Software Foundation; either version 2, or (at your option) any //
+// later version. FORB is distributed in the hope that it will be //
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty //
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
+// General Public License for more details. You should have received a //
+// copy of the GNU General Public License along with FORB; see file //
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, //
+// Cambridge, MA 02139, USA. //
+// //
+// As a special exception, including FORB header files in a file, //
+// instantiating FORB generics or templates, or linking other files //
+// with FORB objects to produce an executable application, does not //
+// by itself cause the resulting executable application to be covered //
+// by the GNU General Public License. This exception does not //
+// however invalidate any other reasons why the executable file might be //
+// covered by the GNU Public License. //
+////////////////////////////////////////////////////////////////////////////
+
+#include "types.idl"
+
+/**
+ * @file iop-idl.idl
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 16:52:08 2008
+ *
+ * @brief Definitions for FORB's IOP (Inter-ORB protocol).
+ *
+ *
+ */
+
+
+/// FORB namespace
+module forb {
+ /// Inter-ORB protocol namespace
+ module iop {
+
+ typedef octet message_type;
+
+ const message_type REQUEST = 0;
+ const message_type REPLY = 1;
+ const message_type HELLO = 2;
+
+ /// Version of FORB IOP protocol
+ struct version {
+ octet major, minor;
+ };
+
+ typedef octet message_flags;
+
+ const message_flags LITTLE_ENDIAN = 1;
+
+ /// Common header of all FORB IOP messages
+ struct message_header {
+ version proto_version;
+ message_type message_type;
+ message_flags flags;
+ unsigned long message_size;
+ };
+ const long MESSAGE_HEADER_SIZE = 8;
+
+ /// Header of REQUEST message
+ struct request_header {
+ unsigned long request_id;
+ string iface;
+ object_key objkey;
+ short method_index;
+ server_id source; ///< Server ID of request originator
+ };
+
+ typedef unsigned short reply_flags;
+ const reply_flags FLAG_EXCEPTION = 1;
+ /// Header of REPLY message
+ struct reply_header {
+ unsigned long request_id;
+ reply_flags flags;
+ };
+ const long REPLY_HEADER_SIZE = 8;
+ };
+};
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file iop.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Mon Sep 1 21:51:58 2008
+ *
+ * @brief Implementation of Inter-ORB protocol.
+ *
+ *
+ */
+#include "iop.h"
+#include <forb/cdr.h>
+#include <forb/object.h>
+#include "proto.h"
+#include <ul_log.h>
+#include "exec_req.h"
+#include <errno.h>
+#include "peer.h"
+#include "discovery.h"
+
+/** Version of the protocol */
+#define VER_MAJOR 0
+#define VER_MINOR 0
+
+#define VER(major, minor) ((major)<<8 || (minor))
+
+extern UL_LOG_CUST(ulogd_forb_iop);
+
+
+CORBA_boolean
+forb_iop_prepend_message_header(FORB_CDR_Codec *codec, forb_iop_message_type mt)
+{
+ CORBA_boolean ret;
+ forb_iop_message_header mh;
+ mh.proto_version.major = VER_MAJOR;
+ mh.proto_version.minor = VER_MINOR;
+ mh.message_type = mt;
+ mh.flags = (codec->data_endian == LittleEndian) ? forb_iop_LITTLE_ENDIAN : 0;
+ mh.message_size = FORB_CDR_data_size(codec);
+ ret = FORB_CDR_buffer_prepend(codec, forb_iop_MESSAGE_HEADER_SIZE);
+ if (ret) {
+ ret = forb_iop_message_header_serialize(codec, &mh);
+ }
+ return ret;
+}
+
+CORBA_boolean
+forb_iop_prepare_request(forb_request_t *req,
+ char *iface,
+ unsigned method_ind,
+ CORBA_Environment *env)
+{
+ CORBA_boolean ret;
+ forb_iop_request_header rh;
+
+ rh.request_id = req->request_id;
+ rh.iface = iface;
+ rh.objkey = forb_object_to_key(req->obj);
+ rh.method_index = method_ind;
+ rh.source = forb_object_to_forb(req->obj)->server_id;
+ ret = forb_iop_request_header_serialize(&req->cdr_request, &rh);
+ if (ret) {
+ /* Request body is 8 byte aligned */
+ ret = FORB_CDR_put_align(&req->cdr_request, 8);
+ char str[50];
+ ul_logdeb("preparing request: id=%d dest=%s iface=%s method=%d\n", req->request_id,
+ forb_server_id_to_string(str, &req->obj->server, sizeof(str)),
+ iface, method_ind);
+ }
+ return ret;
+}
+
+static CORBA_boolean
+forb_iop_prepare_hello(FORB_CDR_Codec *codec,
+ const forb_server_id *server_id,
+ const void *src_addr,
+ CORBA_boolean (*serialize_addr)(FORB_CDR_Codec *codec, const void *addr),
+ const CORBA_char *orb_id)
+{
+ if (!forb_server_id_serialize(codec, server_id)) return CORBA_FALSE;
+ if (serialize_addr) {
+ if (!serialize_addr(codec, src_addr)) return CORBA_FALSE;
+ }
+ if (!CORBA_string_serialize(codec, &orb_id)) return CORBA_FALSE;
+ /* All headers must be 8 byte aligned so align the length of
+ * this message */
+ if (!FORB_CDR_put_align(codec, 8)) return CORBA_FALSE;
+ if (!forb_iop_prepend_message_header(codec, forb_iop_HELLO)) return CORBA_FALSE;
+ return CORBA_TRUE;
+}
+
+int forb_iop_send_hello_to(forb_peer_t *peer)
+{
+ forb_port_t *port = peer->port;
+ FORB_CDR_Codec codec;
+ int ret;
+ FORB_CDR_codec_init_static(&codec, port->forb->orb);
+ if (!FORB_CDR_buffer_init(&codec, 1024, 0))
+ return -1;
+ if (!FORB_CDR_buffer_reset(&codec, forb_iop_MESSAGE_HEADER_SIZE)) {
+ ret = -1;
+ goto free;
+ }
+ if (!forb_iop_prepare_hello(&codec, &port->forb->server_id,
+ port->desc.addr,
+ port->desc.proto->serialize_addr,
+ port->forb->attr.orb_id)) {
+ ret = -1;
+ goto free;
+ }
+ ret = forb_proto_send(peer, &codec);
+ if (ret > 0) ret = 0;
+free:
+ FORB_CDR_codec_release_buffer(&codec);
+ return ret;
+}
+
+int
+forb_iop_redistribute_hello_to(forb_peer_t *dest, forb_peer_t *peer)
+{
+ forb_port_t *port = peer->port;
+ FORB_CDR_Codec codec;
+ int ret;
+ FORB_CDR_codec_init_static(&codec, port->forb->orb);
+ if (!FORB_CDR_buffer_init(&codec, 1024, 0))
+ return -1;
+ if (!FORB_CDR_buffer_reset(&codec, forb_iop_MESSAGE_HEADER_SIZE)) {
+ ret = -1;
+ goto free;
+ }
+ if (!forb_iop_prepare_hello(&codec, &peer->server_id,
+ peer->addr,
+ peer->port->desc.proto->serialize_addr,
+ peer->orb_id)) {
+ ret = -1;
+ goto free;
+ }
+ ul_logdeb("redistributing hello of %s (%s) to %s (%s)\n",
+ ""/*TODO:id*/, peer->orb_id, "", dest->orb_id);
+ ret = forb_proto_send(dest, &codec);
+ if (ret > 0) ret = 0;
+free:
+ FORB_CDR_codec_release_buffer(&codec);
+ return ret;
+}
+
+bool
+forb_iop_process_message_header(forb_iop_message_header *mh, FORB_CDR_Codec *codec)
+{
+ /* FIXME: If we have multiple protocol versions, use different
+ * type (independent from version) for return value instead of
+ * mh */
+ forb_iop_version_deserialize(codec, &mh->proto_version);
+ switch (VER(mh->proto_version.major, mh->proto_version.minor)) {
+ case VER(VER_MAJOR, VER_MINOR):
+ forb_iop_message_type_deserialize(codec, &mh->message_type);
+ forb_iop_message_flags_deserialize(codec, &mh->flags);
+ /* Check whwther the type is meaningfull */
+ switch (mh->message_type) {
+ case forb_iop_REQUEST:
+ case forb_iop_REPLY:
+ case forb_iop_HELLO:
+ break;
+ default:
+ ul_logerr("rcvd wrong message type: %d\n",
+ mh->message_type);
+ return false;
+ }
+ codec->data_endian = (mh->flags && forb_iop_LITTLE_ENDIAN) ?
+ LittleEndian : BigEndian;
+ CORBA_unsigned_long_deserialize(codec, &mh->message_size);
+ return true;
+ break;
+ default:
+ ul_logerr("rcvd wrong protocol versio: %d.%d\n",
+ mh->proto_version.major, mh->proto_version.minor);
+ return false;
+ }
+}
+
+static inline CORBA_boolean
+forb_exception_serialize(FORB_CDR_Codec *codec, struct forb_env *env)
+{
+ return CORBA_long_serialize(codec, &env->major);
+}
+
+static inline CORBA_boolean
+forb_exception_deserialize(FORB_CDR_Codec *codec, struct forb_env *env)
+{
+ /* TODO: Declare exceptions in IDL and don't typecast here. */
+ return CORBA_long_deserialize(codec, (CORBA_long*)&env->major);
+}
+
+void
+forb_iop_send_reply(forb_t *forb,
+ forb_server_id *dest,
+ FORB_CDR_Codec *codec,
+ CORBA_long request_id,
+ struct forb_env *env)
+{
+ forb_iop_reply_header reply_header;
+ CORBA_boolean ret;
+ forb_peer_t *peer;
+ fosa_abs_time_t timeout;
+
+ reply_header.request_id = request_id;
+ reply_header.flags = 0;
+ if (forb_exception_occurred(env)) {
+ reply_header.flags |= forb_iop_FLAG_EXCEPTION;
+ FORB_CDR_buffer_reset(codec, forb_iop_MESSAGE_HEADER_SIZE +
+ forb_iop_REPLY_HEADER_SIZE);
+ forb_exception_serialize(codec, env);
+ }
+ /* All headers must be 8 byte aligned so align the length of
+ * this message */
+ if (!FORB_CDR_put_align(codec, 8)) {
+ ul_logerr("Not enough space for tail align\n");
+ return; /* FIXME: handle error (goto above)*/
+ }
+ /* forb_iop_REPLY_HEADER_SIZE equals to 8 even if the real
+ * header is shorter. We want reply data to be 8 byte
+ * aligned */
+ ret = FORB_CDR_buffer_prepend(codec, forb_iop_REPLY_HEADER_SIZE);
+ if (!ret) {
+ goto err;
+ }
+ ret = forb_iop_reply_header_serialize(codec, &reply_header);
+ if (!ret) {
+ goto err;
+ }
+ forb_iop_prepend_message_header(codec, forb_iop_REPLY);
+
+ fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &timeout);
+ timeout = fosa_abs_time_incr(timeout,
+ fosa_msec_to_rel_time(1000));
+
+ peer = forb_get_next_hop(forb, dest, &timeout);
+ if (!peer) {
+ char str[60];
+ forb_server_id_to_string(str, dest, sizeof(str));
+ ul_logerr("Reply destination not found: %s\n", str);
+ goto err;
+ } else {
+ char str[60];
+ forb_server_id_to_string(str, dest, sizeof(str));
+ ul_logdeb("sending reply: dest=%s, id=%u\n", str, request_id);
+ }
+ forb_proto_send(peer, codec);
+ forb_peer_put(peer);
+err:
+ ;
+}
+
+static void
+process_request(forb_port_t *port, FORB_CDR_Codec *codec, uint32_t message_size)
+{
+ forb_iop_request_header request_header;
+ CORBA_boolean ret;
+ forb_object obj;
+ size_t n;
+ forb_t *forb = port->forb;
+ struct forb_env env;
+ FORB_CDR_Codec reply_codec;
+ forb_exec_req_t *exec_req;
+ uint32_t req_size, data_size, header_size;
+ char str[32];
+ forb_peer_t *peer;
+
+ data_size = FORB_CDR_data_size(codec);
+ ret = forb_iop_request_header_deserialize(codec, &request_header);
+ if (!ret) {
+ ul_logerr("Malformed request recevied\n");
+ env.major = FORB_EX_COMM_FAILURE;
+ goto out;
+ }
+ ret = FORB_CDR_get_align(codec, 8);
+ if (!ret) {
+ ul_logerr("Malformed request recevied\n");
+ env.major = FORB_EX_COMM_FAILURE;
+ goto out;
+ }
+
+ header_size = data_size - FORB_CDR_data_size(codec);
+ req_size = message_size - header_size;
+
+ ul_logdeb("rcvd request: src=%s, id=%u, iface=%s, method=%hd\n",
+ forb_server_id_to_string(str, &request_header.source, sizeof(str)),
+ request_header.request_id,
+ request_header.iface,
+ request_header.method_index);
+
+ if (port->new_peer) {
+ /* Request from a new peer was reported by the underlaying protocol */
+ peer = forb_peer_find(port->forb, &request_header.source);
+ if (peer) {
+ /* We already know this peer */
+ /* TODO: Can it be in FORB_PEER_WANTED state?
+ * If yes, we cannot simply igore this. */
+ ul_logmsg("new_peer was already known\n");
+ forb_peer_put(port->new_peer);
+ port->new_peer = NULL;
+ } else {
+ ul_logdeb("discovered new_peer from incomming connection\n");
+ peer = port->new_peer;
+ port->new_peer = NULL;
+ forb_new_peer_discovered(port, peer, request_header.source,
+ peer->addr, peer->orb_id);
+ }
+
+ }
+
+ obj = forb_key_to_object(forb, request_header.objkey);
+ if (!obj) {
+ ul_logerr("Nonexistent object key\n");
+ env.major = FORB_EX_OBJECT_NOT_EXIST;
+ goto send_execption;
+ }
+
+ n = strlen(request_header.iface);
+ ret = strncmp(request_header.iface, obj->interface->name, n);
+ forb_free(request_header.iface);
+ request_header.iface = NULL;
+ if (ret != 0) {
+ env.major = FORB_EX_INV_OBJREF;
+ ul_logerr("Object reference has incorrect type\n");
+ goto send_execption;
+ }
+
+ if (request_header.method_index >= obj->interface->num_methods) {
+ env.major = FORB_EX_INV_IDENT;
+ ul_logerr("To high method number\n");
+ goto send_execption;
+ }
+
+ if (!obj->executor) {
+ env.major = FORB_EX_NO_IMPLEMENT;
+ ul_logerr("No executor for object\n");
+ goto send_execption;
+
+ }
+
+ /* Enqueue execution request */
+ exec_req = forb_malloc(sizeof(*exec_req));
+ if (exec_req) {
+ memset(exec_req, 0, sizeof(exec_req));
+ exec_req->request_id = request_header.request_id;
+ exec_req->source = request_header.source;
+ exec_req->obj = obj;
+ exec_req->method_index = request_header.method_index;
+ /* Copy the request to exec_req */
+ FORB_CDR_codec_init_static(&exec_req->codec, codec->orb);
+ ret = FORB_CDR_buffer_init(&exec_req->codec,
+ req_size,
+ 0);
+ if (!ret) {
+ env.major = FORB_EX_NO_MEMORY;
+ ul_logerr("No memory for executor request bufer of size %d (header_size=%d)\n",
+ req_size, header_size);
+ goto send_execption;
+ }
+ exec_req->codec.data_endian = codec->data_endian;
+ FORB_CDR_buffer_gets(codec, exec_req->codec.buffer, req_size);
+ /* TODO: Use better data structure for incomming
+ buffer to achieve zero-copy behaviour. */
+ forb_exec_req_ins_tail(obj->executor, exec_req);
+ } else {
+ env.major = FORB_EX_NO_MEMORY;
+ ul_logerr("No memory for executor request\n");
+ goto send_execption;
+ }
+
+out:
+ return;
+
+send_execption:
+ FORB_CDR_codec_init_static(&reply_codec, codec->orb);
+ ret = FORB_CDR_buffer_init(&reply_codec, 4096,
+ forb_iop_MESSAGE_HEADER_SIZE +
+ forb_iop_REPLY_HEADER_SIZE);
+ if (!ret) {
+ ul_logerr("No memory for exception reply buffer\n");
+ return;
+ }
+
+ forb_iop_send_reply(port->forb, &request_header.source,
+ &reply_codec, request_header.request_id, &env);
+ FORB_CDR_codec_release_buffer(&reply_codec);
+ /* TODO: relese exec_req etc. */
+}
+
+static void
+process_reply(forb_port_t *port, FORB_CDR_Codec *codec)
+{
+ forb_iop_reply_header rh;
+ forb_t *forb = port->forb;
+ forb_request_t *req;
+
+ forb_iop_reply_header_deserialize(codec, &rh);
+ /* Reply data are 8 byte aligned */
+ FORB_CDR_get_align(codec, 8);
+ ul_logdeb("rcvd reply: id=%u\n", rh.request_id);
+ req = forb_request_find(forb, &rh.request_id);
+ if (!req) {
+ ul_logerr("Received reply to unknown request_id %u\n", rh.request_id);
+ return;
+ }
+ forb_request_delete(forb, req); /* Deregister request from forb */
+
+ if (rh.flags & forb_iop_FLAG_EXCEPTION) {
+ forb_exception_deserialize(codec, req->env);
+ } else {
+ req->cdr_reply = codec;
+ }
+
+ /* Tell the stub where to signal that reply processing is
+ * finished */
+ req->reply_processed = &port->reply_processed;
+
+ /* Resume the stub waiting in forb_wait_for_reply() */
+ forb_syncobj_signal(&req->reply_ready);
+
+ /* Wait for stub to process the results from the codec's buffer */
+ forb_syncobj_wait(&port->reply_processed);
+}
+
+/**
+ * Process incomming HELLO messages.
+ *
+ * For every incomming HELLO message the peer table is searched
+ * whether it already contains a record for that peer or not. If not,
+ * the new peer is added to the table and another hello message is
+ * sent so that the new peer discovers us quickly.
+ *
+ * @param port Port, where hello was received
+ * @param codec Buffer with the hello message
+ */
+static void
+process_hello(forb_port_t *port, FORB_CDR_Codec *codec)
+{
+ forb_server_id server_id;
+ void *addr = NULL;
+ forb_peer_t *peer;
+ forb_t *forb = port->forb;
+ CORBA_string peer_orb_id = NULL;
+
+/* printf("Hello received at port %p\n", port); */
+
+ forb_server_id_deserialize(codec, &server_id);
+ if (port->desc.proto->deserialize_addr) {
+ port->desc.proto->deserialize_addr(codec, &addr);
+ }
+ {
+ char str[60], addrstr[60];
+ if (port->desc.proto->addr2str) {
+ port->desc.proto->addr2str(addrstr, sizeof(addrstr), addr);
+ } else
+ addrstr[0] = 0;
+ ul_logdeb("rcvd hello from %s (addr %s)\n",
+ forb_server_id_to_string(str, &server_id, sizeof(str)),
+ addrstr);
+ }
+ CORBA_string_deserialize(codec, &peer_orb_id);
+ if (forb_server_id_cmp(&server_id, &forb->server_id) != 0) {
+ peer = forb_peer_find(forb, &server_id);
+ if (peer && peer->state == FORB_PEER_DISCOVERED) {
+ /* TODO: Update last hello receive time */
+ if (port->new_peer) {
+ ul_logdeb("peer already discovered but not connected - replacing\n");
+ forb_peer_disconnected(peer);
+ forb_peer_put(peer);
+ peer = port->new_peer;
+ port->new_peer = NULL;
+ forb_new_peer_discovered(port, peer, server_id, addr, peer_orb_id);
+ } else {
+ ul_logdeb("peer already discovered - ignoring\n");
+ if (addr)
+ forb_free(addr);
+ if (peer_orb_id)
+ forb_free(peer_orb_id);
+ forb_peer_put(peer);
+ }
+ } else {
+ if (port->new_peer) {
+ if (peer) {
+ ul_logerr("Unahandled case - FORB_PEER_WANTED && port->new_peer\n");
+ forb_peer_put(peer);
+ }
+ peer = port->new_peer;
+ port->new_peer = NULL;
+ }
+
+ forb_new_peer_discovered(port, peer, server_id, addr, peer_orb_id);
+ }
+ }
+}
+
+static void
+process_message(forb_port_t *port, const forb_iop_message_header *mh,
+ FORB_CDR_Codec *codec)
+{
+ CORBA_long data_size = FORB_CDR_data_size(codec);
+ /* TODO: Check destination address, whether the message is for
+ * us or should be routed. */
+
+ /* TODO: If there is some processing error, skip the rest of
+ * the message according mh.message_size. */
+ switch (mh->message_type) {
+ case forb_iop_REQUEST:
+ process_request(port, codec, mh->message_size);
+ break;
+ case forb_iop_REPLY:
+ process_reply(port, codec);
+ break;
+ case forb_iop_HELLO:
+ process_hello(port, codec);
+ break;
+ default:
+ ul_logmsg("rcvd unknown message type\n");
+ break;
+ }
+ if (port->new_peer) {
+ /* If for some reaseon the new_peer was not processed so free it here. */
+ ul_logmsg("Forgotten new_peer\n");
+ forb_peer_put(port->new_peer);
+ port->new_peer = NULL;
+ }
+
+ FORB_CDR_get_align(codec, 8);
+
+ if (FORB_CDR_data_size(codec) != data_size - mh->message_size) {
+ size_t processed = data_size - FORB_CDR_data_size(codec);
+ ul_logmsg("Message of type %d handled incorrectly (size=%d, processed=%zu); fixing\n",
+ mh->message_type, mh->message_size, processed);
+ ;
+ codec->rptr += mh->message_size - processed;
+ }
+}
+
+/**
+ * Thread run for every port to receive FORB messages from that port.
+ *
+ * @param arg Pointer to ::forb_port_t typecasted to void *.
+ *
+ * @return Always NULL
+ */
+void *forb_iop_receiver_thread(void *arg)
+{
+ forb_port_t *port = arg;
+ const forb_proto_t *proto = port->desc.proto;
+ FORB_CDR_Codec *c = &port->codec;
+ ssize_t rcvd;
+ size_t len;
+ forb_iop_message_header mh;
+ bool header_received = false;
+
+ while (!port->finish) {
+ if (c->rptr == c->wptr) {
+ /* The buffer is empty now - start writing from begining*/
+ FORB_CDR_buffer_reset(c, 0);
+ }
+ /* TODO: If there is not enough space for reception,
+ * we should shift the already received data to the
+ * beginning of the buffer. */
+ rcvd = proto->recv(port,
+ &c->buffer[c->wptr],
+ c->wptr_max - c->wptr);
+ if (rcvd < 0) {
+ ul_logerr("recv returned error %zd (%s), exiting\n", rcvd, strerror(errno));
+ return NULL;
+ }
+ c->wptr += rcvd;
+ c->wptr_last = c->wptr;
+
+ /* While there are some data in the buffer, process them. */
+ while (FORB_CDR_data_size(c) > 0) {
+ len = FORB_CDR_data_size(c);
+ /* Wait for and then process message header */
+ if (!header_received) {
+ if (len >= forb_iop_MESSAGE_HEADER_SIZE) {
+ if (c->rptr % 8 != 0) {
+ ul_logerr("Header doesn't start at 8 byte bounday\n");
+ }
+ header_received = forb_iop_process_message_header(&mh, c);
+ if (!header_received) {
+ ul_logerr("Wrong header received\n");
+ /* TODO: We should probably reset the buffer here */
+ }
+ len = FORB_CDR_data_size(c);
+ } else {
+ break; /* Wait for more data to arrive*/
+ }
+ }
+
+ /* Wait for and then process the message body */
+ if (header_received) {
+ if (len >= mh.message_size) {
+ process_message(port, &mh, c);
+ /* Wait for the next message */
+ header_received = false;
+ } else {
+ break; /* Wait for more data to arrive*/
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+static void
+discovery_cleanup(void *codec)
+{
+ FORB_CDR_codec_release_buffer((FORB_CDR_Codec*)codec);
+ /* TODO: Broadcast some kind of bye bye message */
+}
+
+
+/**
+ * Thread run for every port to broadcast HELLO messages. These
+ * messages are used for a FORB to discover all peers (and in future
+ * also to detect their disconnection).
+ *
+ * @param arg Pointer to ::forb_port_t typecasted to void *.
+ *
+ * @return Always NULL
+ */
+void *forb_iop_discovery_thread(void *arg)
+{
+ forb_port_t *port = arg;
+ const forb_proto_t *proto = port->desc.proto;
+ FORB_CDR_Codec codec;
+ fosa_abs_time_t hello_time;
+ fosa_rel_time_t hello_interval = fosa_msec_to_rel_time(1000*proto->hello_interval);
+ int ret;
+
+ FORB_CDR_codec_init_static(&codec, port->forb->orb);
+ FORB_CDR_buffer_init(&codec, 1024, 0);
+
+ pthread_cleanup_push(discovery_cleanup, &codec);
+
+ /* Next hello interval is now */
+ fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &hello_time);
+
+ while (!port->finish) {
+ /* Wait for next hello interval or until somebody
+ * signals us. */
+ ret = forb_syncobj_timedwait(&port->hello, &hello_time);
+ /* sem_timedwait would be more appropriate */
+ if (ret == FOSA_ETIMEDOUT) {
+ hello_time = fosa_abs_time_incr(hello_time, hello_interval);
+ } else if (ret != 0) {
+ ul_logerr("hello syncobj error: %s\n", strerror(ret));
+ }
+
+ if (port->finish) break;
+
+ FORB_CDR_buffer_reset(&codec, forb_iop_MESSAGE_HEADER_SIZE);
+ forb_iop_prepare_hello(&codec, &port->forb->server_id, port->desc.addr,
+ proto->serialize_addr, port->forb->attr.orb_id);
+/* printf("Broadcasting hello from port %p\n", port); */
+ proto->broadcast(port, &codec.buffer[codec.rptr],
+ FORB_CDR_data_size(&codec));
+ }
+
+ pthread_cleanup_pop(1);
+ return NULL;
+}
+
+/**
+ * Sends REQUEST message to another FORB.
+ *
+ * The request @a req has to be prepared by
+ * forb_iop_prepare_request(). Then, this function adds a message
+ * header, connects to the destination FORB and sends the request.
+ *
+ * If no exception is reported, then the caller must wait for response
+ * by calling forb_wait_for_reply().
+ *
+ * @param req A request prepared by forb_iop_prepare_request()
+ * @param env Environment for returning exceptions
+ */
+void
+forb_request_send(forb_request_t *req, CORBA_Environment *env)
+{
+ CORBA_boolean ret;
+ forb_peer_t *peer;
+ ssize_t size;
+ size_t len;
+ fosa_abs_time_t timeout;
+ forb_t *forb = forb_object_to_forb(req->obj);
+
+ if (!forb) {
+ env->major = FORB_EX_INTERNAL;
+ return;
+ }
+
+ req->env = env; /* Remember, where to return exceptions */
+
+ /* All headers must be 8 byte aligned so align the length of
+ * this message */
+ if (!FORB_CDR_put_align(&req->cdr_request, 8)) {
+ env->major = FORB_EX_INTERNAL;
+ ul_logerr("Not enough space for tail align\n");
+ return;
+ }
+
+ ret = forb_iop_prepend_message_header(&req->cdr_request, forb_iop_REQUEST);
+ if (!ret) {
+ /* This should never happen */
+ env->major = FORB_EX_INTERNAL;
+ return;
+ }
+
+ fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &timeout);
+ timeout = fosa_abs_time_incr(timeout,
+ fosa_msec_to_rel_time(1000));
+ peer = forb_get_next_hop(forb, &req->obj->server, &timeout);
+ if (!peer) {
+ char str[50];
+ ul_logerr("Cannot find peer to send request for server %s\n",
+ forb_server_id_to_string(str, &req->obj->server, sizeof(str)));
+ env->major = FORB_EX_COMM_FAILURE;
+ return;
+ }
+ /* Register the request with forb so we can match incomming
+ * reply to this request. */
+ ret = forb_request_insert(forb, req);
+ if (ret <= 0) {
+ ul_logerr("Insert request error %d\n", ret);
+ env->major = FORB_EX_INTERNAL;
+ goto err_peer_put;
+ }
+
+ {
+ char str[50];
+ ul_logdeb("sending request: id=%d dest=%s\n", req->request_id,
+ forb_server_id_to_string(str, &req->obj->server, sizeof(str)));
+ }
+ len = FORB_CDR_data_size(&req->cdr_request);
+ fosa_mutex_lock(&peer->send_lock);
+ size = forb_proto_send(peer, &req->cdr_request);
+ fosa_mutex_unlock(&peer->send_lock);
+ if (size <= 0 || size != len) {
+ env->major = FORB_EX_COMM_FAILURE;
+ /* Request is deleted when the stub calls forb_request_destroy() */
+ }
+ err_peer_put:
+ forb_peer_put(peer);
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file iop.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 17:00:39 2008
+ *
+ * @brief Interface to Inter-ORB Protocol.
+ *
+ *
+ */
+
+#ifndef FORB_IOP_H
+#define FORB_IOP_H
+
+#include <forb/iop-idl.h>
+#include <forb/cdr.h>
+#include <forb/request.h>
+#include <forb/peer.h>
+
+CORBA_boolean
+forb_iop_prepend_message_header(FORB_CDR_Codec *codec, forb_iop_message_type mt);
+
+CORBA_boolean
+forb_iop_prepare_request(forb_request_t *req,
+ char *iface,
+ unsigned method_ind,
+ CORBA_Environment *env);
+
+bool
+forb_iop_process_message_header(forb_iop_message_header *mh, FORB_CDR_Codec *codec);
+
+void
+forb_iop_process_message(forb_iop_message_header *mh, FORB_CDR_Codec *codec);
+
+void
+forb_iop_send_reply(forb_t *forb,
+ forb_server_id *dest,
+ FORB_CDR_Codec *codec,
+ CORBA_long request_id,
+ struct forb_env *env);
+
+void *
+forb_iop_receiver_thread(void *arg);
+void *
+forb_iop_discovery_thread(void *arg);
+
+/* TODO: rename to forb_iop_send_request */
+void
+forb_request_send(forb_request_t *req, CORBA_Environment *env);
+
+int
+forb_iop_send_hello_to(forb_peer_t *peer);
+int
+forb_iop_redistribute_hello_to(forb_peer_t *dest, forb_peer_t *peer);
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file object.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 17:03:06 2008
+ *
+ * @brief Functions for manipulation with FORB's object references.
+ *
+ *
+ */
+
+#include <forb/forb-internal.h>
+#include <forb/object.h>
+#include <stdio.h>
+#include <forb/cdr_codec.h>
+#include <forb/cdr.h>
+#include "forb_utils.h"
+#include <inttypes.h>
+
+GAVL_CUST_NODE_INT_IMP(forb_objects_nolock /* cust_prefix */,
+ forb_t /* cust_root_t */,
+ struct _forb_object /* cust_item_t */,
+ forb_object_key /* cust_key_t */,
+ objects /* cust_root_node */,
+ node /* cust_item_node */,
+ objkey /* cust_item_key */,
+ forb_objkey_cmp/* cust_cmp_fnc */);
+
+/**
+ * Creates a new object reference.
+ *
+ * @param orb FORB object this object reference is handled by. This
+ * can be NULL only when local forb_orb reference is created in
+ * forb_init().
+ *
+ * @param server_id Server ID of the remote FORB, where this object is
+ * implemented or NULL if the object is implemented locally by @a orb.
+ *
+ * @param key Key of the remote object. If server_id is NULL this
+ * value is ignored and objkey is assigned internally.
+ *
+ * @return FORB object reference of NULL in case of error.
+ */
+forb_object
+forb_object_new(forb_orb orb,
+ forb_server_id *server_id,
+ forb_object_key key)
+{
+ forb_object obj = forb_malloc(sizeof(*obj));
+ if (obj) {
+ memset(obj, 0, sizeof(*obj));
+ forb_ref_init(&obj->ref);
+ obj->orb = orb ? orb : obj;
+ if (server_id) {
+ /* remote object */
+ obj->server = *server_id;
+ obj->objkey = key;
+ } else {
+ /* local object */
+ if (orb) {
+ /* Normal local object */
+ forb_t *forb = forb_object_to_forb(obj);
+ obj->server = forb->server_id;
+ fosa_mutex_lock(&forb->objkey_mutex);
+ obj->objkey = ++forb->objkey;
+ /* We do not use object references for tree pointers. */
+ forb_objects_nolock_insert(forb, obj);
+ fosa_mutex_unlock(&forb->objkey_mutex);
+ } else {
+ /* forb_orb object. The forb_init()
+ * function must assign server field
+ * and put the object into the
+ * forb->objects */
+ obj->objkey = 0;
+ }
+ }
+ }
+ return obj;
+}
+
+/**
+ * This function does the real release of memory when reference count
+ * is zero.
+ *
+ * @note We add this function the _real suffix because the
+ * forb_object_release() is meant for applications use and we want the
+ * name similar to CORBA_Object_release().
+ */
+static void
+forb_object_release_real(forb_ref_t *ref)
+{
+ forb_object obj = container_of(ref, struct _forb_object, ref);
+
+ if (obj->orb) {
+ forb_t *forb = forb_object_to_forb(obj);
+ if (forb_server_id_cmp(&obj->server, &forb->server_id) == 0) {
+ /* Local object - unregister it from FORB. */
+ forb_objects_delete(forb, obj);
+ }
+ }
+ forb_free(obj);
+}
+
+static inline void forb_object_get(forb_object obj)
+{
+ forb_ref_get(&obj->ref);
+}
+
+static inline void forb_object_put(forb_object obj)
+{
+ forb_ref_put(&obj->ref, forb_object_release_real);
+ /* TODO: Exit executor. Question: Shall the executor have its
+ * own refcount? Is so, how do we know to exit/kill it?
+ * Possible answer: The executor might be notified from here
+ * and then exit if it owns the last reference. */
+}
+
+/**
+ * Releases all memory associated with a object reference and
+ * deregister the object from FORB.
+ *
+ * @param obj Object reference to release
+ */
+void forb_object_release(forb_object obj)
+{
+ forb_object_put(obj);
+}
+
+/**
+ * Returns the object's key.
+ *
+ * @param obj
+ *
+ * @return The key.
+ */
+forb_object_key forb_object_to_key(forb_object obj)
+{
+ return obj->objkey;
+}
+
+/**
+ * Returns the objects reference of a given key.
+ *
+ * @param forb
+ * @param key
+ *
+ * @return The object reference or NULL in case the object with a
+ * given key doesn't exist.
+ */
+forb_object forb_key_to_object(forb_t *forb, forb_object_key key)
+{
+ forb_object obj;
+ obj = forb_objects_find(forb, key);
+ return obj;
+}
+
+/**
+ * Converts object reference to string.
+ *
+ * @param obj Object reference to convert.
+ *
+ * @return String, which must be freed by forb_free() or NULL in case
+ * of error.
+ */
+char *
+forb_object_to_string(const forb_object obj)
+{
+ char *str;
+ size_t s;
+ forb_object_key key;
+ char server_id[65];
+
+ s = 2*sizeof(forb_server_id)+1+2*sizeof(size_t)+1;
+ str = malloc(s);
+ if (!str) {
+ return NULL;
+ }
+
+ forb_server_id_to_string(server_id, &obj->server, s);
+ key = forb_object_to_key(obj);
+ snprintf(str, s, "%s-%"PRIu64, server_id, key);
+
+ return str;
+}
+
+/**
+ * Creates object reference from string.
+ *
+ * The string should be generated by forb_object_to_string() in the
+ * same or another FORB. When the returned reference is not needed, it
+ * should be freed by forb_object_release().
+ *
+ * @param orb FORB which should handle the object.
+ * @param string The string returned by forb_object_to_string().
+ *
+ * @return FORB object reference or NULL in case of error.
+ */
+forb_object
+forb_string_to_object(const forb_orb orb, const char *string)
+{
+ forb_object obj;
+ forb_object_key key;
+ forb_server_id server_id;
+ int ret;
+
+ if (forb_server_id_from_string(&server_id, string) == NULL)
+ return NULL;
+
+ if (string[2*sizeof(server_id)] != '-')
+ return NULL;
+
+ ret = sscanf(&string[2*sizeof(server_id)+1], "%"SCNu64, &key);
+ if (ret == 0 || ret == EOF)
+ return NULL;
+
+ obj = forb_object_new(orb, &server_id, key);
+
+ return obj;
+}
+
+/**
+ * Duplicates the object reference.
+ *
+ * @param obj Object reference to duplicate.
+ *
+ * @return The new copy of @a obj or NULL in case of error. The
+ * duplicated object should be released later by forb_object_release().
+ */
+forb_object
+forb_object_duplicate(const forb_object obj)
+{
+ if (!obj) {
+ return NULL;
+ }
+ forb_object_get(obj);
+ return obj;
+}
+
+/**
+ * Serialize the object reference.
+ *
+ * @param codec
+ * @param obj
+ *
+ * @return CORBA_TRUE on success, CORBA_FALSE on error.
+ */
+CORBA_boolean
+forb_object_serialize(FORB_CDR_Codec *codec, const forb_object *obj)
+{
+ if (!forb_server_id_serialize(codec, &(*obj)->server))
+ return CORBA_FALSE;
+ if (!forb_object_key_serialize(codec, &(*obj)->objkey))
+ return CORBA_FALSE;
+ return CORBA_TRUE;
+}
+
+/**
+ * Creates the object reference by deserialization from ::FORB_CDR_Codec.
+ *
+ * @param codec
+ * @param obj
+ *
+ * @return CORBA_TRUE on success, CORBA_FALSE on error.
+ */
+CORBA_boolean
+forb_object_deserialize(FORB_CDR_Codec *codec, forb_object *obj)
+{
+ forb_server_id server_id;
+ forb_object_key objkey;
+ if (!forb_server_id_deserialize(codec, &server_id))
+ return CORBA_FALSE;
+ if (!forb_object_key_deserialize(codec, &objkey))
+ return CORBA_FALSE;
+ if (!codec->orb)
+ return CORBA_FALSE;
+ *obj = forb_object_new(codec->orb, &server_id, objkey);
+ return CORBA_TRUE;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file object.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 17:03:44 2008
+ *
+ * @brief Declarations for FORB's object references.
+ *
+ *
+ */
+
+#ifndef FORB_OBJECT_H
+#define FORB_OBJECT_H
+
+#include <ul_gavlcust.h>
+#include <forb/forb-internal.h>
+#include <stdbool.h>
+#include <forb/refcnt.h>
+#include <forb/basic_types.h>
+#include <forb/executor.h>
+#include <forb/exec_req.h>
+
+/**
+ * Object reference structure.
+ *
+ * The only ways for applications to create an object reference are:
+ * - call IDL generated forb_<interface>_new() function,
+ * - call forb_string_to_object().
+ * - call forb_get_orb_of()
+ * - call forb_init()
+ *
+ * When the created object is not needed, the application should call
+ * forb_object_release().
+ *
+ * If the object reference is passed as a parameter of interface
+ * method, the same rules as in CORBA C mapping objref_ptr applies,
+ * which is:
+ *
+ * - if the method needs to store the object reference, it must call
+ * forb_object_duplicate() and store the duplicate.
+ */
+struct _forb_object {
+ /** @name Fields valid for both local and remote object references */
+ /*@{*/
+
+ /** Server implementing this object. @see forb::server_id */
+ forb_server_id server;
+ /** Object key of the object. @see forb::object_key */
+ forb_object_key objkey;
+
+ forb_orb orb; /**< FORB reference */
+ forb_ref_t ref; /**< Reference count */
+ /*@}*/
+
+ /** @name Fields used only in implementation (server) */
+ /*@{*/
+
+ /** Any data for implementation */
+ void *instance_data;
+
+ /** Description of interface implemented by this object (for
+ * servers); FIXME: What about clients? */
+ const forb_interface_t *interface;
+
+ /** Pointer to the object implementation methods or NULL in
+ * case of remote object. */
+ const void *implementation;
+
+ /** Executor object, which represents the thread the requests
+ * are executed in. */
+ forb_executor_t *executor;
+
+ /**
+ * Pointer to the execute request in case of remote
+ * invocation.
+ *
+ * @warning If the object can be called both localy and
+ * remotely this field may contain wrong value as the local
+ * and remote requests can be executed in parallel, in
+ * different threads. This will be fixed after even local
+ * invocations will be executed through executors. */
+ forb_exec_req_t *exec_req;
+
+ gavl_node_t node; /**< Node for forb->objects tree */
+ /*@}*/
+};
+
+/**
+ * Description of an IDL interface.
+ *
+ * Instances of this structure are generated by forb-idl (IDL compiler).
+ */
+struct forb_interface {
+ char *name; /**< Name of the interface */
+ unsigned num_methods; /**< Number of methods */
+ const forb_skel_func *skeletons; /**< Array of pointers to skeleton functions (one function for every method) */
+ uint32_t type_hash; /**< Not implemented */
+};
+
+/**
+ * Returns forb_object::instance_data of an object.
+ *
+ */
+#define forb_object_instance_data(obj) ((obj)->instance_data)
+
+/** Return forb_t from an object reference. */
+static inline forb_t *
+forb_data(forb_orb orb)
+{ return forb_object_instance_data(orb); }
+
+
+/**
+ * Returns pointer to forb_t from any object reference.
+ *
+ * @param obj Object reference.
+ *
+ * @return Pointer to forb_t which handles the @a obj.
+ */
+static inline forb_t *
+forb_object_to_forb(forb_object obj)
+{ return forb_data(obj->orb); }
+
+forb_object_key forb_object_to_key(forb_object obj);
+forb_object forb_key_to_object(forb_t *forb, forb_object_key key);
+
+static inline int forb_objkey_cmp(const forb_object_key *a, const forb_object_key *b)
+{
+ return (*a<*b) ? -1 :
+ ((*a>*b) ? +1 :
+ 0);
+}
+
+forb_object
+forb_object_new(forb_orb orb,
+ forb_server_id *server_id,
+ forb_object_key key);
+
+/* Declaration of typesafe function for storing objects in GAVL tree
+ * ordered by object keys. */
+GAVL_CUST_NODE_INT_DEC(forb_objects_nolock /* cust_prefix */,
+ forb_t /* cust_root_t */,
+ struct _forb_object /* cust_item_t */,
+ forb_object_key /* cust_key_t */,
+ objects /* cust_root_node */,
+ node /* cust_item_node */,
+ objkey /* cust_item_key */,
+ forb_objkey_cmp/* cust_cmp_fnc */);
+
+
+/**
+ * Deletes object reference of an implementation from forb_t::objects.
+ *
+ * @param forb
+ * @param obj
+ */
+static inline void
+forb_objects_delete(forb_t *forb, forb_object obj)
+{
+ fosa_mutex_lock(&forb->objkey_mutex);
+ forb_objects_nolock_delete(forb, obj);
+ fosa_mutex_unlock(&forb->objkey_mutex);
+}
+
+/**
+ * Finds implementation of an object with a given key.
+ *
+ * @param forb
+ * @param objkey
+ *
+ * @return Object references if it exists or NULL otherwise.
+ */
+static inline forb_object
+forb_objects_find(forb_t *forb, forb_object_key objkey)
+{
+ forb_object ret;
+ fosa_mutex_lock(&forb->objkey_mutex);
+ ret = forb_objects_nolock_find(forb, &objkey);
+ ret = forb_object_duplicate(ret);
+ fosa_mutex_unlock(&forb->objkey_mutex);
+ return ret;
+}
+
+/**
+ * Determines whether the object is local (in-process) or remote.
+ *
+ * @param obj
+ *
+ * @return true if local, false otherwise or in case of invalid object reference.
+ */
+static inline bool
+forb_object_is_local(forb_object obj)
+{
+ return obj && obj->implementation;
+}
+/**
+ * Determines whether the object is remote.
+ *
+ * @param obj
+ *
+ * @return true if remote, false otherwise or in case of invalid object reference.
+ */
+static inline bool
+forb_object_is_remote(forb_object obj)
+{
+ return obj && (obj->implementation == NULL);
+}
+
+CORBA_boolean
+forb_object_serialize(FORB_CDR_Codec *codec, const forb_object *obj);
+CORBA_boolean
+forb_object_deserialize(FORB_CDR_Codec *codec, forb_object *obj);
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file object_type.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 16:19:24 2008
+ *
+ * @brief Incomplete declarations of forb_object type and all associated stuff.
+ *
+ *
+ */
+
+#ifndef FORB_FORB_OBJECT_H
+#define FORB_FORB_OBJECT_H
+
+#include <forb/basic_types.h>
+#include <stdlib.h>
+#include <forb/types.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+struct _forb_object;
+
+/** Opaque object reference type. */
+typedef struct _forb_object *forb_object;
+typedef forb_object CORBA_Object;
+
+#if !defined(_forb_orb_defined)
+#define _forb_orb_defined 1
+typedef forb_object forb_orb;
+#endif
+
+/**
+ * FORB exception types. Inspired by CORBA's standard system
+ * exceptions.
+ */
+enum forb_exception {
+ FORB_EX_NONE, /* 0 */
+ FORB_EX_UNKNOWN, /* 1 */
+ FORB_EX_BAD_PARAM, /* 2 */
+ FORB_EX_NO_MEMORY, /* 3 */
+ FORB_EX_IMP_LIMIT, /* 4 */
+ FORB_EX_COMM_FAILURE, /* 5 */
+ FORB_EX_INV_OBJREF, /* 6 */
+ FORB_EX_NO_PERMISSION, /* 7 */
+ FORB_EX_INTERNAL, /* 8 */
+ FORB_EX_MARSHAL, /* 9 */
+ FORB_EX_INITIALIZE, /* 10 */
+ FORB_EX_NO_IMPLEMENT, /* 11 */
+ FORB_EX_BAD_OPERATION, /* 12 */
+ FORB_EX_NO_RESOURCES, /* 13 */
+ FORB_EX_NO_RESPONSE, /* 14 */
+ FORB_EX_TRANSIENT, /* 15 */
+ FORB_EX_FREE_MEM, /* 16 */
+ FORB_EX_INV_IDENT, /* 17 */
+ FORB_EX_INV_FLAG, /* 18 */
+ FORB_EX_DATA_CONVERSION, /* 19 */
+ FORB_EX_OBJECT_NOT_EXIST, /* 20 */
+ FORB_EX_TIMEOUT, /* 21 */
+ FORB_EX_APPLICATION, /* 22 */ /**< Application defined exception - TODO: Add minor number to forb_env */
+};
+
+/**
+ * Environment for FORB invocations.
+ *
+ */
+struct forb_env {
+ enum forb_exception major; /**< Exception number */
+};
+
+typedef struct forb_env CORBA_Environment;
+
+static inline CORBA_boolean forb_exception_occurred(CORBA_Environment *env)
+{
+ return (env->major != FORB_EX_NONE);
+}
+
+#define forb_malloc(size) malloc(size)
+#define forb_free(ptr) free(ptr)
+
+#define CORBA_malloc(size) forb_malloc(size)
+#define CORBA_free(ptr) forb_free(ptr)
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file peer.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 17:30:27 2008
+ *
+ * @brief Implementation of peer manipulation functions.
+ *
+ *
+ */
+
+#include "peer.h"
+#include "forb_utils.h"
+#include "proto.h"
+
+forb_peer_t *
+forb_peer_new(void)
+{
+ forb_peer_t *peer;
+
+ peer = forb_malloc(sizeof(*peer));
+ if (peer) {
+ memset(peer, 0, sizeof(*peer));
+ fosa_cond_init(&peer->cond);
+ forb_ref_init(&peer->ref);
+ fosa_mutex_init(&peer->send_lock, 0);
+ }
+ return peer;
+}
+
+void
+forb_peer_release(forb_ref_t *ref)
+{
+ forb_peer_t *peer = container_of(ref, forb_peer_t, ref);
+ if (peer->port &&
+ peer->port->desc.proto->peer_destroy) {
+ peer->port->desc.proto->peer_destroy(peer);
+ }
+ if (peer->addr)
+ forb_free(peer->addr);
+
+ forb_free(peer);
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file peer.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 17:31:51 2008
+ *
+ * @brief Declarations of peer data structure and functions.
+ *
+ *
+ */
+
+#ifndef FORB_PEER_H
+#define FORB_PEER_H
+
+#include <forb/forb-internal.h>
+#include "port.h"
+#include "refcnt.h"
+#include <ul_gavl.h>
+#include <ul_list.h>
+#include <fosa_mutexes_and_condvars.h>
+/**
+ * State of a peer.
+ *
+ */
+enum forb_peer_state {
+ FORB_PEER_WANTED, /**< Somebody is waiting for the peer to be discovered. In this state, only @a server_id field is set. */
+ FORB_PEER_DISCOVERED, /**< The peer is already discovered, so it is addr is known and messages can be sent to him. */
+};
+
+/**
+ * Description of a peer FORB. We consider peers only in one-hop
+ * distance. For more distant forbs, we need to use a routing table.
+ *
+ * @note This structure is reference counted. Use forb_peer_get() when
+ * you copy a pointer to peer and forb_peer_put() when the pointer is
+ * not needed.
+ */
+typedef struct forb_peer {
+ forb_server_id server_id; /**< Server_id of the peer */
+ forb_port_t *port; /**< Port of this peer is connected to */
+ void *addr; /**< Protocol specific address of the peer. */
+ char *orb_id; /**< ORB ID of the peer */
+ void *proto_priv; /**< Protocol private data (e.g. info about established connection) */
+ gavl_node_t gnode; /**< Node of forb_t::peers tree */
+ ul_list_node_t lnode; /**< Node of forb_port_t::peers list */
+ forb_ref_t ref; /**< Reference count */
+ enum forb_peer_state state;
+ fosa_cond_t cond; /**< Condition variable for waiting after the peer is discovered. Used together with forb_t::peer_mutex. */
+ fosa_mutex_t send_lock;
+} forb_peer_t;
+
+UL_LIST_CUST_DEC(forb_port_peer, /* cust_prefix */
+ forb_port_t, /* cust_head_t */
+ forb_peer_t, /* cust_item_t */
+ peers, /* cust_head_field */
+ lnode) /* cust_node_field */
+
+forb_peer_t *
+forb_peer_new(void);
+
+void
+forb_peer_release(forb_ref_t *ref);
+
+static inline forb_peer_t *
+forb_peer_get(forb_peer_t *peer)
+{
+ forb_ref_get(&peer->ref);
+ return peer;
+}
+
+static inline void
+forb_peer_put(forb_peer_t *peer)
+{
+ forb_ref_put(&peer->ref, forb_peer_release);
+}
+
+void
+forb_peer_delete_by_port(forb_t *forb, forb_port_t *port);
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file port.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 17:36:13 2008
+ *
+ * @brief Implementation of port manipulation functions.
+ *
+ *
+ */
+
+
+#include "port.h"
+#include "proto.h"
+#include "object.h"
+#include <forb/config.h>
+#include "iop.h"
+#include <ul_log.h>
+#include "discovery.h"
+
+extern UL_LOG_CUST(ulogd_forb_port);
+
+/**
+ * Registers a new port in FORB and run receiver thread on it to
+ * receive FORB messages through this prot.
+ *
+ * @param forb Where to register the new port.
+ *
+ * @param port Port to register. The @c desc field should be
+ * initialized prior calling this function. The memory for @a port
+ * should be forb_malloced, since forb_free() is called on the port on
+ * destroy operation.
+ *
+ * @return Zero on success, FOSA error code on error.
+ */
+int forb_register_port(forb_orb orb, forb_port_t *port)
+{
+ int ret;
+ forb_t *forb = forb_data(orb);
+
+ port->forb = forb;
+ port->finish = false;
+
+ forb_port_peer_init_head(port);
+
+ fosa_mutex_lock(&forb->port_mutex);
+ forb_port_insert(forb, port);
+ fosa_mutex_unlock(&forb->port_mutex);
+
+ forb_syncobj_init(&port->hello, 0);
+ forb_syncobj_init(&port->reply_processed, 0);
+
+ FORB_CDR_codec_init_static(&port->codec, forb->orb);
+ if (!FORB_CDR_buffer_init(&port->codec, CONFIG_FORB_RECV_BUF_SIZE, 0)) {
+ ret = FOSA_ENOMEM;
+ goto err;
+ }
+
+ if (port->desc.proto->register_cb) {
+ port->desc.proto->register_cb(port);
+ }
+
+ ret = fosa_thread_create(&port->receiver_thread, NULL,
+ forb_iop_receiver_thread, port);
+ if (ret != 0)
+ goto err2;
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT
+ /* For reliability reasons, we do not use discovery protocol
+ * when INET is the default communication protocol. */
+ ret = fosa_thread_create(&port->discovery_thread, NULL,
+ forb_iop_discovery_thread, port);
+ if (ret != 0)
+ goto err3;
+#endif
+ return 0;
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT
+err3:
+ port->finish = true;
+ /* FIXME: This is Aquosa specific - cancelation should be
+ * added to FOSA. */
+ pthread_cancel(port->receiver_thread.pthread_id);
+ pthread_cancel(port->discovery_thread.pthread_id);
+
+ pthread_join(port->receiver_thread.pthread_id, NULL);
+ pthread_join(port->discovery_thread.pthread_id, NULL);
+#endif
+err2:
+ FORB_CDR_codec_release_buffer(&port->codec);
+err:
+ fosa_mutex_lock(&forb->port_mutex);
+ forb_port_delete(forb, port);
+ fosa_mutex_unlock(&forb->port_mutex);
+
+ return ret;
+}
+
+/**
+ * Destroys the port and all resources associated with it.
+ *
+ * @param port
+ */
+void forb_destroy_port(forb_port_t *port)
+{
+ forb_t *forb = port->forb;
+ void *thread_return;
+
+ port->finish = true; /* Exit all the threads */
+
+ /* FIXME: There is no FOSA API for thread cancelation. */
+ pthread_cancel(port->receiver_thread.pthread_id);
+
+ /* FIXME: Canceling discovery thread sometimes didn't
+ * work. The discovery thread stayed forever in the
+ * pthread_cond_timedwait(). */
+ //pthread_cancel(port->discovery_thread.pthread_id);
+
+ /* Sometimes, cancelation doesn't work and the
+ * discovery_thread hangs in pthread_cond_timedwait
+ * infinitely. */
+ forb_syncobj_signal(&port->hello);
+
+ pthread_join(port->receiver_thread.pthread_id, &thread_return);
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT
+ pthread_join(port->discovery_thread.pthread_id, &thread_return);
+#endif
+
+ /* Because of no locking of port->peers, this must be called
+ * after receiver thread is stopped. */
+ forb_peer_t *peer;
+ ul_list_for_each_cut(forb_port_peer, port, peer) {
+ forb_peer_get(peer);
+ forb_peer_disconnected(peer);
+ forb_peer_put(peer);
+ }
+
+ if (port->desc.proto->port_destroy) {
+ port->desc.proto->port_destroy(port);
+ }
+
+ FORB_CDR_codec_release_buffer(&port->codec);
+
+ fosa_mutex_lock(&forb->port_mutex);
+ forb_port_delete(forb, port);
+ fosa_mutex_unlock(&forb->port_mutex);
+
+ /* TODO: reference counting */
+ forb_free(port);
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file port.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 17:36:39 2008
+ *
+ * @brief Declarations of port types and functions.
+ *
+ *
+ */
+
+#ifndef FORB_PORT_H
+#define FORB_PORT_H
+
+#include <forb/forb-internal.h>
+#include <forb/syncobj.h>
+
+struct forb_proto;
+struct forb_peer;
+
+/**
+ * Description of a port. Needs to be filled for forb_register_port().
+ */
+struct forb_port_desc {
+ const struct forb_proto *proto; /**< Protocol used on this port */
+ void *proto_priv; /**< Protocol specific data */
+ void *addr; /**< Port's address in a protocol specific format. */
+};
+
+/**
+ * Represents one (of possibly multiple) ports using a specific
+ * FORB transport protocol (see ::forb_proto).
+ *
+ * Every port runs its own thread for receiving messages
+ * (forb_iop_receiver_thread()) and another thread
+ * (forb_iop_discovery_thread()) for periodic broadcasting of HELLO
+ * messages to discover peers connected to the same network.
+ */
+typedef struct forb_port {
+ struct forb_port_desc desc; /**< Description of the port */
+ forb_t *forb; /**< FORB, this port is registered in. */
+ fosa_thread_id_t receiver_thread; /**< The thread running forb_port_receiver_thread() */
+ fosa_thread_id_t discovery_thread;/**< The thread for periodic sending HELLO messages */
+ forb_syncobj_t hello; /**< Synchronization object for signaling the discovery thread to send the hello messages now. */
+ forb_syncobj_t reply_processed; /**< Synchronization object for signaling the receiver thread to continue processing after the reply is processed by a stub. */
+ FORB_CDR_Codec codec; /**< Receiving buffer for receiver thread */
+ ul_list_node_t node; /**< Node in forb's port list */
+ ul_list_head_t peers; /**< Peers discovered on this port by discovery protocol */
+ bool finish; /**< True when the threads should finish their execution, false otherwise. */
+
+ /** Peer discovered by another mean than discovery
+ * protocol. This field may be set by the protocol whenever it
+ * receives a message (e.g. request) from a new peer. This is
+ * to overcome limitations of discovery protocol on unreliable
+ * medium. */
+ struct forb_peer *new_peer;
+} forb_port_t;
+
+UL_LIST_CUST_DEC(forb_port, /* cust_prefix */
+ forb_t, /* cust_head_t */
+ forb_port_t, /* cust_item_t */
+ ports, /* cust_head_field */
+ node) /* cust_node_field */
+
+int forb_register_port(forb_orb orb, forb_port_t *port);
+void forb_destroy_port(forb_port_t *port);
+
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+/**
+ * @file proto.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 17:43:28 2008
+ *
+ * @brief
+ *
+ *
+ */
+
+#include "proto.h"
+#include <forb/forb-internal.h>
+#include <forb/config.h>
+#include <stdio.h>
+#include <forb/object.h>
+#include <ul_log.h>
+#include "discovery.h"
+
+extern UL_LOG_CUST(ulogd_forb_proto);
+
+ssize_t forb_proto_send(forb_peer_t *peer, FORB_CDR_Codec *codec)
+{
+
+#if 0
+ {
+ int i, j;
+ char m[1000];
+ i=j=0;
+ while (i<CDR_data_size(codec) && j<sizeof(m)-3) {
+ if (i>0 && i%4 == 0) {
+ m[j++] = ' ';
+ }
+ sprintf(&m[j], "%02x", codec->buffer[i+codec->rptr]);
+ j+=2;
+ i+=1;
+ }
+ ul_logdeb("sending: %s\n", m);
+ }
+#endif
+
+ return peer->port->desc.proto->send(peer, &codec->buffer[codec->rptr],
+ FORB_CDR_data_size(codec));
+}
+
+
+/**
+ * Finds next hop on the way to the particular server.
+ *
+ * Currently, as routing is not implemented, this function searches
+ * only peers.
+ *
+ * @param forb Forb to ask.
+ * @param server_id Destination server.
+ *
+ * @return Next hop peer of NULL, if the destination is not found.
+ *
+ * @note After the returned peer is not needed, forb_peer_put() must
+ * called on it.
+ */
+forb_peer_t *
+forb_get_next_hop(forb_t *forb, forb_server_id *server_id, fosa_abs_time_t *timeout)
+{
+ forb_peer_t *peer;
+ peer = forb_peer_find_timed(forb, server_id, timeout);
+ return peer;
+
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file proto.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Thu Aug 28 10:36:23 2008
+ *
+ * @brief FORB transport protocol declarations
+ *
+ *
+ */
+
+#ifndef FORB_PROTO_H
+#define FORB_PROTO_H
+
+#include "forb-internal.h"
+#include "syncobj.h"
+#include "request.h"
+#include <ul_logbase.h>
+#include "port.h"
+#include "peer.h"
+
+typedef struct forb_proto forb_proto_t;
+
+/**
+ * Description of a FORB transport protocol.
+ */
+struct forb_proto {
+ /** Number of seconds between sending of HELLO messages for discovery process */
+ unsigned hello_interval;
+
+ /**
+ * Called to free any protocol resources associated with the port.
+ *
+ * @param port The port to be destroyed.
+ *
+ * @return Zero on success, negatove error code on error.
+ */
+ int (*port_destroy)(forb_port_t *port);
+
+ /**
+ * Sends data to a peer.
+ *
+ * If the protocol is connection-oriented, the connection data
+ * can be stored at @c port->proto_priv and used by later
+ * requests.
+ *
+ * @param peer Peer to send data
+ * @param buf Data to send
+ * @param len Length of data to send
+ *
+ * @return Length of the sent data (should be equal to @a len on
+ * success) or negative error code on error.
+ */
+ ssize_t (*send)(forb_peer_t *peer, const void *buf, size_t len);
+
+ /**
+ * Called to free any protocol resources associated with the
+ * peer.
+ *
+ * @param peer Peer to destroy
+ *
+ * @note The memory allocated by @a deserialize_addr (if any)
+ * is deallocated by FORB and should not be deallocated here.
+ */
+ void (*peer_destroy)(forb_peer_t *peer);
+ /**
+ * Receives data through a port
+ *
+ * @param port Port to use
+ * @param buf Where to store the received data
+ * @param len Length the buffer @a buf
+ *
+ * @return Length of the received data or negative error code
+ * on error.
+ */
+ ssize_t (*recv)(forb_port_t *port, void *buf, size_t len);
+
+ /**
+ * Broadcasts/multicasts a message. All FORBs connected the
+ * the network/bus represented by the @a port should receive
+ * it.
+ *
+ * This function is used by peer discovery protocol.
+ *
+ * @param port Port to use
+ * @param buf Data to broadcast
+ * @param len Length of the @a data
+ *
+ * @return Zero or positive number on success, negative error
+ * code on error.
+ */
+ ssize_t (*broadcast)(forb_port_t *port, const void *buf, size_t len);
+
+ /** Serializes the protocol specific address */
+ CORBA_boolean (*serialize_addr)(FORB_CDR_Codec *codec, const void *addr);
+
+ /** Deserializes the protocol specific address. The memory for
+ * storing the address should be allocated by forb_malloc(). */
+ CORBA_boolean (*deserialize_addr)(FORB_CDR_Codec *codec, void **addr);
+
+ /** Converts protocol specific address to string */
+ size_t (*addr2str)(char *dest, size_t maxlen, const void *addr);
+
+ /**
+ * Callback caled when the port is registered to FORB just
+ * before reception and discovery threads are started.
+ */
+ void (*register_cb)(forb_port_t *port);
+};
+
+ssize_t forb_proto_send(forb_peer_t *peer, FORB_CDR_Codec *codec);
+
+forb_peer_t *
+forb_get_next_hop(forb_t *forb, forb_server_id *server, fosa_abs_time_t *timeout);
+
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+#include "proto.h"
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <forb/proto_inet.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <sys/epoll.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <ul_log.h>
+#include <unistd.h>
+#include <forb/config.h>
+#include "discovery.h"
+#include <stdlib.h>
+#include <netinet/tcp.h>
+#include "iop.h" /* FIXME: Sending hello should be handled in IOP layer */
+
+/**
+ * @file proto_inet.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 16:10:23 2008
+ *
+ * @brief FORB transport protocol based on INET family sockets.
+ *
+ * UDP is used for broadcasts and TCP for requests/replies. There
+ * exist two uni-drectional connections between any two communicating
+ * peers.
+ */
+
+extern UL_LOG_CUST(ulogd_forb_proto_inet);
+
+#define MCAST_PORT 15514 /**< Port used for multicasts */
+#define MCAST_ADDR "225.15.5.14"
+
+/** Address used by inet protocol. All values are stored in network
+ * byte order. */
+struct inet_addr {
+ struct in_addr addr;
+ uint16_t port; /**< TCP listening port */
+};
+
+/** INET protocol data for ports. */
+struct inet_port {
+ int udp_socket; /**< Socket for sending and receiving broadcasts */
+ int listen_socket; /* */
+ int epoll_fd; /**< File descriptor used by epoll() in inet_receive(). */
+ struct inet_addr addr; /**< Address of this port */
+ int last_recv_fd; /**< Used in inet_recv() to read data longer than receiving buffer */
+ struct in_addr multicast_addr;
+ ul_list_head_t new_peers; /**< List of just connected peers which did not send any data yet. */
+};
+
+UL_LIST_CUST_DEC(inet_port_new_peer, /* cust_prefix */
+ struct inet_port, /* cust_head_t */
+ forb_peer_t, /* cust_item_t */
+ new_peers, /* cust_head_field */
+ lnode) /* cust_node_field */
+
+
+/** INET protocol data associated with every peer */
+struct inet_peer {
+ int socket; /**< Connected socket to the peer */
+};
+
+/* static struct inet_port* */
+/* peer_to_inet_port(forb_peer_t *peer) { return peer->port->desc.proto_priv; } */
+
+static CORBA_boolean
+inet_serialize_addr(FORB_CDR_Codec *codec, const void *addr)
+{
+ const struct inet_addr *a = addr;
+ CORBA_unsigned_long haddr = ntohl(a->addr.s_addr);
+ CORBA_unsigned_short hport = ntohs(a->port);
+ CORBA_boolean ret;
+ ret = CORBA_unsigned_long_serialize(codec, &haddr);
+ if (!ret)
+ return ret;
+ return CORBA_unsigned_short_serialize(codec, &hport);
+}
+
+static CORBA_boolean
+inet_deserialize_addr(FORB_CDR_Codec *codec, void **addr)
+{
+ struct inet_addr *a;
+ CORBA_unsigned_long s_addr;
+ CORBA_unsigned_short port;
+ CORBA_boolean ret;
+
+ a = forb_malloc(sizeof(*a));
+ if (!a)
+ return CORBA_FALSE;
+ ret = CORBA_unsigned_long_deserialize(codec, &s_addr);
+ if (!ret)
+ return ret;
+ ret = CORBA_unsigned_short_deserialize(codec, &port);
+ a->addr.s_addr = htonl(s_addr);
+ a->port = htons(port);
+ *addr = a;
+ return ret;
+}
+
+static int
+setnonblocking(int fd);
+
+static int
+setnodelay(int fd)
+{
+ int ret = 0;
+#if 0 /* For nice graphs in benchmarks */
+ int yes = 1;
+ ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes));
+ if (ret < 0) {
+ ul_logerr("setsockopt(TCP_NODELAY): %s\n", strerror(errno));
+ }
+#endif
+ return ret;
+
+}
+
+static int
+inet_connect(forb_peer_t *peer)
+{
+ struct inet_peer *ipeer;
+ struct sockaddr_in sa;
+ struct inet_addr *addr = peer->addr;
+ int ret;
+
+ if (!addr) {
+ ul_logerr("No address to connect\n");
+ goto err;
+ }
+ ipeer = forb_malloc(sizeof(*ipeer));
+ if (!ipeer)
+ goto err;
+ ipeer->socket = socket(PF_INET, SOCK_STREAM, 0);
+ if (!ipeer->socket) {
+ ul_logerr("socket(): %s\n", strerror(errno));
+ goto err_free;
+ }
+ sa.sin_family = AF_INET;
+ sa.sin_port = addr->port;
+ sa.sin_addr = addr->addr;
+ ul_logtrash("connect to %s:%u\n", inet_ntoa(sa.sin_addr), ntohs(sa.sin_port));
+ ret = connect(ipeer->socket, (struct sockaddr*)&sa, sizeof(sa));
+ if (ret) {
+ ul_logerr("connect error: %s\n", strerror(errno));
+ goto err_close;
+ }
+
+ setnonblocking(ipeer->socket);
+ setnodelay(ipeer->socket);
+
+ struct epoll_event ev;
+ struct inet_port *p = peer->port->desc.proto_priv;
+ memset(&ev, 0, sizeof(ev));
+ ev.events = EPOLLIN | EPOLLET;
+ ev.data.fd = ipeer->socket;
+ ret = epoll_ctl(p->epoll_fd, EPOLL_CTL_ADD, ipeer->socket, &ev);
+ if (ret) {
+ ul_logerr("epoll_ctl on connect failed: %s\n", strerror(errno));
+ goto err_close;
+ }
+
+ peer->proto_priv = ipeer;
+
+#ifndef TEST /* FIXME: Move hello to IOP, introduce proto connect callback */
+ ret = forb_iop_send_hello_to(peer);
+ if (ret) {
+ goto err_close;
+ }
+#endif
+
+ return 0;
+err_close:
+ close(ipeer->socket);
+err_free:
+ forb_free(ipeer);
+err:
+ return -1;
+
+}
+
+static ssize_t
+inet_send(forb_peer_t *peer, const void *buf, size_t len)
+{
+ struct inet_peer *ipeer = peer->proto_priv;
+ ssize_t ret, sent;
+
+ if (!ipeer) {
+ ret = inet_connect(peer);
+ if (ret) {
+ return ret;
+ }
+ ipeer = peer->proto_priv;
+ }
+
+ sent = 0;
+ ul_logtrash("send fd=%d len=%zu\n", ipeer->socket, len);
+ do {
+ ret = send(ipeer->socket, buf, len, 0);
+ if (ret < 0) {
+ ul_logerr("send error: %s\n", strerror(errno));
+ return ret;
+ }
+ sent += ret;
+ buf += ret;
+ len -= ret;
+ } while (len > 0);
+
+ return sent;
+}
+
+/*----------------------------------------------------------------------
+ Portable function to set a socket into nonblocking mode.
+ Calling this on a socket causes all future read() and write() calls on
+ that socket to do only as much as they can immediately, and return
+ without waiting.
+ If no data can be read or written, they return -1 and set errno
+ to EAGAIN (or EWOULDBLOCK).
+ Thanks to Bjorn Reese for this code.
+----------------------------------------------------------------------*/
+int setnonblocking(int fd)
+{
+ int flags;
+
+ /* If they have O_NONBLOCK, use the Posix way to do it */
+#if defined(O_NONBLOCK)
+ /* Fixme: O_NONBLOCK is defined but broken on SunOS 4.1.x and AIX 3.2.5. */
+ if (-1 == (flags = fcntl(fd, F_GETFL, 0)))
+ flags = 0;
+ return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+#else
+ /* Otherwise, use the old way of doing it */
+ flags = 1;
+ return ioctl(fd, FIOBIO, &flags);
+#endif
+}
+
+static int
+inet_accept_connection(forb_port_t *port)
+{
+ struct inet_port *p = port->desc.proto_priv;
+ int client;
+ struct sockaddr_in addr;
+ socklen_t addrlen = sizeof(addr);
+ struct epoll_event ev;
+ int ret;
+ forb_peer_t *peer;
+
+ client = accept(p->listen_socket, (struct sockaddr *) &addr, &addrlen);
+ if (client < 0){
+ //perror("accept");
+ return -1;
+ }
+ ret = setnonblocking(client);
+ if (ret) {
+ close(client);
+ return -1;
+ }
+ setnodelay(client);
+
+ peer = forb_peer_new();
+ if (peer) {
+ struct inet_peer *ipeer;
+
+ ipeer = forb_malloc(sizeof(*ipeer));
+ if (ipeer) {
+ ipeer->socket = client;
+ peer->proto_priv = ipeer;
+ peer->port = port;
+ peer->state = FORB_PEER_DISCOVERED;
+ inet_port_new_peer_insert(p, peer);
+ } else {
+ forb_peer_put(peer);
+ }
+ }
+
+ memset(&ev, 0, sizeof(ev));
+ ev.events = EPOLLIN | EPOLLET;
+ ev.data.fd = client;
+ return epoll_ctl(p->epoll_fd, EPOLL_CTL_ADD, client, &ev);
+}
+
+static ssize_t
+inet_recv(forb_port_t *port, void *buf, size_t len)
+{
+ struct inet_port *iport = port->desc.proto_priv;
+#if 1
+ struct epoll_event ev;
+ ssize_t ret;
+ int nfds;
+ forb_peer_t *peer;
+ bool exported_new_peer = false;
+
+ for (;;) {
+ if (iport->last_recv_fd == -1) {
+ nfds = epoll_wait(iport->epoll_fd, &ev, 1, -1);
+ if (nfds == -1 && errno == EINTR)
+ continue;
+ if (nfds < 1)
+ return -1;
+ if (ev.data.fd == iport->listen_socket) {
+ ret = inet_accept_connection(port);
+ if (ret) {
+ ul_logerr("inet_accept_connection error: %s\n", strerror(errno));
+ return -1;
+ } else
+ continue;
+ } else {
+ iport->last_recv_fd = ev.data.fd;
+ }
+ }
+ /* Check for first reception form a just connected peer */
+ ul_list_for_each(inet_port_new_peer, iport, peer) {
+ struct inet_peer *ipeer = peer->proto_priv;
+ //printf("checking new peer with fd=%d\n", ipeer->socket);
+ if (ipeer->socket == iport->last_recv_fd) {
+ inet_port_new_peer_delete(iport, peer);
+
+ if (port->new_peer) forb_peer_put(peer);
+
+ /* Let the upper layer assign forb ID
+ * to this peer according to the request*/
+ port->new_peer = peer;
+ exported_new_peer = true;
+ break;
+ }
+ }
+
+ //printf("recv fd=%d\n", iport->last_recv_fd);
+ ret = recv(iport->last_recv_fd, buf, len, 0);
+ if (ret == -1) {
+ if (exported_new_peer) {
+ forb_peer_put(peer);
+ port->new_peer = NULL;
+ }
+ if (errno != EAGAIN) {
+ ul_logerr("recv fd=%d error: %s\n", iport->last_recv_fd, strerror(errno));
+ }
+ iport->last_recv_fd = -1;
+ continue;
+ }
+ if (ret == 0) {
+ if (exported_new_peer) {
+ forb_peer_put(peer);
+ port->new_peer = NULL;
+ }
+ ul_logtrash("recv fd=%d disconnect\n", iport->last_recv_fd);
+ ul_list_for_each(forb_port_peer, port, peer) {
+ struct inet_peer *ipeer = peer->proto_priv;
+ if (ipeer && ipeer->socket == iport->last_recv_fd) {
+ forb_peer_disconnected(peer);
+ break;
+ }
+ }
+ iport->last_recv_fd = -1;
+ continue;
+ }
+ ul_logtrash("recv fd=%d len=%zd\n", iport->last_recv_fd, ret);
+ return ret;
+ }
+#else
+ return recv(iport->udp_socket, buf, len, 0);
+#endif
+}
+
+static int
+inet_port_destroy(forb_port_t * port)
+{
+ struct inet_port *pd = port->desc.proto_priv;
+ close(pd->epoll_fd);
+ close(pd->udp_socket);
+ close(pd->listen_socket);
+ forb_free(pd);
+ return 0;
+}
+
+static ssize_t
+inet_broadcast(forb_port_t *port, const void *buf, size_t len)
+{
+ struct inet_port *p = port->desc.proto_priv;
+ struct sockaddr_in addr;
+ ssize_t ret;
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(MCAST_PORT);
+ addr.sin_addr = p->multicast_addr;
+
+ ret = sendto(p->udp_socket, buf, len, 0,
+ (struct sockaddr*)&addr, sizeof(addr));
+ return ret;
+}
+
+static void
+inet_peer_destroy(forb_peer_t *peer)
+{
+ struct inet_peer *ipeer = peer->proto_priv;
+ if (ipeer) {
+ peer->proto_priv = NULL;
+ ul_logtrash("destroying peer fd=%d (orb_id=%s)\n",
+ ipeer->socket, peer->orb_id);
+ close(ipeer->socket);
+ free(ipeer);
+ }
+}
+
+size_t inet_addr2str(char *dest, size_t maxlen, const void *addr)
+{
+ const struct inet_addr *a = addr;
+ size_t ret = 0;
+ if (addr) {
+ snprintf(dest, maxlen, "%s:%d", inet_ntoa(a->addr), ntohs(a->port));
+ }
+ return ret;
+}
+
+#if CONFIG_FCB && CONFIG_FORB_PROTO_INET_DEFAULT
+
+#include <fcb.h>
+#include <fcb_contact_info.h>
+
+static void inet_register_cb(forb_port_t *port)
+{
+ struct inet_addr *ia;
+
+ ia = malloc(sizeof(*ia));
+ if (!ia) return;
+
+ char *fcb_addr = getenv("FCB_ADDR");
+ if (!fcb_addr) fcb_addr = "127.0.0.1";
+ ia->addr.s_addr = inet_addr(fcb_addr);
+ ia->port = htons(FCB_TCP_PORT);
+ forb_new_peer_discovered(port, NULL, FCB_SERVER_ID, ia, "");
+}
+#else
+#define inet_register_cb NULL
+#endif
+
+static const forb_proto_t proto_inet = {
+ .hello_interval = 40 /* seconds */,
+ .port_destroy = inet_port_destroy,
+ .peer_destroy = inet_peer_destroy,
+ .send = inet_send,
+ .recv = inet_recv,
+ .broadcast = inet_broadcast,
+ .serialize_addr = inet_serialize_addr,
+ .deserialize_addr = inet_deserialize_addr,
+ .addr2str = inet_addr2str,
+ .register_cb = inet_register_cb,
+};
+
+#define MAX_INTERFACES 10
+int get_local_address(int sock, struct in_addr *addr)
+{
+ struct ifconf ifc;
+ struct ifreq *ifr, req[MAX_INTERFACES];
+ char *env;
+ bool loopback = false;
+ int ret;
+ struct in_addr env_addr;
+
+ env = getenv("FORB_EXTERNAL_IP");
+ if (env) {
+ if (inet_aton(env, &env_addr) == 0) {
+ ul_logerr("Cannot convert FORB_EXTERNAL_IP\n");
+ errno = EINVAL;
+ return -1;
+ }
+ }
+
+ ifc.ifc_len = sizeof(req);
+ ifc.ifc_req = req;
+
+ if (ioctl(sock, SIOCGIFCONF, &ifc) < 0)
+ return -1;
+ for (ifr = req; ifr < &req[MAX_INTERFACES]; ifr++) {
+ struct sockaddr_in ia;
+ memcpy(&ia, &ifr->ifr_addr, sizeof(ia));
+ ret = ioctl(sock, SIOCGIFFLAGS, ifr);
+ if ((ret == 0) && (ifr->ifr_flags & IFF_UP)) {
+ if (env && env_addr.s_addr == ia.sin_addr.s_addr) {
+ *addr = env_addr;
+ return 0;
+ }
+ if (!(ifr->ifr_flags & IFF_LOOPBACK)) {
+ if (!env) {
+ *addr = ia.sin_addr;
+ return 0;
+ }
+ } else {
+ *addr = ia.sin_addr;
+ loopback = true;
+ }
+ }
+ }
+ if (env) {
+ ul_logerr("FORB_EXTERNAL_IP doesn't match local interface\n");
+ errno = ENODEV;
+ return -1;
+ }
+ if (loopback)
+ return 0;
+ else
+ return -1;
+}
+
+/**
+ * Initializes INET protocol port.
+ *
+ * @param port_desc Port description to initialize.
+ * @return Zero on success, -1 on error and errno is set
+ * appropriately.
+ */
+int
+forb_inet_port_init(struct forb_port_desc *port_desc, struct in_addr listen_on,
+ uint16_t port)
+{
+ int ret;
+ struct inet_port *port_priv;
+ struct sockaddr_in addr;
+ socklen_t len;
+ struct epoll_event ev;
+
+ port_priv = forb_malloc(sizeof(*port_priv));
+ if (!port_priv)
+ return -1;
+
+ memset(port_priv, 0, sizeof(*port_priv));
+ port_priv->last_recv_fd = -1;
+ inet_port_new_peer_init_head(port_priv);
+
+ /* Initialize UDP multicast socket */
+ port_priv->udp_socket = socket(PF_INET, SOCK_DGRAM, 0);
+ if (port_priv->udp_socket == -1) goto err_free;
+
+ int yes = 1;
+ ret = setsockopt(port_priv->udp_socket, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(yes));
+ if (ret)
+ goto err_close_udp;
+
+ int reuse = 1;
+ setsockopt(port_priv->udp_socket, SOL_SOCKET, SO_REUSEADDR, (int *) &reuse, sizeof(reuse));
+ if (ret)
+ goto err_close_udp;
+
+ setnonblocking(port_priv->udp_socket);
+
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT
+ struct ip_mreq mreq;
+ inet_aton(MCAST_ADDR, &port_priv->multicast_addr);
+ mreq.imr_multiaddr = port_priv->multicast_addr;
+ mreq.imr_interface.s_addr = INADDR_ANY;
+ ret = setsockopt(port_priv->udp_socket, IPPROTO_IP,
+ IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
+ if (ret)
+ goto err_close_udp;
+#endif
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(MCAST_PORT);
+ addr.sin_addr = port_priv->multicast_addr;
+
+ ret = bind(port_priv->udp_socket, (struct sockaddr *)&addr, sizeof(addr));
+ if (ret != 0) goto err_close_udp;
+
+ char loop = 1;
+ unsigned loop_size = sizeof(loop);
+ ret = setsockopt(port_priv->udp_socket, IPPROTO_IP,
+ IP_MULTICAST_LOOP, &loop, loop_size);
+ if (ret)
+ goto err_close_udp;
+
+
+ /* Initialize TCP socket */
+ port_priv->listen_socket = socket(PF_INET, SOCK_STREAM, 0);
+ if (port_priv->listen_socket == -1) goto err_close_udp;
+
+ reuse = 1;
+ setsockopt(port_priv->listen_socket, SOL_SOCKET, SO_REUSEADDR, (int *) &reuse, sizeof(reuse));
+ if (ret)
+ goto err_close_listen;
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ addr.sin_addr = listen_on;
+ ret = bind(port_priv->listen_socket, (struct sockaddr *)&addr, sizeof(addr));
+ if (ret != 0) goto err_close_listen;
+ if (setnonblocking(port_priv->listen_socket))
+ goto err_close_listen;
+
+ ret = listen(port_priv->listen_socket, 10);
+ if (ret)
+ goto err_close_listen;
+
+ /* Determine our address and port*/
+ len = sizeof(addr);
+ ret = getsockname(port_priv->listen_socket, (struct sockaddr *)&addr, &len);
+ if (ret) {
+ ul_logerr("Non-loopback inet address not found\n");
+ goto err_close_listen;
+ }
+
+ port_priv->addr.port = addr.sin_port;
+ if (listen_on.s_addr == INADDR_ANY) {
+ if (get_local_address(port_priv->listen_socket, &port_priv->addr.addr)) {
+ goto err_close_listen;
+ }
+ } else
+ port_priv->addr.addr = listen_on;
+
+ /* Initialize epoll descriptor */
+ port_priv->epoll_fd = epoll_create(10);
+ if (port_priv->epoll_fd == -1)
+ goto err_close_listen;
+
+ memset(&ev, 0, sizeof(ev));
+ ev.events = EPOLLIN | EPOLLET;
+ ev.data.fd = port_priv->listen_socket;
+ ret = epoll_ctl(port_priv->epoll_fd, EPOLL_CTL_ADD,
+ port_priv->listen_socket, &ev);
+ if (ret)
+ goto err_close_epoll;
+
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT
+ ev.events = EPOLLIN | EPOLLET;
+ ev.data.fd = port_priv->udp_socket;
+ ret = epoll_ctl(port_priv->epoll_fd, EPOLL_CTL_ADD,
+ port_priv->udp_socket, &ev);
+ if (ret)
+ goto err_close_epoll;
+#endif
+
+ port_desc->proto = &proto_inet;
+ port_desc->proto_priv = port_priv;
+ port_desc->addr = &port_priv->addr;
+ return 0;
+err_close_epoll:
+ close(port_priv->epoll_fd);
+err_close_listen:
+ ret = errno;
+ close(port_priv->listen_socket);
+ errno = ret;
+err_close_udp:
+ ret = errno;
+ close(port_priv->udp_socket);
+ errno = ret;
+err_free:
+ ret = errno;
+ forb_free(port_priv);
+ errno = ret;
+ return -1;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ *
+ * @file proto_inet.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 19:03:10 2008
+ *
+ * @brief Prototypes for INET transport protocol
+ */
+
+#ifndef FORB_PROTO_INET_H
+#define FORB_PROTO_INET_H
+
+#include <forb/port.h>
+#include <netinet/in.h>
+#include <stdint.h>
+
+int forb_inet_port_init(struct forb_port_desc *port_desc, struct in_addr listen_on,
+ uint16_t port);
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+#include <dirent.h>
+#include "proto.h"
+#include <forb/proto_unix.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+
+/**
+ * @file proto_unix.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 16:10:23 2008
+ *
+ * @brief FORB transport protocol based on UNIX DGRAM sockets.
+ *
+ * The sockets are created in filesystem in #FORB_TMP_DIR directory.
+ */
+
+
+typedef struct sockaddr_un unix_addr_t;
+
+/** UNIX protocol data for ports. */
+struct unix_port {
+ int socket;
+ unix_addr_t addr;
+};
+
+static struct unix_port*
+peer_to_uport(forb_peer_t *peer) { return peer->port->desc.proto_priv; }
+
+static void
+unix_server_to_addr(unix_addr_t *addr, const forb_server_id *server)
+{
+ char str[65];
+ addr->sun_family = AF_UNIX;
+ sprintf(addr->sun_path, FORB_TMP_DIR "/sock.%s",
+ forb_uuid_to_string(str, (forb_uuid_t*)server->uuid, sizeof(str)));
+}
+
+static ssize_t
+unix_send(forb_peer_t *peer, const void *buf, size_t len)
+{
+ unix_addr_t addr;
+ struct unix_port *p = peer_to_uport(peer);
+ //printf("send to %s\n", c->addr.sun_path);
+ unix_server_to_addr(&addr, &peer->server_id);
+ return sendto(p->socket, buf, len, 0,
+ (struct sockaddr*)&addr, sizeof(addr));
+}
+
+static ssize_t
+unix_recv(forb_port_t *port, void *buf, size_t len)
+{
+ struct unix_port *p = port->desc.proto_priv;
+ return recv(p->socket, buf, len, 0);
+}
+
+static int
+unix_port_destroy(forb_port_t * port)
+{
+ struct unix_port *pd = port->desc.proto_priv;
+ unix_addr_t addr;
+ socklen_t len = sizeof(addr);
+ getsockname(pd->socket, (struct sockaddr*)&addr, &len);
+ if (addr.sun_family == AF_UNIX)
+ unlink(addr.sun_path);
+ close(pd->socket);
+ forb_free(pd);
+ return 0;
+}
+
+static ssize_t
+unix_broadcast(forb_port_t *port, const void *buf, size_t len)
+{
+ struct unix_port *p = port->desc.proto_priv;
+ DIR *dir;
+ struct dirent *dirent;
+ unix_addr_t addr;
+ int ret;
+ int success = 0;
+
+ dir = opendir(FORB_TMP_DIR);
+ if (!dir) return -errno;
+
+ addr.sun_family = AF_UNIX;
+
+ while ((dirent = readdir(dir))) {
+ bool forb_socket =
+#ifdef _DIRENT_HAVE_D_TYPE
+ (dirent->d_type == DT_SOCK ||
+ dirent->d_type == DT_UNKNOWN) &&
+#else
+#warning This system does not support _DIRENT_HAVE_D_TYPE
+#endif
+ (strncmp(dirent->d_name, "sock.", 5) == 0);
+
+/* printf("d_name=%s d_type=%d (%d)\n", dirent->d_name, dirent->d_type, DT_SOCK); */
+ if (forb_socket)
+ {
+ strcpy(addr.sun_path, FORB_TMP_DIR "/");
+ strncat(addr.sun_path, dirent->d_name, sizeof(addr.sun_path));
+/* printf("Broadcasting to %s\n", addr.sun_path); */
+ ret = sendto(p->socket, buf, len, 0,
+ (struct sockaddr*)&addr, sizeof(addr));
+ /* We do not care about errors in brodcasts -
+ * the socket may nomore be active */
+ if (ret == len) {
+ success++;
+ } else if (ret < 0 && errno == ECONNREFUSED) {
+ /* Try to unlink stale socket */
+ unlink(addr.sun_path);
+ } else {
+/* perror("unix_broadcast"); */
+/* return ret; */
+ }
+ }
+
+ }
+ closedir(dir);
+ if (success) {
+ ret = len;
+ } else {
+ ret = -1;
+ }
+ return ret;
+}
+
+static const forb_proto_t proto_unix = {
+ .hello_interval = 40 /* seconds */,
+ .port_destroy = unix_port_destroy,
+ .peer_destroy = NULL,
+ .send = unix_send,
+ .recv = unix_recv,
+ .broadcast = unix_broadcast,
+ /* We do not need the following functions, sice the address
+ * can be derived from server_id */
+ .serialize_addr = NULL,
+ .deserialize_addr = NULL,
+};
+
+/**
+ * Initializes UNIX protocol port.
+ *
+ * @param port Port to initialize.
+ * @param server Server this port belongs to.
+ *
+ * @return Zero on success, -1 on error and errno is set
+ * appropriately.
+ */
+int
+forb_unix_port_init(struct forb_port_desc *port_desc, const forb_server_id *server)
+{
+
+ int ret;
+ struct unix_port *pd;
+
+ ret = forb_init_tmp_dir();
+
+ pd = forb_malloc(sizeof(*pd));
+ if (!pd)
+ return -1;
+
+ pd->socket = socket(PF_UNIX, SOCK_DGRAM, 0);
+ if (pd->socket == -1) goto err1;
+
+ unix_server_to_addr(&pd->addr, server);
+ /* unlink(pd->addr.sun_path); */ /* TODO: What to do when the socket already exist? */
+ ret = bind(pd->socket, (struct sockaddr*)&pd->addr, sizeof(pd->addr));
+ chmod(pd->addr.sun_path, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+ if (ret == -1) goto err;
+
+ port_desc->proto = &proto_unix;
+ port_desc->proto_priv = pd;
+ return 0;
+err:
+ ret = errno;
+ close(pd->socket);
+ errno = ret;
+err1:
+ ret = errno;
+ forb_free(pd);
+ errno = ret;
+ return -1;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ *
+ * @file proto_unix.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 19:03:10 2008
+ *
+ * @brief Prototypes for UNIX transport protocol
+ */
+
+#ifndef FORB_PROTO_UNIX_H
+#define FORB_PROTO_UNIX_H
+
+int forb_unix_port_init(struct forb_port_desc *port_desc,
+ const forb_server_id *server);
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file refcnt.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Wed Oct 1 09:23:40 2008
+ *
+ * @brief Atomic reference counting operations.
+ *
+ * @note To provide portable atomicity, we use GCC's builtin
+ * functions introduced in GCC 4.1.
+ *
+ */
+#include "refcnt.h"
+
+void forb_ref_set(struct forb_ref *ref, int num)
+{
+ ref->refcount = num;
+}
+
+/**
+ * Initializes reference count to 1.
+ *
+ * @param ref
+ */
+void forb_ref_init(struct forb_ref *ref)
+{
+ forb_ref_set(ref, 1);
+}
+
+/**
+ * Atomicaly increases reference count
+ *
+ * @param ref
+ */
+void forb_ref_get(struct forb_ref *ref)
+{
+ __sync_add_and_fetch(&ref->refcount, 1);
+}
+
+/**
+ * Atomicaly decreases reference count and if zero is reached calls, @a
+ * release function (destructor).
+ *
+ * @param ref Reference to act on.
+ * @param release Release function called when reference count reaches zero.
+ *
+ * @return 1 if the @a release function was called, zero othewise
+ * (which doesn't mean that the object still exist in memory as it
+ * might be released by somebody else in the mean time).
+ */
+int forb_ref_put(struct forb_ref *ref, void (*release) (struct forb_ref *ref))
+{
+ if (__sync_add_and_fetch(&ref->refcount, -1) == 0) {
+ release(ref);
+ return 1;
+ }
+ return 0;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+#ifndef FORB_REFCNT_H
+#define FORB_REFCNT_H
+
+/**
+ * @file refcnt.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 16:03:51 2008
+ *
+ * @brief Atomic reference counting types and prototypes.
+ *
+ *
+ */
+
+
+/**
+ * Reference counter type
+ *
+ */
+struct forb_ref {
+ unsigned refcount;
+};
+
+typedef struct forb_ref forb_ref_t;
+
+void forb_ref_set(struct forb_ref *ref, int num);
+void forb_ref_init(struct forb_ref *ref);
+void forb_ref_get(struct forb_ref *ref);
+int forb_ref_put(struct forb_ref *ref, void (*release) (struct forb_ref *ref));
+
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+#include "regref.h"
+#include "object.h"
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ul_log.h>
+#include <forb/config.h>
+
+extern UL_LOG_CUST(ulogd_forb_regref);
+
+static inline int forb_regref_cmp(const forb_regref_name_t *a, const forb_regref_name_t *b)
+{
+ return strncmp(a->str, b->str, FORB_REGREF_NAME_LEN);
+}
+
+GAVL_CUST_NODE_INT_IMP(forb_regref_nolock /* cust_prefix */,
+ forb_t /* cust_root_t */,
+ forb_regref_t /* cust_item_t */,
+ forb_regref_name_t /* cust_key_t */,
+ regrefs /* cust_root_node */,
+ node /* cust_item_node */,
+ name /* cust_item_key */,
+ forb_regref_cmp/* cust_cmp_fnc */);
+
+/**
+ * Allocates a new ::forb_regref_t structure and fills it with data.
+ *
+ * @param object Object reference to register.
+ *
+ * @param name Name of the registered object reference, which can be
+ * used by other applications in forb_resolve_reference().
+ *
+ * @return Pointer to the newly allocated regref of NULL in case of error.
+ */
+forb_regref_t *
+forb_regref_new(forb_object object, forb_regref_name_t name)
+{
+ forb_regref_t *regref;
+
+ regref = forb_malloc(sizeof(*regref));
+ if (regref) {
+ regref->name = name;
+ regref->object = forb_object_duplicate(object);
+ }
+ return regref;
+}
+
+/**
+ * Releases ::forb_regref_t previously allocated by forb_regref_new().
+ *
+ * @param regref Regref to release.
+ */
+void
+forb_regref_release(forb_regref_t *regref)
+{
+ if (regref) {
+ forb_object_release(regref->object);
+ forb_free(regref);
+ }
+}
+
+
+
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT
+/**
+ *
+ *
+ * @param fd
+ * @param objref
+ *
+ * @return Zero on success, -1 on error.
+ */
+static int
+rewrite_regref(int fd, const char *objref)
+{
+ int ret;
+ int len = strlen(objref);
+ lseek(fd, 0, SEEK_SET);
+ ftruncate(fd, 0);
+
+ while (len > 0) {
+ ret = write(fd, objref, len);
+ if (ret < 0) goto out;
+ len -= ret;
+ objref += ret;
+ }
+ ret = 0; /* Success */
+out:
+ return ret;
+}
+
+/**
+ *
+ *
+ * @param orb
+ * @param fn File name
+ * @param objref string form of the object reference
+ *
+ * @return -1 on error, 0 if reference was replaced and 1 in the
+ * reference is valid.
+ */
+static int
+replace_regref_if_stale(forb_orb orb, const char *fn, const char *objref)
+{
+ int fd, ret = 0;
+ char str[100];
+ forb_object object;
+
+ fd = open(fn, O_RDWR);
+ if (fd < 0) {
+ ret = -1;
+ goto out;
+ }
+ ret = lockf(fd, F_LOCK, 0);
+ if (ret < 0) goto close_err;
+ ret = read(fd, str, sizeof(str)-1);
+ if (ret < 0) goto unlock_err;
+ /* TODO: Check that we have read the whole file */
+
+ str[ret] = '\0';
+ object = forb_string_to_object(orb, str);
+ if (!object) {
+ /* reference is unreadable, so we can replace it */
+ ret = rewrite_regref(fd, objref);
+ /* We are done for now */
+ goto unlock_err;
+ }
+ if (forb_object_is_stale(object)) {
+ /* Orb is not alive */
+ ret = rewrite_regref(fd, objref);
+ } else {
+ /* Reference's FORB is alive :-( */
+ ret = 1;
+ }
+
+ forb_object_release(object);
+unlock_err:
+ lockf(fd, F_ULOCK, 0);
+close_err:
+ close(fd);
+out:
+ return ret;
+}
+#endif
+
+/**
+ * Registers a given object reference so that other FORBs on the same
+ * node can find it by using forb_resolve_reference().
+ *
+ * @param object Object reference to register.
+ * @param name Name under which to register the reference.
+ *
+ * @return Zero on success, -1 on error.
+ */
+int
+forb_register_reference(forb_object object, const char *name)
+{
+ forb_regref_t *regref;
+ forb_regref_name_t regname;
+ forb_t *forb = forb_object_to_forb(object);
+
+ strncpy(regname.str, name, FORB_REGREF_NAME_LEN-1);
+ regname.str[FORB_REGREF_NAME_LEN-1]='\0';
+
+ regref = forb_regref_new(object, regname);
+ if (!regref) goto err;
+
+ forb_regref_insert(forb, regref);
+
+#ifdef CONFIG_FORB_PROTO_INET_DEFAULT
+ return 0;
+#else
+ char fn[100], fntmp[100];
+ char *objref;
+ FILE *f;
+ int ret;
+ snprintf(fn, sizeof(fn), FORB_TMP_DIR "/%s", regname.str);
+ snprintf(fntmp, sizeof(fntmp), FORB_TMP_DIR "/%s.%s", regname.str,
+ forb->server_id_str);
+
+ f = fopen(fntmp, "w");
+ if (!f) goto unalloc_err;
+
+ objref = forb_object_to_string(object);
+ if (!objref) goto unlink_err;
+
+ ret = fprintf(f, "%s", objref);
+ if (ret < 0) goto free_objref_err;
+
+ ret = fclose(f);
+ if (ret == EOF) goto free_objref_err;
+
+ /* Make the atomic registration in filesystem */
+ ret = link(fntmp, fn);
+
+ if (ret < 0 && errno == EEXIST) {
+ /* The reference exists. Try whether it is still
+ * active. */
+ if (replace_regref_if_stale(object->orb, fn, objref) != 0) {
+ goto free_objref_err;
+ }
+ ul_logdeb("Stale registration replaced\n");
+ } else if (ret < 0) {
+ goto free_objref_err;
+ }
+
+ forb_free(objref);
+
+ /* Unlink the temporary filename */
+ unlink(fntmp);
+
+ return 0;
+free_objref_err:
+ ret = errno;
+ forb_free(objref);
+ errno = ret;
+unlink_err:
+ ret = errno;
+ unlink(fntmp);
+ errno = ret;
+unalloc_err:
+ ret = errno;
+ forb_regref_delete(forb, regref);
+ forb_regref_release(regref);
+ errno = ret;
+#endif
+err:
+ return -1;
+}
+
+/**
+ * Unregister reference previously registered by
+ * forb_register_reference().
+ *
+ * @param orb forb::orb reference
+ * @param name Name to unregister.
+ *
+ * @return Zero on success, -1 on error.
+ */
+int
+forb_unregister_reference(forb_orb orb, const char *name)
+{
+ forb_regref_t *regref;
+ forb_regref_name_t regname;
+ forb_t *forb = forb_object_to_forb(orb);
+
+ strncpy(regname.str, name, FORB_REGREF_NAME_LEN-1);
+ regname.str[FORB_REGREF_NAME_LEN-1]='\0';
+
+ regref = forb_regref_find(forb, ®name);
+ if (!regref) goto err;
+
+ forb_regref_delete(forb, regref);
+ forb_regref_release(regref);
+
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT
+ char fn[100];
+ snprintf(fn, sizeof(fn), FORB_TMP_DIR "/%s", regname.str);
+ return unlink(fn);
+#endif
+
+ return 0;
+err:
+ return -1;
+}
+
+/**
+ * Returns a named reference previously registered by
+ * forb_register_reference(). This function can be called even if the
+ * reference was registered in a diferent process (but on the same
+ * node).
+ *
+ * @param orb Local orb object reference
+ * @param name Name under which the reference was registered.
+ *
+ * @return Object reference on NULL in case of error.
+ */
+forb_object
+forb_resolve_reference(const forb_orb orb, const char *name)
+{
+ forb_regref_name_t regname;
+ forb_object object;
+
+ strncpy(regname.str, name, FORB_REGREF_NAME_LEN-1);
+ regname.str[FORB_REGREF_NAME_LEN-1]='\0';
+
+#ifdef CONFIG_FORB_PROTO_INET_DEFAULT
+ forb_regref_t *regref;
+ forb_t *forb = forb_object_to_forb(orb);
+
+ regref = forb_regref_find(forb, ®name);
+ if (!regref) return NULL;
+
+ object = forb_object_duplicate(regref->object);
+ return object;
+
+#else
+ char fn[100];
+ char str[100];
+ int fd, ret;
+
+ snprintf(fn, sizeof(fn), FORB_TMP_DIR "/%s", regname.str);
+
+ fd = open(fn, 0);
+ if (fd < 0) {
+ return NULL;
+ }
+ ret = read(fd, str, sizeof(str)-1);
+ /* TODO: Check that we have read the whole file */
+ str[ret] = '\0';
+ object = forb_string_to_object(orb, str);
+ close(fd);
+#endif
+
+ if (forb_object_is_stale(object)) {
+ forb_object_release(object);
+ object = NULL;
+ }
+ return object;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file regref.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sat Oct 11 14:46:08 2008
+ *
+ * @brief Handling of registered object references.
+ *
+ *
+ */
+
+#ifndef FORB_REGREF_H
+#define FORB_REGREF_H
+
+#include <forb.h>
+#include <forb/forb-internal.h>
+#include <ul_gavl.h>
+
+#define FORB_REGREF_NAME_LEN 32
+
+/**
+ * Type for registered names
+ *
+ * We must encapsulate the array in structure in order to behave as
+ * normal C object. This is necessary for usage as GAVL key. The
+ * reason is that typeof(&array) == typeof(array).
+ */
+typedef struct {
+ char str[FORB_REGREF_NAME_LEN];
+} forb_regref_name_t;
+
+struct forb_regref {
+ forb_regref_name_t name; /**< Name of the registered reference */
+ forb_object object; /**< Registered object reference */
+ gavl_node_t node; /**< Node for forb->regrefs tree */
+};
+
+typedef struct forb_regref forb_regref_t;
+
+GAVL_CUST_NODE_INT_DEC(forb_regref_nolock /* cust_prefix */,
+ forb_t /* cust_root_t */,
+ forb_regref_t /* cust_item_t */,
+ forb_regref_name_t /* cust_key_t */,
+ regrefs /* cust_root_node */,
+ node /* cust_item_node */,
+ name /* cust_item_key */,
+ forb_regref_cmp/* cust_cmp_fnc */);
+
+
+forb_regref_t *
+forb_regref_new(forb_object object, forb_regref_name_t name);
+
+void
+forb_regref_release(forb_regref_t *regref);
+
+static inline void
+forb_regref_insert(forb_t *forb, forb_regref_t *regref)
+{
+ pthread_mutex_lock(&forb->regref_mutex);
+ forb_regref_nolock_insert(forb, regref);
+ pthread_mutex_unlock(&forb->regref_mutex);
+}
+
+static inline void
+forb_regref_delete(forb_t *forb, forb_regref_t *regref)
+{
+ pthread_mutex_lock(&forb->regref_mutex);
+ forb_regref_nolock_delete(forb, regref);
+ pthread_mutex_unlock(&forb->regref_mutex);
+}
+
+static inline forb_regref_t *
+forb_regref_find(forb_t *forb, forb_regref_name_t const *name)
+{
+ forb_regref_t *regref;
+ pthread_mutex_lock(&forb->regref_mutex);
+ regref = forb_regref_nolock_find(forb, name);
+ pthread_mutex_unlock(&forb->regref_mutex);
+ return regref;
+}
+
+static inline forb_regref_t *
+forb_regref_first(forb_t *forb)
+{
+ forb_regref_t *regref;
+ pthread_mutex_lock(&forb->regref_mutex);
+ regref = forb_regref_nolock_first(forb);
+ pthread_mutex_unlock(&forb->regref_mutex);
+ return regref;
+}
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file request.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 19:04:21 2008
+ *
+ * @brief Implementation of request handling functions
+ *
+ *
+ */
+
+#include <forb/forb-internal.h>
+#include "request.h"
+#include <forb/iop-idl.h>
+#include <forb/object.h>
+#include "peer.h"
+#include "iop.h"
+#include "proto.h"
+#include <ul_log.h>
+
+extern UL_LOG_CUST(ulogd_forb_request);
+
+static inline int forb_request_cmp(const CORBA_unsigned_long *a,
+ const CORBA_unsigned_long *b)
+{
+ return (*a<*b) ? -1 :
+ ((*a>*b) ? +1 :
+ 0);
+}
+
+GAVL_CUST_NODE_INT_IMP(forb_request_nolock /* cust_prefix */,
+ forb_t /* cust_root_t */,
+ forb_request_t /* cust_item_t */,
+ CORBA_unsigned_long /* cust_key_t */,
+ requests /* cust_root_node */,
+ node /* cust_item_node */,
+ request_id /* cust_item_key */,
+ forb_request_cmp/* cust_cmp_fnc */);
+
+/**
+ * Initializes @a req structure for sending new request to object @a obj.
+ *
+ * @param req Request structure to initialize
+ * @param obj Destination object
+ *
+ * @return Zero on success, FOSA error code on error.
+ */
+int
+forb_request_init(forb_request_t *req, forb_object obj)
+{
+ int ret = 0;
+ forb_t *forb = forb_object_to_forb(obj);
+ CORBA_boolean bret;
+
+ memset(req, 0, sizeof(*req));
+ req->obj = obj;
+
+ fosa_mutex_lock(&forb->request_id_mutex);
+ req->request_id = forb->request_id++;
+ fosa_mutex_unlock(&forb->request_id_mutex);
+
+ FORB_CDR_codec_init_static(&req->cdr_request, obj->orb);
+ bret = FORB_CDR_buffer_init(&req->cdr_request, 4096-8, forb_iop_MESSAGE_HEADER_SIZE);
+ if (bret == CORBA_FALSE) {
+ return FOSA_ENOMEM;
+ }
+
+ ret = forb_syncobj_init(&req->reply_ready, 0);
+ return ret;
+}
+
+void
+forb_request_destroy(forb_request_t *req)
+{
+ forb_t *forb = forb_object_to_forb(req->obj);
+
+ forb_request_delete(forb, req);
+ FORB_CDR_codec_release_buffer(&req->cdr_request);
+ forb_syncobj_destroy(&req->reply_ready);
+}
+
+void
+forb_request_signal_reply(forb_request_t *req)
+{
+ forb_syncobj_signal(&req->reply_ready);
+}
+
+void
+forb_request_wait_for_reply(forb_request_t *req)
+{
+ fosa_abs_time_t timeout;
+ int ret;
+
+ /* FIXME: What is the appropriate length for timeout? Maybe,
+ * we can specify timeout in forb_env, but since it is
+ * out-direction parameter, we cannot distinguish between
+ * initialized and uninitialized env.timeout. */
+ fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &timeout);
+ timeout = fosa_abs_time_incr(timeout,
+ fosa_msec_to_rel_time(10000));
+
+ ret = forb_syncobj_timedwait(&req->reply_ready, &timeout);
+
+ if (ret == ETIMEDOUT) {
+ req->env->major = FORB_EX_TIMEOUT;
+ } else if (ret) {
+ req->env->major = FORB_EX_INTERNAL;
+ }
+}
+
+void
+forb_request_signal_processed(forb_request_t *req)
+{
+ /* Signal, that we are done */
+ forb_syncobj_signal(req->reply_processed);
+}
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+#ifndef REQUEST_H
+#define REQUEST_H
+
+/**
+ * @file request.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 15:50:30 2008
+ *
+ * @brief Data type and functions for manipulation with requests.
+ *
+ *
+ */
+
+
+#include <forb.h>
+#include <forb/cdr.h>
+#include <forb/basic_types.h>
+#include <forb/syncobj.h>
+#include <ul_gavlcust.h>
+#include <forb/forb-internal.h>
+
+
+
+/**
+ * Helper structure for sending ORB requests.
+ *
+ * Its purpose is to match incomming reply messages to previously sent
+ * requests. It is allocated in stub's stack and during waiting for
+ * reply is stored in forb_t::requests tree.
+ *
+ */
+struct forb_request {
+ CORBA_unsigned_long request_id; /**< Numeric ID of this request. Used to match replies agains this request. */
+ FORB_CDR_Codec cdr_request; /**< Buffer for the request serialization. */
+ FORB_CDR_Codec *cdr_reply; /**< Buffer with received reply. */
+ gavl_node_t node; /**< forb_t::requests node */
+ forb_object obj; /**< Object being requested. */
+ struct forb_env *env; /**< Where to store exception returned in reply */
+ forb_syncobj_t reply_ready; /**< Synchronization object for waiting for reply */
+ forb_syncobj_t *reply_processed; /**< Synchronization object for receiver thread to wait for stub. */
+};
+
+typedef struct forb_request forb_request_t;
+
+/* Declaration of AVL tree for storing sent requests. */
+GAVL_CUST_NODE_INT_DEC(forb_request_nolock /* cust_prefix */,
+ forb_t /* cust_root_t */,
+ forb_request_t /* cust_item_t */,
+ CORBA_unsigned_long /* cust_key_t */,
+ requests /* cust_root_node */,
+ node /* cust_item_node */,
+ request_id /* cust_item_key */,
+ forb_request_cmp/* cust_cmp_fnc */);
+
+static inline int
+forb_request_insert(forb_t *forb, forb_request_t *req)
+{
+ int ret;
+ fosa_mutex_lock(&forb->request_mutex);
+ ret = forb_request_nolock_insert(forb, req);
+ fosa_mutex_unlock(&forb->request_mutex);
+ return ret;
+}
+
+static inline void
+forb_request_delete(forb_t *forb, forb_request_t *req)
+{
+ fosa_mutex_lock(&forb->request_mutex);
+ forb_request_nolock_delete(forb, req);
+ fosa_mutex_unlock(&forb->request_mutex);
+}
+
+static inline forb_request_t *
+forb_request_find(forb_t *forb, CORBA_unsigned_long *request_id)
+{
+ forb_request_t *ret;
+ fosa_mutex_lock(&forb->request_mutex);
+ ret = forb_request_nolock_find(forb, request_id);
+ fosa_mutex_unlock(&forb->request_mutex);
+ return ret;
+}
+
+int
+forb_request_init(forb_request_t *req, forb_object obj);
+void
+forb_request_destroy(forb_request_t *req);
+void
+forb_request_wait_for_reply(forb_request_t *req);
+void
+forb_request_signal_processed(forb_request_t *req);
+
+#endif
--- /dev/null
+#ifndef FORB_SERVER_ID_H
+#define FORB_SERVER_ID_H
+
+#include <forb/uuid.h>
+#include <forb/types.h>
+
+void
+forb_server_id_init(forb_server_id *serer);
+
+/**
+ * Compares to server IDs.
+ *
+ * @param id1
+ * @param id2
+ *
+ * @return -1, 0 or 1 if the @a id1 is less, equal on greated to @a id2 respectively.
+ */
+static inline int forb_server_id_cmp(const forb_server_id *id1, const forb_server_id *id2)
+{
+ return memcmp(id1, id2, sizeof(forb_server_id));
+}
+
+/**
+ * Converts a server ID to string.
+ *
+ * @param dest Where to store the converted string.
+ * @param server_id Server ID to convert.
+ * @param n The size of @a dest memory buffer.
+ *
+ * @return Same value as @a dest.
+ */
+static inline char *
+forb_server_id_to_string(char *dest, const forb_server_id *server_id, size_t n)
+{
+ return forb_uuid_to_string(dest, (forb_uuid_t*)server_id->uuid, n);
+}
+
+/**
+ * Initializes server ID from string.
+ *
+ * @param server_id Initialized server ID.
+ * @param string String form of server ID.
+ *
+ * @return Same value as @a server_id.
+ */
+static inline forb_server_id *
+forb_server_id_from_string(forb_server_id *server_id, const char *string)
+{
+ return (forb_server_id *)forb_uuid_from_string((forb_uuid_t*)&server_id->uuid, string);
+}
+
+
+static inline bool
+forb_server_id_empty(const forb_server_id *server_id)
+{
+ unsigned i;
+ for (i=0; i<sizeof(server_id); i++) {
+ if (server_id->uuid[i] != 0)
+ return false;
+ }
+ return true;
+}
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/*
+SHA-1 in C
+By Steve Reid <steve@edmweb.com>
+100% Public Domain
+
+Test Vectors (from FIPS PUB 180-1)
+"abc"
+ A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+A million repetitions of "a"
+ 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+/* #define LITTLE_ENDIAN * This should be #define'd if true. */
+/* #define SHA1HANDSOFF * Copies data before messing with it. */
+
+/* #include <stdio.h> */
+#include <inttypes.h>
+#include <string.h>
+#include "sha1.h"
+
+/* Extract endinaning from glibc */
+#include <endian.h>
+#undef LITTLE_ENDIAN
+#ifdef __BYTE_ORDER
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define LITTLE_ENDIAN
+#endif
+#endif
+
+void SHA1Transform(uint32_t state[5], uint8_t buffer[64]);
+void SHA1Init(SHA1_CTX* context);
+void SHA1Update(SHA1_CTX* context, uint8_t* data, unsigned int len);
+void SHA1Final(uint8_t digest[20], SHA1_CTX* context);
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#ifdef LITTLE_ENDIAN
+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+ |(rol(block->l[i],8)&0x00FF00FF))
+#else
+#define blk0(i) block->l[i]
+#endif
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+ ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+
+void SHA1Transform(uint32_t state[5], uint8_t buffer[64])
+{
+uint32_t a, b, c, d, e;
+typedef union {
+ uint8_t c[64];
+ uint32_t l[16];
+} CHAR64LONG16;
+CHAR64LONG16* block;
+#ifdef SHA1HANDSOFF
+static uint8_t workspace[64];
+ block = (CHAR64LONG16*)workspace;
+ memcpy(block, buffer, 64);
+#else
+ block = (CHAR64LONG16*)buffer;
+#endif
+ /* Copy context->state[] to working vars */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ /* 4 rounds of 20 operations each. Loop unrolled. */
+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+ /* Add the working vars back into context.state[] */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ /* Wipe variables */
+ a = b = c = d = e = 0;
+}
+
+
+/* SHA1Init - Initialize new context */
+
+void SHA1Init(SHA1_CTX* context)
+{
+ /* SHA1 initialization constants */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xEFCDAB89;
+ context->state[2] = 0x98BADCFE;
+ context->state[3] = 0x10325476;
+ context->state[4] = 0xC3D2E1F0;
+ context->count[0] = context->count[1] = 0;
+}
+
+
+/* Run your data through this. */
+
+void SHA1Update(SHA1_CTX* context, uint8_t* data, unsigned int len)
+{
+unsigned int i, j;
+
+ j = (context->count[0] >> 3) & 63;
+ if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
+ context->count[1] += (len >> 29);
+ if ((j + len) > 63) {
+ memcpy(&context->buffer[j], data, (i = 64-j));
+ SHA1Transform(context->state, context->buffer);
+ for ( ; i + 63 < len; i += 64) {
+ SHA1Transform(context->state, &data[i]);
+ }
+ j = 0;
+ }
+ else i = 0;
+ memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+
+/* Add padding and return the message digest. */
+
+void SHA1Final(uint8_t digest[20], SHA1_CTX* context)
+{
+unsigned long i, j;
+uint8_t finalcount[8];
+
+ for (i = 0; i < 8; i++) {
+ finalcount[i] = (uint8_t)((context->count[(i >= 4 ? 0 : 1)]
+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
+ }
+ SHA1Update(context, (uint8_t *)"\200", 1);
+ while ((context->count[0] & 504) != 448) {
+ SHA1Update(context, (uint8_t *)"\0", 1);
+ }
+ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
+ for (i = 0; i < 20; i++) {
+ digest[i] = (uint8_t)
+ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+ }
+ /* Wipe variables */
+ i = j = 0;
+ memset(context->buffer, 0, 64);
+ memset(context->state, 0, 20);
+ memset(context->count, 0, 8);
+ memset(&finalcount, 0, 8);
+#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
+ SHA1Transform(context->state, context->buffer);
+#endif
+}
+
+
+/*************************************************************/
+
+#if 0
+#include <stdio.h>
+
+int main(int argc, char** argv)
+{
+int i, j;
+SHA1_CTX context;
+uint8_t digest[20], buffer[16384];
+FILE* file;
+
+ if (argc > 2) {
+ puts("Public domain SHA-1 implementation - by Steve Reid <steve@edmweb.com>");
+ puts("Produces the SHA-1 hash of a file, or stdin if no file is specified.");
+ exit(0);
+ }
+ if (argc < 2) {
+ file = stdin;
+ }
+ else {
+ if (!(file = fopen(argv[1], "rb"))) {
+ fputs("Unable to open file.", stderr);
+ exit(-1);
+ }
+ }
+ SHA1Init(&context);
+ while (!feof(file)) { /* note: what if ferror(file) */
+ i = fread(buffer, 1, 16384, file);
+ SHA1Update(&context, buffer, i);
+ }
+ SHA1Final(digest, &context);
+ fclose(file);
+ for (i = 0; i < 5; i++) {
+ for (j = 0; j < 4; j++) {
+ printf("%02X", digest[i*4+j]);
+ }
+ putchar(' ');
+ }
+ putchar('\n');
+ exit(0);
+}
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/*
+SHA-1 in C
+By Steve Reid <steve@edmweb.com>
+100% Public Domain
+*/
+
+#include <inttypes.h>
+
+typedef struct {
+ unsigned long count[2];
+ uint32_t state[5];
+ uint8_t buffer[64];
+} SHA1_CTX;
+
+void SHA1Transform(uint32_t state[5], uint8_t buffer[64]);
+void SHA1Init(SHA1_CTX* context);
+void SHA1Update(SHA1_CTX* context, uint8_t* data, unsigned int len);
+void SHA1Final(uint8_t digest[20], SHA1_CTX* context);
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of DTM (Distributed Transaction Manager)
+//
+// DTM is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. DTM is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with DTM; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including DTM header files in a file,
+// instantiating DTM generics or templates, or linking other files
+// with DTM objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+/**
+ * @file
+ *
+ * @brief Synchronization object used in FORB
+ *
+ * @author
+ * Michael Gonzalez Harbour <mgh@unican.es>
+ * Michal Sojka <sojkam1@fel.cvut.cz>
+ * Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ * @comments
+ *
+ * This module contains the definition of the data object and operations to
+ * create a pool of objects, obtain the id of an unused object, wait upon it,
+ * signal it, and finish using it.
+ *
+ * @license
+ *
+ * See the COPYING file in the FORB's root directory
+ *
+ */
+
+#include "syncobj.h"
+
+/**
+ * Initializes the synchronization object.
+ *
+ * @return Zero on success, FOSA error code on error.
+ **/
+
+int forb_syncobj_init(forb_syncobj_t *syncobj, int ceiling)
+{
+ int err;
+
+ err = fosa_cond_init(&syncobj->cond);
+ if (err != 0) return err;
+
+ syncobj->is_work_done = false;
+
+ err = fosa_mutex_init(&syncobj->mutex, ceiling);
+ if (err != 0) return err;
+
+ return 0;
+}
+
+/**
+ * Destroys all resources related to the synchronization object.
+ **/
+
+int forb_syncobj_destroy(forb_syncobj_t *syncobj)
+{
+ int err;
+
+ err = fosa_cond_destroy(&syncobj->cond);
+ if (err != 0) return err;
+
+ err = fosa_mutex_destroy(&syncobj->mutex);
+ if (err != 0) return err;
+
+ return 0;
+}
+
+/**
+ * Signal the synchronization object.
+ **/
+
+int forb_syncobj_signal(forb_syncobj_t *syncobj)
+{
+ int err;
+
+ err = fosa_mutex_lock(&syncobj->mutex);
+ if (err != 0) return err;
+
+ syncobj->is_work_done = true;
+
+ err = fosa_cond_signal(&syncobj->cond);
+ if (err != 0) goto locked_error;
+
+ err = fosa_mutex_unlock(&syncobj->mutex);
+ if (err != 0) return err;
+
+ return 0;
+
+locked_error:
+ fosa_mutex_unlock(&syncobj->mutex);
+ return err;
+}
+
+static void
+syncobj_cleanup(void *syncobj)
+{
+ forb_syncobj_t *s = syncobj;
+ fosa_mutex_unlock(&s->mutex);
+}
+
+/**
+ * Wait on the synchronization object.
+ **/
+
+int forb_syncobj_wait(forb_syncobj_t *syncobj)
+{
+ int err = 0;
+
+ err = fosa_mutex_lock(&syncobj->mutex);
+ if (err != 0) return err;
+ pthread_cleanup_push(syncobj_cleanup, syncobj);
+
+ while (syncobj->is_work_done == false) {
+ err = fosa_cond_wait(&syncobj->cond,
+ &syncobj->mutex);
+ if (err != 0) goto locked_error;
+ }
+
+ syncobj->is_work_done = false;
+
+locked_error:;
+ pthread_cleanup_pop(1);
+ return err;
+;
+}
+
+/**
+ * Wait on the synchronization object with a timeout.
+ *
+ * @return Zero on success, ETIMEDOUT on timeout or other FOSA error
+ * code on error.
+ **/
+
+int forb_syncobj_timedwait(forb_syncobj_t *syncobj,
+ const struct timespec *abstime)
+{
+ int err = 0;
+
+ err = fosa_mutex_lock(&syncobj->mutex);
+ if (err != 0) return err;
+ pthread_cleanup_push(syncobj_cleanup, syncobj);
+
+ while (syncobj->is_work_done == false) {
+ err = fosa_cond_timedwait(&syncobj->cond,
+ &syncobj->mutex,
+ abstime);
+ if (err != 0) goto locked_error;
+ }
+
+ syncobj->is_work_done = false;
+
+locked_error:;
+ pthread_cleanup_pop(1);
+ return err;
+}
--- /dev/null
+#ifndef SYNC_OBJ_H
+#define SYNC_OBJ_H
+
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of DTM (Distributed Transaction Manager)
+//
+// DTM is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. DTM is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with DTM; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including DTM header files in a file,
+// instantiating DTM generics or templates, or linking other files
+// with DTM objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+/*!
+ * @file syncobj.h
+ *
+ * @brief Synchronization objects
+ *
+ * This module contains the definition of simple synchronization
+ * objects built on top FOSA condition variables.
+ *
+ * @author Michael Gonzalez Harbour <mgh@unican.es>
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ */
+
+#ifndef _SYNC_OBJ_H_
+#define _SYNC_OBJ_H_
+
+#include <fosa_mutexes_and_condvars.h>
+#include <time.h> /* for timespec */
+#include <fosa_opaque_types.h> /* for FOSA_ETIMEDOUT */
+
+/**
+ * Semaphore-like synchronization object build on top of FOSA's
+ * condition variables.
+ */
+typedef struct forb_syncobj {
+ bool is_work_done;
+ fosa_cond_t cond;
+ fosa_mutex_t mutex;
+} forb_syncobj_t;
+
+
+extern int forb_syncobj_init(forb_syncobj_t *syncobj, int ceiling);
+extern int forb_syncobj_destroy(forb_syncobj_t *syncobj);
+extern int forb_syncobj_signal(forb_syncobj_t *syncobj);
+extern int forb_syncobj_wait(forb_syncobj_t *syncobj);
+extern int forb_syncobj_timedwait(forb_syncobj_t *syncobj,
+ const struct timespec *abstime);
+#define FORB_ETIMEDOUT FOSA_ETIMEDOUT
+
+#endif // _SYNC_OBJ_H_
+
+
+#endif
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+SUBDIRS = $(ALL_OMK_SUBDIRS)
+
+test_PROGRAMS += hello_inproc hello_remote test_proto_inet discovery \
+ syncobj regobjref
+ifeq ($(CONFIG_FORB_PROTO_UNIX),y)
+test_PROGRAMS += test_proto_unix
+endif
+
+wvtest_PROGRAMS += sequence
+sequence_SOURCES = sequence.c
+sequence_CLIENT_IDL = sequence.idl
+sequence_LIBS = wvtest
+
+CFLAGS += -DTEST -DWVTEST_CONFIGURED
+INCLUDES += -I.
+
+lib_LOADLIBES = forb ulut fosa rt
+
+hello_inproc_SOURCES = hello_inproc.c hello_impl.c
+hello_inproc_CLIENT_IDL = hello.idl
+hello_inproc_SERVER_IDL = hello.idl
+
+hello_remote_SOURCES = hello_remote.c hello_impl.c
+hello_remote_CLIENT_IDL = hello.idl
+hello_remote_SERVER_IDL = hello.idl
+
+regobjref_SOURCES = regobjref.c hello_impl.c
+regobjref_CLIENT_IDL = hello.idl
+regobjref_SERVER_IDL = hello.idl
+
+include_GEN_HEADERS = hello.h
+
+# test_PROGRAMS += hello_client
+# hello_client_SOURCES = hello_client.c
+# hello_inproc_CLIENT_IDL = hello.idl
+
+# test_PROGRAMS += hello_server
+# hello_server_SOURCES = hello_server.c
+# hello_inproc_SERVER_IDL = hello.idl
+
+test_proto_unix_SOURCES = test_proto_unix.c
+test_proto_inet_SOURCES = test_proto_inet.c
+
+discovery_SOURCES = discovery.c
+
+syncobj_SOURCES = test_syncobj.c
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file discovery.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 19:05:27 2008
+ *
+ * @brief Test for correctness of peer discovery protocol
+ *
+ * Multiple FORB obejcts are created and it is tested whether every
+ * FORB automatically discovers the other FORBs.
+ */
+
+#include <stdbool.h>
+#include <forb.h>
+#include <forb/object.h>
+#include <forb/forb-internal.h>
+#include <forb/config.h>
+#include <unistd.h>
+#include "../proto.h"
+#include "../discovery.h"
+#include <error.h>
+#include <fosa.h>
+#include <stdio.h>
+
+#define NUM_ORBS 5
+
+#if !CONFIG_FORB_PROTO_UNIX && !CONFIG_FORB_PROTO_INET_DEFAULT
+#error This test should only work if there is some local protocol enabled.
+#endif
+
+int main(int argc, char *argv[])
+{
+ forb_orb orb[NUM_ORBS];
+ int i;
+ bool all_peers_found = true;
+ fosa_abs_time_t timeout;
+
+ for (i=0; i<NUM_ORBS; i++) {
+ orb[i] = forb_init(&argc, &argv, NULL);
+ if (!orb[i]) {
+ error(1, errno, "Orb no. %d was not created\n", i);
+ }
+ }
+
+ fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &timeout);
+ timeout = fosa_abs_time_incr(timeout,
+ fosa_msec_to_rel_time(1000));
+
+ /* Check whether all the peers are found */
+ for (i=0; i<NUM_ORBS && all_peers_found; i++) {
+ int j;
+ forb_peer_t *peer;
+ for (j=0; j<NUM_ORBS && all_peers_found; j++) {
+ if (i==j) continue;
+ peer = forb_peer_find_timed(forb_data(orb[i]),
+ &forb_data(orb[j])->server_id,
+ &timeout);
+
+ all_peers_found &= (peer != NULL);
+ if (!all_peers_found) {
+ char id[100];
+ error(1, 0, "Peer %d (%s) was not discovered on node %d",
+ j, forb_uuid_to_string(id,
+ (forb_uuid_t*)&forb_data(orb[i])->server_id.uuid,
+ sizeof(id)),
+ i);
+ }
+ }
+ }
+
+ printf("OK\n");
+ return 0;
+}
--- /dev/null
+/**
+ * @file hello.idl
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 19:07:24 2008
+ *
+ * @brief Definition of hello interface
+ *
+ *
+ */
+interface hello {
+ void message(in string msg);
+};
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file hello_impl.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 19:07:44 2008
+ *
+ * @brief Implementation of hello interfaces shared between multiple
+ * tests.
+ *
+ *
+ */
+
+#include <hello.h>
+#include <stdio.h>
+
+static void message(hello _obj, const CORBA_char * msg, CORBA_Environment *ev)
+{
+ printf("Hello object received: %s\n", msg);
+}
+
+static const struct forb_hello_impl impl = {
+ message
+};
+
+forb_object hello_impl_initialize(forb_orb orb)
+{
+ return forb_hello_new(orb, &impl, NULL);
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file hello_impl.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 19:08:20 2008
+ *
+ * @brief Interface to the common hello implementation
+ *
+ *
+ */
+
+#ifndef HELLO_IMPL_H
+#define HELLO_IMPL_H
+
+#include <hello.h>
+
+forb_object hello_impl_initialize(forb_orb orb);
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file hello_inproc.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 19:08:46 2008
+ *
+ * @brief Test of in-process invocation
+ *
+ *
+ */
+
+#include <hello.h>
+#include "hello_impl.h"
+#include <forb.h>
+#include <error.h>
+
+int main(int argc, char *argv[])
+{
+ forb_orb orb;
+ hello hobj;
+ struct forb_env env;
+ struct forb_init_attr attr = {
+ .orb_id = "hello_inproc"
+ };
+
+ orb = forb_init(&argc, &argv, &attr);
+ if (!orb) {
+ error(1, errno, "Cannot initialize FORB");
+ }
+ hobj = hello_impl_initialize(orb);
+
+ hello_message(hobj, "Hello world!", &env);
+ if (forb_exception_occurred(&env)) {
+ error(1, 0, "FORB exception %d", env.major);
+ }
+
+ return 0;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file hello_remote.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Thu Sep 25 16:05:27 2008
+ *
+ * @brief Test of remote invocation.
+ *
+ * In this test, two FORBs are created, one for running the server of
+ * hello interface and the second for running the client code. Since
+ * the client and server are registered in different FORBs, remote
+ * communication is used even if the two FORBs share the same
+ * memory. This way we can easily test remote communication without
+ * writing separate applications for client and server.
+ */
+
+#include <hello.h>
+#include "hello_impl.h"
+#include <forb.h>
+#include <error.h>
+#include <fosa.h>
+#include <forb/executor.h>
+
+int argc_g;
+char **argv_g;
+
+void *server_thread(void *arg)
+{
+ hello hobj = arg;
+
+ forb_execute_object(hobj);
+ return NULL;
+}
+
+char *start_server()
+{
+ forb_orb orb;
+ hello hobj;
+
+ fosa_thread_id_t tid;
+ struct forb_init_attr attr = {
+ .orb_id = "hello_remote_server"
+ };
+
+ orb = forb_init(&argc_g, &argv_g, &attr);
+ if (!orb) {
+ error(1, errno, "Cannot initialize FORB for server");
+ }
+ hobj = hello_impl_initialize(orb);
+ fosa_thread_create(&tid, NULL, server_thread, hobj);
+
+ return forb_object_to_string(hobj);
+}
+
+
+
+void client(void *arg)
+{
+ forb_orb orb;
+ hello hobj;
+ struct forb_env env;
+ char *objref = arg;
+ struct forb_init_attr attr = {
+ .orb_id = "hello_remote_client"
+ };
+
+ orb = forb_init(&argc_g, &argv_g, &attr);
+ if (!orb) {
+ error(1, errno, "Cannot initialize FORB for server");
+ }
+
+ hobj = forb_string_to_object(orb, objref);
+ if (!hobj) {
+ error(1, 0, "Cannot create object reference from the string (%s)\n", objref);
+ }
+
+ hello_message(hobj, "Hello world!", &env);
+ if (forb_exception_occurred(&env)) {
+ error(1, 0, "FORB exception %d", env.major);
+ }
+
+}
+
+int main(int argc, char *argv[])
+{
+
+ char *objref_str;
+
+ argc_g = argc;
+ argv_g = argv;
+
+ objref_str = start_server();
+
+ client(objref_str);
+
+ return 0;
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+test_PROGRAMS = obj2str
+obj2str_SOURCES = obj2str.c
+obj2str_SERVER_IDL = interface.idl
+
+CFLAGS += -I.
+
+
+lib_LOADLIBES = forb ulut fosa rt
--- /dev/null
+interface i {
+ void method();
+};
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file obj2str.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 19:10:23 2008
+ *
+ * @brief Test for forb_object_to_string() and forb_string_to_object()
+ *
+ *
+ */
+
+#include <forb.h>
+#include <stdio.h>
+#include "interface.h"
+#include <error.h>
+#include <string.h>
+
+struct forb_i_impl i_impl = { NULL };
+
+int main(int argc, char *argv[])
+{
+ forb_object orb, obj, obj2;
+ char *str, *str2;
+ struct forb_init_attr attr = {
+ .orb_id = "obj2str"
+ };
+
+ orb = forb_init(&argc, &argv, &attr);
+
+ obj = forb_i_new(orb, &i_impl, NULL);
+ if (!obj) {
+ error(1, errno, "Object was not created");
+ }
+
+ str = forb_object_to_string(obj);
+ if (str) {
+ printf("Object reference1: %s\n", str);
+ } else {
+ return 1;
+ }
+
+ obj2 = forb_string_to_object(orb, str);
+
+ str2 = forb_object_to_string(obj2);
+ if (str) {
+ printf("Object reference2: %s\n", str2);
+ } else {
+ return 1;
+ }
+
+ if (strcmp(str, str2) != 0)
+ error(1, 0, "Object references should be the same");
+
+ forb_free(str);
+ forb_free(str2);
+
+ return 0;
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+test_PROGRAMS = objref
+
+lib_LOADLIBES = forb ulut fosa rt
+
+objref_SOURCES = objref.c
+objref_CLIENT_IDL = objref.idl
+objref_SERVER_IDL = objref.idl
+
+INCLUDES += -I$(USER_OBJS_DIR)
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file objref.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Thu Oct 2 15:32:17 2008
+ *
+ * @brief Test for passing object references as method parameters
+ *
+ * In this test a client calls server's method call_me_back(), which
+ * takes a client object reference as parameter. The server then
+ * invokes the callback() method on the received object reference.
+ *
+ */
+
+#include <forb.h>
+#include <error.h>
+#include <fosa.h>
+#include <forb/executor.h>
+#include "objref.h"
+#include <stdio.h>
+#include <stdbool.h>
+
+int argc_g;
+char **argv_g;
+
+static void call_me_back(server _obj, const client obj, CORBA_Environment *ev)
+{
+ CORBA_Environment env;
+ printf("Server called\n");
+ client_callback(obj, &env);
+}
+
+static const struct forb_server_impl server_impl = {
+ .call_me_back = call_me_back
+};
+
+
+void *server_thread(void *arg)
+{
+ server s = arg;
+ forb_execute_object(s);
+ return NULL;
+}
+
+char *start_server()
+{
+ forb_orb orb;
+ server s;
+ fosa_thread_id_t tid;
+ struct forb_init_attr attr = {
+ .orb_id = "objref_server"
+ };
+
+ orb = forb_init(&argc_g, &argv_g, &attr);
+ s = forb_server_new(orb, &server_impl, NULL);
+ fosa_thread_create(&tid, NULL, server_thread, s);
+
+ return forb_object_to_string(s);
+}
+
+unsigned callback_called = 0;
+
+static void callback(client _obj, CORBA_Environment *ev)
+{
+ callback_called++;
+ printf("Client callback called %d times\n", callback_called);
+}
+
+static const struct forb_client_impl client_impl = {
+ .callback = callback
+};
+
+void *client_thread(void *arg)
+{
+ client c = arg;
+ forb_execute_object(c);
+ return NULL;
+}
+
+
+void start_client(void *arg)
+{
+ char *objref = arg;
+ forb_orb orb;
+ server serv;
+ client me;
+ struct forb_env env;
+ fosa_thread_id_t tid;
+ struct forb_init_attr attr = {
+ .orb_id = "objref_client"
+ };
+
+ orb = forb_init(&argc_g, &argv_g, &attr);
+
+ me = forb_client_new(orb, &client_impl, NULL);
+ fosa_thread_create(&tid, NULL, client_thread, me);
+
+ serv = forb_string_to_object(orb, objref);
+ if (!serv) {
+ error(1, 0, "Cannot create object reference from the string (%s)\n", objref);
+ }
+
+ server_call_me_back(serv, me, &env);
+ if (forb_exception_occurred(&env)) {
+ error(1, 0, "FORB exception %d", env.major);
+ }
+
+ forb_object_release(me);
+}
+
+int main(int argc, char *argv[])
+{
+
+ char *objref_str;
+
+ argc_g = argc;
+ argv_g = argv;
+
+ objref_str = start_server();
+
+ start_client(objref_str);
+
+ if (callback_called == 0) {
+ error(1, 0, "Callback was not called");
+ }
+ return 0;
+}
--- /dev/null
+interface client {
+ void callback();
+};
+
+interface server {
+ void call_me_back(in client obj);
+};
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file regobjref.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sat Oct 11 21:12:09 2008
+ *
+ * @brief Test for forb_register_reference() and forb_resolve_reference()
+ *
+ * This test is the same as hello_remote.c. The only difference is
+ * that in hello_remote.c, the object reference of the server is
+ * passed as a string to the client, whereas here we use
+ * forb_register_reference()/forb_resolve_reference() for this.
+ */
+
+
+#include <hello.h>
+#include "hello_impl.h"
+#include <forb.h>
+#include <error.h>
+#include <fosa.h>
+#include <forb/executor.h>
+
+int argc_g;
+char **argv_g;
+
+void *server_thread(void *arg)
+{
+ hello hobj = arg;
+
+ forb_execute_object(hobj);
+ return NULL;
+}
+
+void start_server()
+{
+ forb_orb orb;
+ hello hobj;
+ int ret;
+
+ fosa_thread_id_t tid;
+ struct forb_init_attr attr = {
+ .orb_id = "hello_remote_server"
+ };
+
+ orb = forb_init(&argc_g, &argv_g, &attr);
+ hobj = hello_impl_initialize(orb);
+ fosa_thread_create(&tid, NULL, server_thread, hobj);
+
+ ret = forb_register_reference(hobj, "hello");
+ if (ret != 0) {
+ error(1, errno, "Cannot register reference to hello");
+ }
+}
+
+
+
+void client(void)
+{
+ forb_orb orb;
+ hello hobj;
+ struct forb_env env;
+ struct forb_init_attr attr = {
+ .orb_id = "hello_remote_client"
+ };
+
+ orb = forb_init(&argc_g, &argv_g, &attr);
+
+ hobj = forb_resolve_reference(orb, "hello");
+ if (!hobj) {
+ error(1, errno, "Cannot resolve reference to hello server)");
+ }
+
+ hello_message(hobj, "Hello world!", &env);
+ if (forb_exception_occurred(&env)) {
+ error(1, 0, "FORB exception %d", env.major);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+
+ argc_g = argc;
+ argv_g = argv;
+
+ start_server();
+
+ client();
+
+ return 0;
+}
--- /dev/null
+#include <forb.h>
+#include <wvtest.h>
+#include "sequence.h"
+
+int destructor_called;
+int sum_of_destructed;
+
+void destructor(int *elem)
+{
+ destructor_called++;
+ sum_of_destructed += *elem;
+}
+
+WVTEST_MAIN("sequence manipulation")
+{
+ CORBA_sequence_long *s;
+ int i, *e, foreach_retuned_sum = 0;
+ forb_sequence_alloc(s, 10);
+ WVPASS(s);
+ WVPASS(forb_sequence_allocated(s) == 10);
+ bool initialized_to_zero = true;
+ for (i=0; i<10; i++)
+ initialized_to_zero &= forb_sequence_elem(s, i) == 0;
+ WVPASS(initialized_to_zero);
+ WVPASS(forb_sequence_elem(s, 9) = 1);
+ WVPASS(forb_sequence_ensure_allocated(s, 1000) != NULL);
+ WVPASS(forb_sequence_allocated(s) == 1000);
+ WVPASS(forb_sequence_elem(s, 9) == 1);
+ WVPASS(forb_sequence_elem(s, 999) = 1);
+ CORBA_sequence_set_release(s, 1);
+ WVPASS(forb_sequence_length(s) == 0);
+ forb_sequence_free(s, destructor);
+ WVPASS(destructor_called == 0);
+
+ forb_sequence_alloc(s, 10);
+ WVPASS(s);
+ for (i=0; i<10; i++)
+ forb_sequence_elem(s, i) = i;
+ forb_sequence_length(s) = 10;
+ WVPASS(forb_sequence_length(s) == 10);
+ forb_sequence_free(s, destructor);
+ WVPASS(destructor_called == 0);
+
+ forb_sequence_alloc(s, 10);
+ WVPASS(s);
+ CORBA_sequence_set_release(s, 1);
+ for (i=0; i<10; i++)
+ forb_sequence_elem(s, i) = i;
+ forb_sequence_length(s) = 10;
+ WVPASS(forb_sequence_length(s) == 10);
+
+ forb_sequence_foreach(s, e) {
+ foreach_retuned_sum += *e;
+ }
+ WVPASS(foreach_retuned_sum == 45);
+
+ forb_sequence_free(s, destructor);
+ WVPASS(destructor_called == 10);
+ WVPASS(sum_of_destructed == 45);
+}
--- /dev/null
+interface MyIface {
+ void MyOp();
+};
+
+struct SeqStruct {
+ sequence<long,10> MyLongs;
+ sequence<octet> MyOctets;
+// sequence<MyIface> Interfaces; FIXME: This is bugy: sequence-common.c:124: undefined reference to `CORBA_sequence_Object_deserialize
+ sequence<sequence<short> > SeqSeq;
+};
+
+typedef sequence<string> MyStrings;
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file test_proto_inet.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Thu Aug 28 15:20:37 2008
+ *
+ * @brief Unit test for INET socket based FORB transport protocol
+ */
+
+#include <error.h>
+#include "../proto_inet.c"
+
+const char *msg = "Hello world!";
+const char *msg2 = "Blablabla!";
+#define NUM_PORTS 10
+
+char *timeout_msg = "timeout\n";
+
+void timeout(int signal)
+{
+ error(1, 0, timeout_msg);
+}
+
+int main()
+{
+ int len;
+ struct inet_addr addr[NUM_PORTS];
+ forb_port_t port[NUM_PORTS];
+ int i, ret;
+
+ signal(SIGALRM, timeout);
+
+ memset(port, 0, sizeof(port));
+
+ for (i=0; i<NUM_PORTS; i++) {
+ addr[i].addr.s_addr = htonl(0x7f000001+i);
+ if (forb_inet_port_init(&port[i].desc, addr[i].addr, 0) != 0)
+ error(1, errno, "forb_inet_port_init(%d)", i);
+ }
+
+
+ /* Send from zeroth node to all others (starting from 1) */
+ for (i=1; i<NUM_PORTS; i++) {
+ forb_peer_t *peer;
+ char buf[100];
+ char tmsg[100];
+
+ peer = forb_peer_new();
+ peer->addr = port[i].desc.addr;
+ peer->port = &port[0];
+
+ len = strlen(msg)+1;
+ ret = inet_send(peer, msg, len);
+
+ peer->addr = NULL;
+ forb_peer_put(peer);
+ if (ret != len)
+ error(1, errno, "send(to %d) = %d", i, ret);
+
+ sprintf(tmsg, "Timeout when sending from 0 to %d\n", i);
+ timeout_msg = tmsg;
+ alarm(1); /* timeout 1s */
+ ret = inet_recv(&port[i], buf, sizeof(buf));
+ alarm(0);
+ if (ret != len)
+ error(1, errno, "recv(port[%d]) = %d", i, ret);
+
+ if (strcmp(msg, buf) != 0)
+ error(1, errno, "port %d: received wrong data", i);
+
+ }
+
+ len = strlen(msg2)+1;
+ ret = inet_broadcast(&port[0], msg2, len);
+ if (ret != len)
+ error(1, errno, "broadcast(port[0]) = %d should be %d", ret, len);
+
+ for (i=0; i<NUM_PORTS; i++) {
+ char buf[100];
+ char tmsg[100];
+
+ sprintf(tmsg, "Timeout when receiving broadcast for port %d\n", i);
+ timeout_msg = tmsg;
+ alarm(1);
+ ret = inet_recv(&port[i], buf, sizeof(buf));
+ alarm(0);
+ if (ret != len)
+ error(1, errno, "broadcast recv(port[%d]) = %d should be %d (errno=%d)", i, ret, len, errno);
+ //printf("broadcast received: %s\n", buf);
+
+ if (strcmp(msg2, buf) != 0)
+ error(1, errno, "port %d: broadcast received wrong data", i);
+
+ }
+
+ for (i=0; i<NUM_PORTS; i++) {
+ inet_port_destroy(&port[i]);
+ }
+
+ printf("OK\n");
+ return 0;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file test_proto_unix.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Thu Aug 28 15:20:37 2008
+ *
+ * @brief Unit test for UNIX socket based FORB transport protocol
+ */
+
+#include <error.h>
+#include "../proto_unix.c"
+
+const char *msg = "Hello world!";
+const char *msg2 = "Blablabla!";
+#define NUM_PORTS 10
+
+char *timeout_msg = "timeout\n";
+
+void timeout(int signal)
+{
+ error(1, 0, timeout_msg);
+}
+
+int main()
+{
+ int len;
+ forb_server_id server[NUM_PORTS];
+ forb_port_t port[NUM_PORTS];
+ int i, ret;
+
+ signal(SIGALRM, timeout);
+
+ for (i=0; i<NUM_PORTS; i++) {
+ forb_server_id_init(&server[i]);
+ if (forb_unix_port_init(&port[i].desc, &server[i]) != 0)
+ error(1, errno, "forb_unix_port_init(%d)", i);
+ }
+
+
+ /* Send from zeroth node to all others (starting from 1) */
+ for (i=1; i<NUM_PORTS; i++) {
+ forb_peer_t peer;
+ char buf[100];
+ char tmsg[100];
+
+ peer.server_id = server[i];
+ peer.port = &port[0];
+
+ len = strlen(msg)+1;
+ ret = unix_send(&peer, msg, len);
+ if (ret != len)
+ error(1, errno, "send(to %d) = %d", i, ret);
+
+ sprintf(tmsg, "Timeout when sending from 0 to %d\n", i);
+ timeout_msg = tmsg;
+ alarm(1); /* timeout 1s */
+ ret = unix_recv(&port[i], buf, sizeof(buf));
+ alarm(0);
+ if (ret != len)
+ error(1, errno, "recv(port[%d]) = %d", i, ret);
+
+ if (strcmp(msg, buf) != 0)
+ error(1, errno, "port %d: received wrong data", i);
+
+ }
+
+
+ len = strlen(msg2)+1;
+ ret = unix_broadcast(&port[0], msg2, len);
+ if (ret != len)
+ error(1, errno, "broadcast(port[0]) = %d should be %d", ret, len);
+
+ for (i=0; i<NUM_PORTS; i++) {
+ char buf[100];
+ char tmsg[100];
+
+ sprintf(tmsg, "Timeout when receiving broadcast for port %d\n", i);
+ timeout_msg = tmsg;
+ alarm(1);
+ ret = unix_recv(&port[i], buf, sizeof(buf));
+ alarm(0);
+ if (ret != len)
+ error(1, errno, "broadcast recv(port[%d]) = %d should be %d", i, ret, len);
+ //printf("broadcast received: %s\n", buf);
+
+ if (strcmp(msg2, buf) != 0)
+ error(1, errno, "port %d: broadcast received wrong data", i);
+
+ }
+
+ for (i=0; i<NUM_PORTS; i++) {
+ unix_port_destroy(&port[i]);
+ }
+
+ return 0;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file test_syncobj.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 19:09:45 2008
+ *
+ * @brief Test of synchronization obects
+ *
+ *
+ */
+
+#include <stdio.h>
+#include <forb/syncobj.h>
+#include <fosa.h>
+#include <error.h>
+
+forb_syncobj_t syncobj;
+
+void *thread(void *arg)
+{
+ fosa_abs_time_t now, hello_time;
+ fosa_rel_time_t hello_interval = fosa_msec_to_rel_time(2000);
+ int ret;
+
+ fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &hello_time);
+ hello_time = fosa_abs_time_incr(hello_time, hello_interval);
+ ret = forb_syncobj_timedwait(&syncobj, &hello_time);
+ if (ret != 0) {
+ error(1, errno, "forb_syncobj_timedwait() error %d\n", ret);
+ }
+
+ fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &now);
+ if (fosa_abs_time_smaller_or_equal(hello_time, now)) {
+ error(1, 0, "Should not wait longet than timeout\n");
+ }
+ return NULL;
+}
+
+int main()
+{
+ fosa_abs_time_t now, hello_time;
+ fosa_rel_time_t hello_interval = fosa_msec_to_rel_time(1000);
+ int ret;
+ fosa_thread_id_t tid;
+
+ forb_syncobj_init(&syncobj, 0);
+
+ fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &hello_time);
+ hello_time = fosa_abs_time_incr(hello_time, hello_interval);
+
+ ret = forb_syncobj_timedwait(&syncobj, &hello_time);
+ if (ret != 0 && ret != FOSA_ETIMEDOUT) {
+ error(1, errno, "forb_syncobj_timedwait() error %d\n", ret);
+ }
+ fosa_clock_get_time(FOSA_CLOCK_ABSOLUTE, &now);
+ if (fosa_abs_time_smaller_or_equal(now, hello_time)) {
+ error(1, 0, "Wait less then timeout\n");
+ }
+
+ fosa_thread_create(&tid, NULL, thread, NULL);
+ forb_syncobj_signal(&syncobj);
+ return 0;
+}
--- /dev/null
+/**
+ * @file types.idl
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Oct 12 17:12:30 2008
+ *
+ * @brief Types used internally by FORB.
+ *
+ *
+ */
+
+module forb {
+ /**
+ * Object key for distinguishing different objects in a FORB.
+ */
+ typedef long long object_key;
+
+ typedef char uuid[8];
+
+ /**
+ * Server ID for identifying different FORBs.
+ *
+ * The ID is based on universal unique identifiers (UUID).
+ */
+
+ struct server_id {
+ uuid uuid;
+ };
+};
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file uuid.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Tue Aug 26 09:17:31 2008
+ *
+ * @brief Unix version of UUID generator
+ *
+ */
+#include <forb/uuid.h>
+#include <sys/time.h>
+#include <time.h>
+#include "sha1.h"
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/**
+ * Generates universally unique ID.
+ *
+ * @param dest Where to store the newly generated UUID.
+ *
+ * @return Same as @a dest.
+ */
+forb_uuid_t *forb_uuid_generate(forb_uuid_t *dest)
+{
+ SHA1_CTX ctx;
+ struct timeval tv;
+ pid_t pid = getpid();
+ unsigned char digest[20];
+ int i, r;
+
+ gettimeofday(&tv, 0);
+
+ SHA1Init(&ctx);
+ SHA1Update(&ctx, (unsigned char*)&tv, sizeof(tv));
+ SHA1Update(&ctx, (unsigned char*)&pid, sizeof(pid));
+
+ /* Crank the random number generator a few times */
+ gettimeofday(&tv, 0);
+ for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--) {
+ r = rand();
+ SHA1Update(&ctx, (unsigned char*)&r, sizeof(r));
+ }
+
+ /* Also try to use /dev/urnadom to get some randomnes */
+
+ /* This should be enough for localhost process.
+ * TODO: Add network addresses for distributed operation! */
+ SHA1Final(digest, &ctx);
+ memcpy(dest, digest, sizeof(forb_uuid_t));
+ return dest;
+}
+
+/**
+ * Converts UUID to string.
+ *
+ * @param dest Where to store the result.
+ * @param uuid The UUID to convert.
+ * @param n Size of @a dest buffer.
+ *
+ * @return The same value as @a dest.
+ */
+char *forb_uuid_to_string(char *dest, const forb_uuid_t *uuid, size_t n)
+{
+ int i;
+ for (i = 0; i<sizeof(uuid->byte) && 2*(i+1) < n; i++)
+ sprintf(dest + 2*i, "%02hhx", uuid->byte[i]);
+ dest[2*i] = '\0';
+ return dest;
+}
+
+static inline int hexval(char c)
+{
+ if (c >= '0' && c <= '9')
+ return c-'0';
+ if (c >= 'a' && c <= 'f')
+ return 10+c-'a';
+ if (c >= 'A' && c <= 'F')
+ return 10+c-'A';
+ return -1;
+}
+
+/**
+ * Creates UUID from string form.
+ *
+ * @param dest Where to store the UUID.
+ * @param string UUID in the string form.
+ *
+ * @return @a dest in case of success, NULL in case of error.
+ */
+forb_uuid_t *forb_uuid_from_string(forb_uuid_t *dest, const char *string)
+{
+ int i;
+
+ for (i = 0; i<sizeof(dest->byte); i++) {
+ int a, b;
+ a = hexval(string[2*i]);
+ if (a < 0)
+ return NULL;
+ b = hexval(string[2*i+1]);
+ if (b < 0)
+ return NULL;
+
+ dest->byte[i] = (a << 4) + b;
+ }
+ return dest;
+}
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FORB (Frescor Object Request Broker) */
+/* */
+/* FORB is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FORB is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FORB; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FORB header files in a file, */
+/* instantiating FORB generics or templates, or linking other files */
+/* with FORB objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+#ifndef FORB_UUID_H
+#define FORB_UUID_H
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Universally unique ID type.
+ */
+typedef struct {
+ char byte[8];
+} forb_uuid_t;
+
+static inline int forb_uuid_cmp(forb_uuid_t u1, forb_uuid_t u2)
+{
+ return memcmp(&u1, &u2, sizeof(forb_uuid_t));
+}
+
+forb_uuid_t *forb_uuid_generate(forb_uuid_t *dest);
+char *forb_uuid_to_string(char *dest, const forb_uuid_t *uuid, size_t n);
+forb_uuid_t *forb_uuid_from_string(forb_uuid_t *dest, const char *string);
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+#SUBDIRS = $(ALL_OMK_SUBDIRS)
+
+USER_IDLS += $(notdir $(wildcard $(SOURCES_DIR)/*.idl))
+
+library-pass_HOOKS = $(foreach idl,$(USER_IDLS),$(idl:%.idl=%.h))
+
+lib_LIBRARIES = forb-idl-tests
+# Test whether are the generated files compilable
+forb-idl-tests_GEN_SOURCES = $(addsuffix -skels.c,$(basename $(USER_IDLS))) \
+ $(addsuffix -stubs.c,$(basename $(USER_IDLS))) \
+ $(addsuffix -common.c,$(basename $(USER_IDLS)))
+
+test_PROGRAMS += example_server
+INCLUDES += -I$(USER_OBJS_DIR)
+example_server_SOURCES = example_server.c
+example_server_LIBS = fosa pthread rt forb ulut
+example_server_SERVER_IDL = myinterface.idl
+
+test_PROGRAMS += example_client
+INCLUDES += -I$(USER_OBJS_DIR)
+example_client_SOURCES = example_client.c
+example_client_LIBS = fosa pthread rt forb ulut
+example_client_CLIENT_IDL = myinterface.idl
--- /dev/null
+enum MyEnum {
+ ONE_VALUE,
+ SECOND_VALUE
+};
+
+typedef MyEnum TypedeffedEnum;
--- /dev/null
+#include <stdio.h>
+#include <forb.h>
+#include "myinterface.h" /* IDL compiler generated prototypes etc. */
+
+int main(int argc, char *argv[])
+{
+ forb_orb orb;
+ myinterface example;
+ CORBA_Environment env;
+ CORBA_long sum, a, b;
+
+ orb = forb_init(&argc, &argv, NULL); /* FORB initialization */
+
+ /* Find our implementation */
+ example = forb_resolve_reference(orb, "example");
+
+ /* Call our implementation */
+ sum = myinterface_add(example, 2, 3, &env);
+ printf("2+3=%d\n", sum);
+
+ /* Call our implementation again */
+ myinterface_get_last(example, &a, &b, &env);
+ printf("last used values: %d and %d\n", a, b);
+
+ return 0;
+}
--- /dev/null
+#include <forb.h>
+#include "myinterface.h" /* IDL compiler generated prototypes etc. */
+
+/* Internal data of our object implementing myinterface */
+struct example_data {
+ int last_a, last_b;
+};
+
+/* Implementation of add method */
+CORBA_long example_add(myinterface obj, const CORBA_long a,
+ const CORBA_long b, CORBA_Environment *ev)
+{
+ struct example_data *ed = forb_instance_data(obj);
+ ed->last_a = a;
+ ed->last_b = b;
+ return a + b;
+}
+
+/* Implementation of get_last method */
+void example_get_last(myinterface obj, CORBA_long* a,
+ CORBA_long* b, CORBA_Environment *ev)
+{
+ struct example_data *ed = forb_instance_data(obj);
+ *a = ed->last_a;
+ *b = ed->last_b;
+}
+
+/* Table of implemented methods */
+struct forb_myinterface_impl example_implementation = {
+ .add = example_add,
+ .get_last = example_get_last,
+};
+
+int main(int argc, char *argv[])
+{
+ forb_orb orb;
+ myinterface example;
+ struct example_data example_data;
+
+ orb = forb_init(&argc, &argv, NULL); /* FORB initialization */
+ /* Cration of an object implementing myinterface */
+ example = forb_myinterface_new(orb, &example_implementation,
+ &example_data);
+ /* We can register our object under a name, so that other
+ * processes can use it. */
+ forb_register_reference(example, "example");
+
+ /* Process incomming requests to this object */
+ forb_execute_object(example);
+
+ return 0; /* Never returns */
+}
--- /dev/null
+struct struct_t {
+ long a, b;
+};
+
+typedef long mytype;
+
+interface myinterface {
+ long add(in long a, in long b);
+ void get_last(out long a, out long b);
+ void square(inout long r);
+ void message(in string msg);
+ void last_message(out string msg);
+ void struct_method(in struct_t s, out struct_t ss);
+ void obj_method(in myinterface mi, out myinterface mo);
+ void mytype_method(in mytype mt, out mytype mtt);
+};
--- /dev/null
+interface MyIface {
+ void MyOp();
+};
+
+struct SeqStruct {
+ sequence<long,10> MyLongs;
+ sequence<octet> MyOctets;
+ sequence<MyIface> Interfaces;
+ sequence<sequence<short> > SeqSeq;
+};
+
+typedef sequence<string> MyStrings;
--- /dev/null
+struct StringStruct {
+ string x;
+};
+
+interface StringIntf {
+ void method(in string s1, out string s2);
+};
--- /dev/null
+struct MyStruct {
+ short d1, d2;
+ long d3[3][6];
+ struct InnerStruct {
+ long data;
+ } d4;
+};
--- /dev/null
+#include "struct.idl"
+
+typedef MyStruct TypedefedStruct;
+typedef long MyLong, MyLongArray[20];
--- /dev/null
+NOTE: The text below develops the terms of the GNU General Public
+ License in detail which serves as the basis for distribution of
+ this software. Please check the source code files themselves
+ for the final exceptions on the GPL license.
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+# Doxyfile 1.4.6
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = FOSA
+PROJECT_NUMBER = D-EP3v2
+OUTPUT_DIRECTORY = doc
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = NO
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP = NO
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 5
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = YES
+OPTIMIZE_OUTPUT_JAVA = NO
+BUILTIN_STL_SUPPORT = NO
+DISTRIBUTE_GROUP_DOC = NO
+SUBGROUPING = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = NO
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = NO
+EXTRACT_LOCAL_CLASSES = NO
+EXTRACT_LOCAL_METHODS = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = YES
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = YES
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = NO
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_DIRECTORIES = NO
+FILE_VERSION_FILTER =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = ./include
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.d \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.idl \
+ *.odl \
+ *.cs \
+ *.php \
+ *.php3 \
+ *.inc \
+ *.m \
+ *.mm \
+ *.dox \
+ *.py \
+ *.C \
+ *.CC \
+ *.C++ \
+ *.II \
+ *.I++ \
+ *.H \
+ *.HH \
+ *.H++ \
+ *.CS \
+ *.PHP \
+ *.PHP3 \
+ *.M \
+ *.MM \
+ *.PY
+RECURSIVE = YES
+EXCLUDE = tests
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS = *
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = YES
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION = NO
+USE_HTAGS = NO
+VERBATIM_HEADERS = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = api_html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT = api_latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = YES
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = YES
+USE_PDFLATEX = YES
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED = RT_LINUX=YES
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 1024
+MAX_DOT_GRAPH_HEIGHT = 1024
+MAX_DOT_GRAPH_DEPTH = 1000
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
--- /dev/null
+# Doxyfile 1.4.6
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = FOSA
+PROJECT_NUMBER = D-EP3v2
+OUTPUT_DIRECTORY = doc
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = NO
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP = NO
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 5
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = YES
+OPTIMIZE_OUTPUT_JAVA = NO
+BUILTIN_STL_SUPPORT = NO
+DISTRIBUTE_GROUP_DOC = NO
+SUBGROUPING = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = NO
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = NO
+EXTRACT_LOCAL_CLASSES = NO
+EXTRACT_LOCAL_METHODS = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = YES
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = YES
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = NO
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_DIRECTORIES = NO
+FILE_VERSION_FILTER =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = ./include
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.d \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.idl \
+ *.odl \
+ *.cs \
+ *.php \
+ *.php3 \
+ *.inc \
+ *.m \
+ *.mm \
+ *.dox \
+ *.py \
+ *.C \
+ *.CC \
+ *.C++ \
+ *.II \
+ *.I++ \
+ *.H \
+ *.HH \
+ *.H++ \
+ *.CS \
+ *.PHP \
+ *.PHP3 \
+ *.M \
+ *.MM \
+ *.PY
+RECURSIVE = YES
+EXCLUDE = tests
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS = *
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION = NO
+USE_HTAGS = NO
+VERBATIM_HEADERS = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = NO
+HTML_OUTPUT = api_html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = YES
+LATEX_OUTPUT = api_latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = YES
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = YES
+USE_PDFLATEX = YES
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED = RT_LINUIX=YES
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 1024
+MAX_DOT_GRAPH_HEIGHT = 1024
+MAX_DOT_GRAPH_DEPTH = 1000
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
--- /dev/null
+all: libfosa
+include config.mk
+include rules.mk
+
+
--- /dev/null
+SUBDIRS=include
+
+ifeq ($(PLATFORM),MARTE_OS)
+ SUBDIRS+=src_marte_os
+endif
+
+ifeq ($(PLATFORM),AQuoSA)
+ SUBDIRS+=src_aquosa
+endif
--- /dev/null
+Introduction
+============
+
+This is the development trunk of FOSA Fresh OS Adaption), a library to
+port FRSH to POSIX and non-POSIX platforms.
+
+
+This directory holds the C API and test examples. Specific
+achievements or milestones will be reflected with static tags at:
+
+ http://www.frescor.org/private/svn/frescor/fosa/snapshots
+
+Extensive documentation about FOSA can be found in the D-EP3
+deliverable series.
+
+
+Directory Overview
+==================
+
+- README: This file.
+
+- COPYING: GNU GENERAL PUBLIC LICENSE
+
+- include/: FOSA API C header files.
+
+- src_marte/ : source code of FOSA for MaRTE-OS
+- src_ose: source code of FOSA for OSE
+- src_partikle/: source code of FOSA for ParTiKle
+- src_aquosa/: source code of FOSA for AQuoSA
+- src_rtlinux/: source code of FOSA for RT-Linux
+
+- marte_non_local_jump: temporary place holder for MaRTE-OS longjump
+ implementation
+- lib/: libraries.
+
+- doc/: Extra Documentation (TODO, INSTALL, changelog and API_reference.pdf)
+
+
+
--- /dev/null
+# Platform: MARTE_OS, DUMMY_OS, RT_LINUX, OSE
+PLATFORM = MARTE_OS
+
+FRESCOR_ROOT = $(HOME)/frescor_dev
+
+# the path to the FOSA directory.
+FOSA_PATH = $(FRESCOR_ROOT)/fosa
+
+
+# the compilation flags
+CFLAGS = -Wall -g
+CFLAGS += -O1 -Wuninitialized
--- /dev/null
+api_html
+api_latex
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FOSA (Frsh Operating System Abstraction)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
--- /dev/null
+include_HEADERS = $(notdir $(wildcard $(SOURCES_DIR)/*.h))
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+
+#ifndef _FOSA_H_
+#define _FOSA_H_
+
+#include "fosa_cpp_macros.h"
+#include "fosa_configuration_parameters.h"
+#include "fosa_types.h"
+
+#include "fosa_threads_and_signals.h"
+#include "fosa_clocks_and_timers.h"
+#include "fosa_mutexes_and_condvars.h"
+#include "fosa_app_def_sched.h"
+#include "fosa_long_jump.h"
+#include "fosa_time.h"
+#include "fosa_platform_values.h"
+#include "fosa_group_clocks.h"
+
+/**
+ * @defgroup fosa FOSA Private Interfaces
+ *
+ * FOSA is an OS adaption layer that encapsulates all POSIX types and
+ * functions into neutral names so that FRSH can compile and be used in
+ * non-POSIX operating systems such as OSE.
+ *
+ * It is divided in two parts:
+ * - FRSH_FOSA: Types visible to the application via FRSH_API and
+ * the functions to manage them (thread, signals).
+ * - FOSA: Types and functions only used within FRSH.
+ *
+ * The former reside in the FRSH subversion directory and the latter
+ * have their own. They need to be separated because the application
+ * must not see FOSA itself.
+ *
+ * For simplicity, we have chosen to hide the operation function on
+ * signals and mutexes with the assumption that a direct mapping
+ * exists for frsh_signal_t, frsh_signal_info_t and frsh_mutext_t in
+ * the native OS.
+ *
+ * Since there are some parts which are platform dependent a define
+ * has been introduced for each platform. Currently the supported
+ * defines are:
+ *
+ * -DRT_LINUX
+ * -DPARTIKLE
+ * -DOSE
+ * -DMARTE_OS
+ * -DAQuoSA
+ *
+ * This module contains all other modules that are internal to the
+ * FRSH implementation.
+ *
+ * Note that to compile FOSA objects an include path towards FRSH is
+ * needed: -I<frsh_include_directory>.
+ **/
+
+
+#endif // _FOSA_H_
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_app_def_sched.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+
+#ifndef FOSA_APP_DEF_SCHED_H_
+#define FOSA_APP_DEF_SCHED_H_
+
+#include "fosa_types.h"
+
+FOSA_CPP_BEGIN_DECLS
+
+/**
+ * @defgroup appdefsched Application Defined Scheduling
+ * @ingroup fosa
+ *
+ * This module defines the function and types for an abstraction of
+ * the Application Defined Scheduling.
+ *
+ * @{
+ **/
+
+
+
+/********************************
+ * Application-defined scheduling
+ ********************************/
+
+/**
+ * We make the following ASSUMPTIONS:
+ *
+ * - The ADS always executes in the user memory space, so we don't
+ * need to manage the memory space translation.
+ *
+ * - Only one application scheduler exists, so we don't need an
+ * scheduler_id.
+ **/
+
+/**
+ * fosa_ads_scheduler_create()
+ *
+ * Create the application defined scheduler
+ *
+ * The application defined scheduler is created with the primitive
+ * operations specified in the object pointed to by scheduler_ops.
+ *
+ * The clock used to read the time immediately before the invocation
+ * of each primitive operation, to be reported to the scheduler via
+ * the current_time parameter of each primitive operation is the
+ * FOSA_CLOCK_REALTIME clock.
+ *
+ * The scheduler_data_size parameter is used to request that a memory
+ * area of this size must be created and reserved for the scheduler to
+ * store its state. A pointer to this area is passed to the scheduler
+ * operations in the sched_data parameter.
+ *
+ * Parameter init_arg points to an area that contains configuration
+ * information for the scheduler. The function creates a memory area
+ * of init_arg_size bytes and copies into it the area pointed by
+ * arg. A pointer to this new created area will be passed to the
+ * primitive operation init() in its arg parameter.
+ *
+ * This function must be called before any other function in this
+ * header file.
+ *
+ * In addition it must be called at a priority level no greater than
+ * the priority at which the scheduler operations execute. This
+ * priority is defined as the maximum SCHED_FIFO priority in the
+ * system minus the configuration parameter FOSA_ADS_SCHEDULER_PRIO_DIFF.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_EINVAL: The value of scheduler_ops was invalid \n
+ * FOSA_EAGAIN: The system lacks enough resources to create the
+ * scheduler \n
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_scheduler_create
+ (const fosa_ads_scheduler_ops_t * scheduler_ops,
+ size_t scheduler_data_size,
+ void * init_args,
+ size_t init_args_size);
+
+/**
+ * fosa_thread_attr_set_appscheduled()
+ *
+ * Set the appscheduled attribute of a thread attributes object
+ *
+ * This function is used to set the appscheduled attribute in the
+ * object pointed to by attr. This attribute controls the kind of
+ * scheduling used for threads created with it. If true, the thread is
+ * scheduled by the application scheduler. If not, it is scheduled by
+ * the system under a fixed priority scheduler
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_EINVAL: The value of attr is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_set_appscheduled
+ (fosa_thread_attr_t *attr,
+ bool appscheduled);
+
+/**
+ * fosa_thread_attr_get_appscheduled()
+ *
+ * Get the appscheduled attribute of a thread attributes object
+ *
+ * This function is used to get the appscheduled attribute in the
+ * object pointed to by attr. This attribute controls the kind of
+ * scheduling used for threads created with it. If true, the thread is
+ * scheduled by the application scheduler. If not, it is scheduled by
+ * the system under a fixed priority scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_EINVAL: The value of attr is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_get_appscheduled
+ (const fosa_thread_attr_t *attr,
+ bool *appscheduled);
+
+/**
+ * fosa_thread_attr_set_appsched_params()
+ *
+ * Set the appsched_param attribute of a thread attributes object
+ *
+ * This function is used to set the appsched_param attribute in the
+ * object pointed to by attr. For those threads with appscheduled set
+ * to true, this attribute represents the application-specific
+ * scheduling parameters. If successful, the function shall set the
+ * size of the appsched_param attribute to the value specified by
+ * paramsize, and shall copy the scheduling parameters occupying
+ * paramsize bytes and pointed to by param into that attribute
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_EINVAL: The value of attr is invalid, or paramsize is less than
+ * zero or larger than FOSA_ADS_SCHEDPARAM_MAX
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_set_appsched_params
+ (fosa_thread_attr_t *attr,
+ const void *param,
+ size_t paramsize);
+
+/**
+ * fosa_thread_attr_get_appsched_params()
+ *
+ * Get the appsched_param attribute of a thread attributes object
+ *
+ * This function is used to get the appsched_param attribute from the
+ * object pointed to by attr. For those threads with appscheduled set
+ * to true, this attribute represents the application-specific
+ * scheduling parameters. If successful, the function shall set the
+ * value pointed to by paramsize to the size of the appsched_param
+ * attribute, and shall copy the scheduling parameters occupying
+ * paramsize bytes into the variable pointed to by param. This
+ * variable should be capable of storing a number of bytes equal to
+ * paramsize.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_EINVAL: The value of attr is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_get_appsched_params
+ (const fosa_thread_attr_t *attr,
+ void *param,
+ size_t *paramsize);
+
+/**
+ * fosa_ads_set_appscheduled()
+ *
+ * Dynamically set the appscheduled attribute of a thread
+ *
+ * This function is used to dynamically set the appscheduled attribute
+ * of the thread identified by thread. This attribute controls the
+ * kind of scheduling used for threads created with it. If true, the
+ * thread is scheduled by the application scheduler. If not, it is
+ * scheduled by the system under a fixed priority scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_EINVAL: The value of thread is invalid
+ *
+ * FOSA_EREJECT: the attachment of the thread to the frsh schehduler
+ * was rejected by the frsh scheduler possibly because of
+ * incorrect attributes, or because the requested minimum
+ * capacity cannot be guaranteed
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_set_appscheduled
+ (fosa_thread_id_t thread,
+ bool appscheduled);
+
+/**
+ * fosa_ads_getappscheduled()
+ *
+ * Dynamically get the appscheduled attribute of a thread
+ *
+ * This function is used to dynamically get the appscheduled attribute
+ * of the thread identified by thread. This attribute controls the
+ * kind of scheduling used for threads created with it. If true, the
+ * thread is scheduled by the application scheduler. If not, it is
+ * scheduled by the system under a fixed priority scheduler
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_EINVAL: The value of thread is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_get_appscheduled
+ (fosa_thread_id_t thread,
+ bool *appscheduled);
+
+
+/**
+ * fosa_ads_setappschedparam()
+ *
+ * Dynamically set the appsched_param attribute of a thread
+ *
+ * This function is used to dynamically set the appsched_param
+ * attribute of the thread identified by thread. For those threads
+ * with appscheduled set to true, this attribute represents the
+ * application-specific scheduling parameters. If successful, the
+ * function shall set the size of the appsched_param attribute to the
+ * value specified by paramsize, and shall copy the scheduling
+ * parameters occupying paramsize bytes and pointed to by param into
+ * that attribute
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_EINVAL: The value of thread is invalid, or paramsize is less than
+ * zero or larger than FOSA_ADS_SCHEDPARAM_MAX
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_set_appsched_params
+ (fosa_thread_id_t thread,
+ const void *param,
+ size_t paramsize);
+
+/**
+ * fosa_ads_get_appsched_params()
+ *
+ * Dynamically get the appsched_param attribute of a thread
+ *
+ * This function is used to dynamically get the appsched_param
+ * attribute of the thread identified by thread. For those threads
+ * with appscheduled set to true, this attribute represents the
+ * application-specific scheduling parameters. If successful, the
+ * function shall set the variable pointed to by paramsize to the size
+ * of the appsched_param attribute, and shall copy the scheduling
+ * parameters occupying paramsize bytes into the variable pointed to
+ * by param. This variable should be capable of storing a number of
+ * bytes equal to paramsize.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_EINVAL: The value of thread is invalid, or paramsize is less than
+ * zero or larger than FOSA_ADS_SCHEDPARAM_MAX
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications.
+ **/
+int fosa_ads_get_appsched_params
+ (fosa_thread_id_t thread,
+ void *param,
+ size_t *paramsize);
+
+
+/*********************************
+ * ADS actions
+ *
+ * A scheduling actions object is used to specify a series of actions
+ * to be performed by the system at the end of a scheduler primitive
+ * operation. The order of the actions added to the object shall be
+ * preserved.
+ *
+ *********************************/
+
+/**
+ * fosa_adsactions_add_reject()
+ *
+ * Add a reject-thread action
+ *
+ * This function adds a thread-reject action to the object referenced
+ * by sched_actions, that will serve to notify that the thread
+ * identified by thread has not been accepted by the scheduler to be
+ * scheduled by it, possibly because the thread contained invalid
+ * application scheduling attributes, or because there are not enough
+ * resources for the new thread. At the end of the new_thread()
+ * scheduler primitive operation, the parent of the rejected thread
+ * waiting on a fosa_thread_create() or the rejected thread itself
+ * waiting on a fosa_ads_set_appscheduled() function shall complete the
+ * function with an error code of FOSA_EREJECT. If no reject-thread action
+ * is added during the new_thread() scheduler primitive operation, the
+ * thread is accepted to be scheduled by the scheduler and the
+ * associated fosa_thread_create() or the fosa_ads_set_appscheduled()
+ * function shall be completed without error. For the function to
+ * succeed, it has to be called from the new_thread() primitive
+ * operation and for the thread that is requesting attachment to the
+ * scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_ENOMEM: There is insufficient memory to add this action \n
+ * FOSA_EPOLICY: The thread specified by thread is not the one requesting
+ * attachment to the scheduler, or the function is not being
+ * called from the new_thread primitive operation \n
+ * FOSA_EINVAL: The value specified by sched_actions is invalid \n
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_reject(
+ fosa_ads_actions_t *sched_actions,
+ fosa_thread_id_t thread);
+
+/**
+ * fosa_adsactions_add_activate()
+ *
+ * Add a thread-activate action
+ *
+ * This function adds a thread-activate action to the object
+ * referenced by sched_actions. In case the thread had been previously
+ * suspended via posix_appsched_actions_addsuspend(), it will be
+ * activated at the end of the primitive operation.
+ *
+ * In those implementations that do not support urgency scheduling,
+ * the urgencu value is ignored. These implementations cannot support
+ * the frsh hierarchical scheduling module.
+ *
+ * In those implementations supporting urgency-scheduling, the action
+ * will cause the change of the urgency of the thread to the value
+ * specified in the urgency argument. Besides, if the thread was
+ * already active at the time the thread-activate action is executed,
+ * the change or urgency will imply a reordering of the thread in its
+ * priority queue, so that for threads of the same priority, those
+ * with more urgency will be scheduled before those of less urgency.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_ENOMEM: There is insufficient memory to add this action \n
+ * FOSA_EPOLICY: The thread specified by thread has its appscheduled
+ * attribute set to false \n
+ * FOSA_EINVAL: The value specified by sched_actions is invalid \n
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_activate(
+ fosa_ads_actions_t *sched_actions,
+ fosa_thread_id_t thread,
+ fosa_ads_urgency_t urgency);
+
+/**
+ * fosa_adsactions_add_suspend()
+ *
+ * Add a thread-suspend action
+ *
+ * This function adds a thread-suspend action to the object referenced
+ * by sched_actions, that will cause the thread identified by thread
+ * to be suspended waiting for a thread-activate action at the end of
+ * the scheduler operation. If the thread was already waiting for a
+ * thread-activate action the thread-suspend action has no effect. It
+ * is an error trying to suspend a thread that is blocked by the
+ * operating system.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_ENOMEM: There is insufficient memory to add this action \n
+ * FOSA_EPOLICY: The thread specified by thread has its appscheduled
+ * attribute set to false \n
+ * FOSA_EINVAL: The value specified by sched_actions is invalid \n
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_suspend(
+ fosa_ads_actions_t *sched_actions,
+ fosa_thread_id_t thread);
+
+/**
+ * fosa_adsactions_add_timeout()
+ *
+ * Add a timeout action
+ *
+ * This function adds a timeout action to the object referenced by
+ * sched_actions, that will cause the timeout() scheduler operation to
+ * be invoked if no other scheduler operation is invoked before
+ * timeout expires. The timeout shall expire when the clock specified by
+ * clock_id reaches the absolute time specified by the at_time
+ * argument.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_ENOMEM: There is insufficient memory to add this action \n
+ * FOSA_EINVAL: The value specified by sched_actions is invalid \n
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_timeout(
+ fosa_ads_actions_t *sched_actions,
+ fosa_clock_id_t clock_id,
+ const fosa_abs_time_t *at_time);
+
+/**
+ * fosa_adsactions_add_thread_notification()
+ *
+ * Add a timed-thread-notification action
+ *
+ * This function adds a thread-notification action associated with the
+ * thread specified in the thread argument that will cause the
+ * notification_for_thread() scheduler operation to be invoked at the
+ * time specified by at_time. This operation shall be invoked when the
+ * clock specified by clock_id reaches the absolute time specified by
+ * the at_time argument. In particular, a cpu-time clock may be used
+ * for parameter clock_id.Only one thread-notification can be active
+ * for each thread and clock. Calling the function shall remove the
+ * former thread-notification, if any, that had been programmed for
+ * the same thread and clock. A value of NULL for parameter at_time is
+ * used to cancel a previous thread-notification, if any, for the
+ * thread specified by thread and the clock specified by clock_id.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_ENOMEM: There is insufficient memory to add this action \n
+ * FOSA_EPOLICY: The thread specified by thread has its appscheduled
+ * attribute set to false \n
+ * FOSA_EINVAL: The value specified by sched_actions is invalid \n
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_thread_notification(
+ fosa_ads_actions_t *sched_actions,
+ fosa_thread_id_t thread,
+ fosa_clock_id_t clock_id,
+ const fosa_abs_time_t *at_time);
+
+
+/**
+ * fosa_ads_set_handled_signal_set()
+ *
+ * Specifiy the set of signals that will be handled by the application
+ * scheduler
+ *
+ * This function is used to dynamically set the set of signals that
+ * are handled by the application scheduler. When a signal included
+ * in this set is generated, the signal() primitive operation of the
+ * application scheduler shall be executed. When a signal in tis set
+ * is generated, it shall always imply the execution of the signal()
+ * primitive operation, regardless of whether that signal could be
+ * accepted by some other thread. Once the signal() primitive
+ * operation is executed the signal is consumed, so no signal handlers
+ * shall be executed and no threads using a sigwait operation shall
+ * return for that particular signal instance. For this function to
+ * succeed, it has to be called from a primitive operation of a
+ * scheduler.
+ *
+ * The size of the array is specified by argument size.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_EPOLICY: The function has not been called from a scheduler
+ * primitive operation \n
+ * FOSA_EINVAL: The value specified by set is invalid \n
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_set_handled_signal_set(fosa_signal_t set[], int size);
+
+
+/**
+ * fosa_signal_queue_scheduler()
+ *
+ * Queue a signal destinated to the scheduler
+ *
+ * This is a special case of fosa_signal_queue() in which the
+ * destinator is the scheduler itself. It is needed by the service
+ * thread to notify the results to the scheduler.
+ *
+ * The problem with this case is that, depending on the implementation,
+ * this call would be translated to a true signal or to a scheduler
+ * notification message.
+ *
+ * Besides for the scheduler we don't have always a destinator
+ * thread_id needed in fosa_signal_queue for OSE.
+ *
+ * So the fosa implementation will solve this issue internally.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the signal specified by signal is not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX
+ *
+ * FOSA_EAGAIN: no resources are available to queue the signal; the
+ * maximum number of queued signals has been reached, or a
+ * systemwide resource limit has been exceeded
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_signal_queue_scheduler(fosa_signal_t signal, fosa_signal_info_t info);
+
+
+/**
+ * fosa_ads_invoke_withdata()
+ *
+ * Explicitly invoke the scheduler, with data
+ *
+ * This function can be used by any thread in the process to invoke
+ * the ads scheduler or to share data with it.
+ *
+ * If successful, the function shall cause the execution of the
+ * primitive operation explicit_call_with_data() of the ads scheduler
+ * with its thread parameter equal to the thread ID of the calling
+ * thread, and its msg_size parameter equal to msg_size. In addition,
+ * if msg_size is larger than zero, the function shall make available
+ * to the scheduler a memory area whose contents are identical to the
+ * memory area pointed to by msg in the msg parameter of the
+ * explicit_call_with_data() primitive operation (note that copying
+ * the information is not needed).
+ *
+ * The function shall not return until the system has finished
+ * execution of the explicit_call_with_data() primitive operation. If
+ * the reply argument is non NULL, the memory area pointed to by the
+ * reply parameter of explicit_call_with_data() primitive operation is
+ * copied into the memory area pointed to by reply, and its size is
+ * copied into the variable pointed to by reply_size. The size of the
+ * reply information is limited to the value FOSA_ADS_SCHEDINFO_MAX.
+ *
+ * The function shall fail if the size specified by msg_size is larger
+ * than FOSA_ADS_SCHEDINFO_MAX. The function shall fail if primitive
+ * operation explicit_call_with_data() is set to NULL for the ads
+ * scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_EPOLICY: The function been called from inside a scheduler
+ * primitive operation \n
+ * FOSA_EINVAL: The value of msg_size is less than zero or larger than
+ * FOSA_ADS_SCHEDINFO_MAX \n
+ * FOSA_EMASKED: The operation cannot be executed because the primitive
+ * operation explicit_call_with_data() is set to NULL \n
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_invoke_withdata
+ (const void *msg, size_t msg_size, void *reply, size_t *reply_size);
+
+/*}*/
+
+FOSA_CPP_END_DECLS
+
+#endif /* !FOSA_APP_DEF_SCHED_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_clocks_and_timers.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+
+#ifndef FOSA_CLOCKS_AND_TIMERS_H_
+#define FOSA_CLOCKS_AND_TIMERS_H_
+
+#include "fosa_types.h"
+#include "fosa_configuration_parameters.h"
+
+FOSA_CPP_BEGIN_DECLS
+
+/**
+ * @defgroup clocksandtimers Clocks and Timers
+ * @ingroup fosa
+ *
+ * This module defines the types and functions to abstract clocks and
+ * timers for the FRSH implementation.
+ *
+ * @{
+ **/
+
+
+
+/*************************
+ * Timing: Clocks
+ *************************/
+
+/**
+ * fosa_get_time()
+ *
+ * Get the time from a clock
+ *
+ * This function sets the variable pointed to by current_time to the
+ * current value of the clock specified by clockid, which may be the
+ * FOSA_CLOCK_REALTIME constant or a value obtained with
+ * fosa_get_cputime_clock()
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of clockid is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_clock_get_time(fosa_clock_id_t clockid, fosa_abs_time_t *current_time);
+
+
+/**
+ * fosa_get_cputime_clock()
+ *
+ * Get the identifier of a cpu-time clock
+ *
+ * This function stores in the variable pointed to by clockid the
+ * identifier of a cpu-time clock for the thread specified by tid.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of tid is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_get_cputime_clock(fosa_thread_id_t tid, fosa_clock_id_t *clockid);
+
+
+/*************************
+ * Timing: Timers
+ *************************/
+
+/**
+ * fosa_timer_create()
+ *
+ * Create a one-shot timer
+ *
+ * This function creates a timer based on the clock specified by clock,
+ * and associates to this timer a notification mechanism consisting of
+ * a signal and associated information. Initially, the timer is in the
+ * disarmed state, i.e., not counting time. It can be armed to start
+ * counting time with fosa_timer_arm().
+ *
+ * The function stores the identifier of the newly created timer in the
+ * variable pointed to by timerid.
+ *
+ * When the timer expires, the signal number specified by signal will be
+ * sent together with the information specified by info, to the thread
+ * that armed the timer (@see fosa_timer_arm()).
+ *
+ * In those implementations that do not support queueing a
+ * signal with information to a thread (such as POSIX), the signal may
+ * be sent to any thread that is waiting for this signal via
+ * fosa_signal_wait(). Portability can be ensured by having the receiver
+ * thread be the one who is waiting for the signal.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of clockid or signal is invalid
+ *
+ * FOSA_EAGAIN: the system lacks enough resources to create the timer
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+ int fosa_timer_create
+ (fosa_clock_id_t clockid, fosa_signal_t signal, fosa_signal_info_t info,
+ fosa_timer_id_t *timerid);
+
+/**
+ * fosa_timer_create_with_receiver()
+ *
+ * Create a one-shot timer with a specific signal receiver thread
+ *
+ * This function creates a timer in the same way as fosa_timer_create,
+ * except that the signal generated when the timer expires is sent to
+ * the thread specified by receiver
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of clockid or signal is invalid
+ *
+ * FOSA_EAGAIN: the system lacks enough resources to create the timer
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+ int fosa_timer_create_with_receiver
+ (fosa_clock_id_t clockid, fosa_signal_t signal, fosa_signal_info_t info,
+ fosa_timer_id_t *timerid, fosa_thread_id_t receiver);
+
+/**
+ * fosa_timer_delete()
+ *
+ * Delete a timer
+ *
+ * The function deletes the timer specified by timerid, which becomes
+ * unusable. If the timer was armed, it is automatically disarmed before
+ * deletion.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of timerid is not valid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_timer_delete(fosa_timer_id_t timerid);
+
+/**
+ * fosa_rel_timer_arm()
+ *
+ * Arm a timer with a relative time interval
+ *
+ * The timer specified by timer is armed and starts counting time.
+ *
+ * The value pointed to by value is the relative interval that must
+ * elapse for the timer to expire. Negative values cause the timer to
+ * expire immediately.
+ *
+ * The time is measured with the clock associated with the timer when
+ * it was created.
+ *
+ * If the timer was already armed, the previous time or interval is discarded
+ * and the timer is rearmed with the new value.
+ *
+ * When the timer expires, it is disarmed.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of timerid or value is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_rel_timer_arm
+ (fosa_timer_id_t timerid, const fosa_rel_time_t *value);
+
+/**
+ * fosa_abs_timer_arm()
+ *
+ * Arm a timer that will expire in an absolute time instant.
+ *
+ * The timer specified by timer is armed and starts counting time.
+ *
+ * The value pointed to by value is the absolute time at which the
+ * timer will expire. If value specifies a time instant in the past,
+ * the timer expires immediately.
+ *
+ * The time is measured with the clock associated with the timer when
+ * it was created.
+ *
+ * If the timer was already armed, the previous time or interval is discarded
+ * and the timer is rearmed with the new value.
+ *
+ * When the timer expires, it is disarmed.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of timerid or value is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_abs_timer_arm
+ (fosa_timer_id_t timerid, const fosa_abs_time_t *value);
+
+
+
+
+/**
+ * fosa_timer_get_remaining_time()
+ *
+ * Get the remaining time for timer expiration
+ *
+ * Returns the relative remaining time for timer expiration. If the
+ * clock is a CPU clock it returns the time as if the thread was
+ * executing constantly.
+ *
+ * If the timer is disarmed it returns 0.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of timerid or value is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_timer_get_remaining_time
+ (fosa_timer_id_t timerid, fosa_rel_time_t *remaining_time);
+
+/**
+ * fosa_timer_disarm()
+ *
+ * Disarm a timer and optionally obtain remaining time before expiration
+ *
+ * The timer specified by timer is disarmed, and will not expire unless
+ * it is rearmed. If the timer was already disramed, the function has
+ * no effect.
+ *
+ * If the pointer remaining_time is != NULL, the remaining time before
+ * expiration will be returned in that pointer. If the timer was
+ * disarmed a 0 value will be set.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of timerid or value is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_timer_disarm(fosa_timer_id_t timerid,
+ fosa_rel_time_t *remaining_time);
+
+
+/*@}*/
+
+FOSA_CPP_END_DECLS
+
+#endif /* !FOSA_CLOCKS_AND_TIMERS_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_configuration_parameters.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+// 15-Nov-2007 sangorrin: add FOSA_CLOCK_ABSOLUTE for fosa_cond_timedwait
+
+#ifndef _FOSA_CONFIG_PARAM_H_
+#define _FOSA_CONFIG_PARAM_H_
+#include <fosa_cpp_macros.h>
+#include <time.h>
+
+FOSA_CPP_BEGIN_DECLS
+
+// the realtime clock used internally by the FRSH implementation
+// as the time basis for all timed services
+#define FOSA_CLOCK_REALTIME CLOCK_MONOTONIC
+#define FOSA_CLOCK_ABSOLUTE CLOCK_REALTIME
+
+// The maximum number of keys, or data items that may be associated
+// with each thread, in the thread-specific data
+#define FOSA_MAX_KEYS 4
+
+/**
+ * Real-time signal number reserved for the long jump handler
+ **/
+#define FOSA_LONG_JUMP_SIGNAL FOSA_SIGNAL_MIN+1
+
+
+
+/*********
+ * ADS
+ *********/
+
+// the maximum size in bytes of the ADS scheduling parameters
+#define FOSA_ADS_SCHEDPARAM_MAX 8000
+
+// the maximum size in bytes of the data exchanged between a thread
+// and an ADS scheduler
+#define FOSA_ADS_SCHEDINFO_MAX 8000
+
+
+// the difference between the maximum SCHED_FIFO priority
+// and the priority of the ADS scheduler thread
+// value= 2 priority levels below the maximum
+
+#define FOSA_ADS_SCHEDULER_PRIO_DIFF 2
+
+// The preemption level of the ADS scheduler thread
+#define FOSA_ADS_SCHEDULER_LEVEL 0xffff
+
+
+/******************
+ * THREAD GROUPS
+ ******************/
+#define FOSA_MAX_THREADS_PER_GROUP 5
+
+
+FOSA_CPP_END_DECLS
+
+#endif // _FOSA_CONFIG_PARAM_H_
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+
+#ifndef _FOSA_CPP_MACROS_H_
+#define _FOSA_CPP_MACROS_H_
+
+#if defined(__cplusplus)
+#define FOSA_CPP_BEGIN_DECLS extern "C" {
+#else
+#define FOSA_CPP_BEGIN_DECLS
+#endif
+
+#if defined(__cplusplus)
+#define FOSA_CPP_END_DECLS }
+#else
+#define FOSA_CPP_END_DECLS
+#endif
+
+#endif // _FOSA_CPP_MACROS_H_
+
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_group_clocks.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#ifndef _FOSA_GROUP_CLOCKS_H
+#define _FOSA_GROUP_CLOCKS_H
+
+#include "fosa_types.h"
+#include "fosa_configuration_parameters.h"
+
+FOSA_CPP_BEGIN_DECLS
+
+/**
+ * @defgroup groupclockss Group Clocks
+ * @ingroup fosa
+ *
+ * This module defines the types and functions to manage thread sets
+ * and execution clocks attached to them. These functions are used
+ * for the hierarchical scheduling module of FRSH
+ *
+ * @{
+ **/
+
+
+
+/**
+ * fosa_thread_set_create()
+ *
+ * Create an empty thread set and return an identifier
+ *
+ * This function stores in the variable pointed to by set the
+ * identifier of a thread set that is created by the function.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EAGAIN: no resources are currently available to create the
+ * thread set
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_set_create(fosa_thread_set_id_t *set);
+
+
+/**
+ * fosa_thread_set_destroy()
+ *
+ * Destroy a thread set
+ *
+ * This function destroys the thread set identified by set. The
+ * threads that were in the set are detached from the set. It is
+ * an error to use the identifier after this call. The effects of
+ * using a CPU-time clock associated with the destroyed thread are
+ * undefined.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: set is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_set_destroy(fosa_thread_set_id_t set);
+
+
+/**
+ * fosa_thread_set_add()
+ *
+ * Add a thread to a thread set
+ *
+ * This function adds the thread identified with thread_id to the
+ * thread set identified by set.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: set is invalid
+ * FOSA_ENOTSUP: thread already a member of some other set
+ * FOSA_EAGAIN: no resources available to add the new thread
+ * FOSA_ESRCH: thread_id doesn't identify a valid thread
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_set_add(fosa_thread_set_id_t set,
+ fosa_thread_id_t thread_id);
+
+
+/**
+ * fosa_thread_set_del()
+ *
+ * Delete a thread from a thread set
+ *
+ * This function deletes the thread identified with thread_id from
+ * the thread set identified by set.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: set is invalid
+ * FOSA_EINVAL: thread is not a member of the set
+ * FOSA_ESRCH: thread_id doesn't identify a valid thread
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_set_del(fosa_thread_set_id_t set,
+ fosa_thread_id_t thread_id);
+
+
+/**
+ * fosa_get_groupcpu_clock()
+ *
+ * Get the identifier of a cpu-time clock associated to a thread
+ * set
+ *
+ * This function stores in the variable pointed to by clockid the
+ * identifier of a cpu-time clock for the thread set specified
+ * by set.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the set is invalid
+ * FOSA_EINVAL: clock_id is a null pointer
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_get_groupcpu_clock(const fosa_thread_set_id_t set,
+ fosa_clock_id_t *clock_id);
+
+
+
+/*@}*/
+
+FOSA_CPP_END_DECLS
+
+
+
+#endif
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_long_jump.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+
+#ifndef FOSA_LONG_JUMP
+#define FOSA_LONG_JUMP
+
+#include "fosa_types.h"
+#include "fosa_opaque_types.h"
+
+FOSA_CPP_BEGIN_DECLS
+
+/**
+ * @defgroup longjumps Long Jumps
+ * @ingroup fosa
+ *
+ * This module defines the types and functions that allow te
+ * application to abort a piece of running code; it can be used to
+ * stop an action that is overrunning its budget and needs to be
+ * aborted, without aborting the whole thread on which it is based.
+ *
+ * The model is that the application installs a long-jump handler for
+ * each thread that potentially needs to be aborted through the long
+ * jump mechanism. As a result of installing the handler it gets back
+ * a signal identifier. This signal is later used to notify the
+ * handler that the thread needs to be aborted. Previous to sending
+ * the signal, the application must store the context of the thread so
+ * that when it is aborted the saved context can be recovered. The
+ * signal may be sent to the handler from any thread, but must contain
+ * as attached information a pointer to the variable where the context
+ * was saved.
+ *
+ * The implementation may internally choose to implement a single long
+ * jump handler for all threads (and use a single signal), or one for each
+ * thread (requiring the reservation of a pool of signals).
+ *
+ * @{
+ **/
+
+
+
+/*************************
+ * Functions
+ *************************/
+
+/**
+ * fosa_long_jump_save_context
+ *
+ * Save the context of the current thread for a future long jump
+ *
+ * This function stores in context the information required to modify
+ * the stack of the calling thread so that a later long jump may be
+ * executed in the future to restore this context
+ *
+ * This function stores in 'context' the thread id, the registers,
+ * and the stack frame of the calling thread. This information can be
+ * used by the long jump handler to change the stack of the task so
+ * that when it is scheduled again it returns to the end of this
+ * function
+ *
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of context is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ */
+int fosa_long_jump_save_context
+ (fosa_long_jump_context_t * context);
+
+
+/**
+ * fosa_long_jump_was_performed
+ *
+ * Check whether the current thread suffered a long jump or not
+ *
+ * This function should be invoked after fosa_long_jump_save_context
+ * to determine whether the current thread is executing normally, or
+ * has suffered a long jump to the point where the context was
+ * saved. If invoked after a direct invocation to
+ * fosa_long_jump_save_context, the function shall set the variable
+ * pointed to by jumped to zero. If invoked after returning from
+ * fosa_long_jump_save_context due to a long jump caused by the long
+ * jump handler, the function shall set this variable to 1.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of context is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ */
+int fosa_long_jump_was_performed
+ (const fosa_long_jump_context_t * context, int * jumped);
+
+
+/**
+ * fosa_long_jump_install_handler
+ *
+ * Install a long jump handler for the calling thread
+ *
+ * This function shall install a handler that is capable of causing a
+ * long jump operation that restores the context of a thread to a
+ * previously saved value. If the handler has already been installed
+ * for this thread the previously installed handler will be used and
+ * the call shall succeed.
+ *
+ * The long-jump handler is waiting for a signal to notify that a
+ * thread context should be restored. This signal must carry attached
+ * to it a pointer to the variable where the thread context was
+ * saved. The thread referenced in that context will have its
+ * internal context restored to the point where it was saved. For
+ * this restore operation to work properly, the program frame where
+ * the thread saved its context must still be valid.
+ *
+ * Depending on the implementation a given thread may also install a signal
+ * handler or a signal handler thread that is capable of executing
+ * the actions required to restore the context of a thread from the
+ * appropriate context. For instance, in POSIX it is necesaray that
+ * the context is restored from the same thread being restored,
+ * usually from a signal handler of that thread.
+ *
+ * The function shall store in the variable pointed to by signal the
+ * identifier of the signal that must be used to notify the request
+ * for a long jump to be executed. In the variable pointed to by
+ * handler, it shall store the thread id to which the signal must be
+ * sent. The signal must be sent with its attached information set to
+ * a pointer to the variable of type fosa_long_jump_context_t where
+ * the context of the thread to be restored was saved.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of context is invalid
+ * FOSA_ENOMEM: there are no resources to satisfy the call at this time
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ */
+int fosa_long_jump_install_handler
+(fosa_signal_t *signal, fosa_thread_id_t *handler);
+
+
+
+/*@}*/
+
+
+FOSA_CPP_END_DECLS
+
+#endif /* !FOSA_LONG_JUMP */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_mutexes_and_condvars.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#ifndef FOSA_MUTEX_AND_CONDVARS_H_
+#define FOSA_MUTEX_AND_CONDVARS_H_
+
+
+#include "fosa_types.h"
+
+FOSA_CPP_BEGIN_DECLS
+
+/**
+ * @defgroup mutexesandcondvars Mutexes and Condvars
+ * @ingroup fosa
+ *
+ * This module defines the types and functions to abstract mutexes and
+ * conditional variables for the FRSH implementation.
+ *
+ * @{
+ **/
+
+
+/*******************************************************
+ * Mutexes with priority ceiling
+ ******************************************************/
+
+/**
+ * fosa_mutex_init()
+ *
+ * Initialize a frsh mutex
+ *
+ * The mutex pointed to by mutex is initialized as a mutex using
+ * the priority ceiling protocol. A priority ceiling of prioceiling
+ * is assigned to this mutex.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_EINVAL: the value of prioceiling is invalid \n
+ * FOSA_EAGAIN: the system lacked the necessary resources to create
+ * the mutex \n
+ * FOSA_ENOMEM: Insufficient memory exists to initialize the mutex \n
+ * FOSA_EBUSY: The system has detected an attempt to reinitialize the mutex
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_mutex_init(fosa_mutex_t *mutex, int prioceiling);
+
+/**
+ * fosa_mutex_destroy()
+ *
+ * Destroy a frsh mutex
+ *
+ * The mutex pointed to by mutex is destroyed
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_EINVAL: the value of mutex is invalid \n
+ * FOSA_EBUSY: The mutex is in use (is locked)\n
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_mutex_destroy(fosa_mutex_t *mutex);
+
+/**
+ * fosa_mutex_set_prioceiling()
+ *
+ * Dynamically set the priority ceiling of a mutex
+ *
+ * This function locks the mutex (blocking the calling thread if
+ * necessary) and after it is locked it changes its priority ceiling
+ * to the value specified by new_ceiling, and then it unlocks the
+ * mutex. The previous value of the ceiling is returned in
+ * old_ceiling.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_EINVAL: the value of mutex or prioceiling is invalid \n
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_mutex_set_prioceiling
+ (fosa_mutex_t *mutex, int new_ceiling, int *old_ceiling);
+
+/**
+ * fosa_mutex_get_prioceiling()
+ *
+ * Dynamically get the priority ceiling of a mutex
+ *
+ * This function copies into the variable pointed to by ceiling the
+ * current priority ceiling of the mutex referenced by mutex
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ *
+ * FOSA_EINVAL: the value of mutex is invalid \n
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_mutex_get_prioceiling(const fosa_mutex_t *mutex, int *ceiling);
+
+/**
+ * fosa_mutex_lock()
+ *
+ * Lock a mutex
+ *
+ * This function locks the mutex specified by mutex. If it is already
+ * locked, the calling thread blocks until the mutex becomes
+ * available. The operation returns with the mutex in the locked
+ * state, with the calling thread as its owner.
+ *
+ * Returns 0 if successful; otherwise it returns an error code: \n
+ *
+ * FOSA_EINVAL: the value of mutex is invalid, or the priority of the
+ * calling thread is higher than the priority ceiling of
+ * the mutex \n
+ *
+ * FOSA_EDEADLK: the current thread already owns this mutex \n
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_mutex_lock(fosa_mutex_t *mutex);
+
+/**
+ * fosa_mutex_trylock()
+ *
+ * Try locking a mutex
+ *
+ * This function is identical to fosa_mutex_lock() except that if the
+ * mutex is already locked the call returns immediately with an error
+ * indication.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of mutex is invalid, or the priority of the
+ * calling thread is higher than the priority ceiling of the
+ * mutex \n
+ * FOSA_EBUSY: the mutex was already locked \n
+ *
+ * Alternatively, except for FOSA_EBUSY, in case of error the
+ * implementation is allowed to notify it to the system console and
+ * then terminate the FRSH implementation and dependant applications
+ **/
+int fosa_mutex_trylock(fosa_mutex_t *mutex);
+
+/**
+ * fosa_mutex_unlock()
+ *
+ * Unlock a mutex
+ *
+ * This function must be called by the owner of the mutex referenced
+ * by mutex, to unlock it. If there are threads blocked on the mutex
+ * the mutex becomes available and the highest priority thread is
+ * awakened to acquire the mutex.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of mutex is invalid
+ * FOSA_EPERM: the calling thread is not the owner of the mutex
+ *
+ * Alternatively, except for FOSA_EBUSY, in case of error the
+ * implementation is allowed to notify it to the system console and
+ * then terminate the FRSH implementation and dependant applications
+ **/
+int fosa_mutex_unlock(fosa_mutex_t *mutex);
+
+
+/**********************
+ * Condition variables
+ *********************/
+
+/**
+ * fosa_cond_init()
+ *
+ * Initiatize a condition variable
+ *
+ * The condition variable referenced by cond is initialized with
+ * the attributes required by the FOSA implementation.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EAGAIN: the system lacked the necessary resources to create the
+ * condition variable
+ * FOSA_ENOMEM: Insufficient memory exists to initialize the condition variable
+ * FOSA_EBUSY: The system has detected an attempt to reinitialize the
+ * condition variable
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_cond_init(fosa_cond_t *cond);
+
+/**
+ * fosa_cond_destroy()
+ *
+ * Destroy a condition variable
+ *
+ * The condition variable pointed to by cond is destroyed
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of cond is invalid
+ * FOSA_EBUSY: The condition variable is in use (a thread is waiting on it)
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_cond_destroy(fosa_cond_t *cond);
+
+/**
+ * fosa_cond_signal()
+ *
+ * Signal a condition variable
+ *
+ * This call unblocks at least one of the threads that are waiting on
+ * the condition variable referenced by cond. If there are no threads
+ * waiting, the function has no effect
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of cond is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_cond_signal(fosa_cond_t *cond);
+
+/**
+ * fosa_cond_broadcast()
+ *
+ * Broadcast a condition variable
+ *
+ * This call unblocks all of the threads that are waiting on the
+ * condition variable referenced by cond. If there are no threads
+ * waiting, the function has no effect.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of cond is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_cond_broadcast(fosa_cond_t *cond);
+
+/**
+ * fosa_cond_wait()
+ *
+ * Wait at a condition variable
+ *
+ * This call is used to block on the condition variable referenced by
+ * cond. It shall be called with the mutex referenced by mutex
+ * locked. The function releases the mutex and blocks the calling
+ * thread until the condition is signalled by some other thread and
+ * the calling thread is awakened. Then it locks the mutex and
+ * returns with the mutex locked by the calling thread.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of cond or mutex is invalid, or different
+ * mutexes were used for concurrent wait operations on cond, or
+ * the mutex was not owned by the calling thread
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_cond_wait(fosa_cond_t *cond, fosa_mutex_t *mutex);
+
+/**
+ * fosa_cond_timedwait()
+ *
+ * Wait at a condition variable, with a timeout
+ *
+ * This function is equal to fosa_cond_wait(), except that the maximum
+ * wait time is limited to the absolute time referenced by abstime, as
+ * measured by the FOSA_CLOCK_ABSOLUTE clock.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of cond or mutex or abstime is invalid, or different
+ * mutexes were used for concurrent wait operations on cond, or
+ * the mutex was not owned by the calling thread
+ * FOSA_ETIMEDOUT: the timeout expired
+ *
+ * Alternatively, except for FOSA_ETIMEDOUT, in case of error the
+ * implementation is allowed to notify it to the system console and
+ * then terminate the FRSH implementation and dependant applications
+ **/
+int fosa_cond_timedwait(fosa_cond_t *cond, fosa_mutex_t *mutex,
+ const fosa_abs_time_t *abstime);
+
+/*@}*/
+
+
+FOSA_CPP_END_DECLS
+
+#endif /* !FOSA_MUTEX_AND_CONDVARS_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_opaque_types.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+// Implementation dependent definitions
+
+#ifndef _FOSA_OPAQUE_TYPES_H_
+#define _FOSA_OPAQUE_TYPES_H_
+
+#include <stdbool.h>
+
+#include "fosa_cpp_macros.h"
+#include "fosa_opaque_types_time.h"
+
+/////////////////////// MARTE_OS /////////////////////////////
+
+#ifdef MARTE_OS
+
+#include <pthread.h>
+#include <signal.h>
+#include <time.h>
+#include <sched.h>
+#include <errno.h>
+
+FOSA_CPP_BEGIN_DECLS
+
+
+/* Thread and signals */
+/**********************/
+typedef pthread_t FOSA_THREAD_ID_T_OPAQUE;
+typedef pthread_attr_t FOSA_THREAD_ATTR_T_OPAQUE;
+
+typedef int FOSA_SIGNAL_T_OPAQUE;
+/* Signal info is defined as a union in thread_and_signals */
+
+#define FOSA_SIGNAL_MIN SIGRTMIN
+#define FOSA_SIGNAL_MAX SIGRTMIN+0
+
+#define FOSA_NULL_SIGNAL 0
+
+/* Clocks and timers */
+/**********************/
+typedef clockid_t FOSA_CLOCK_ID_T_OPAQUE;
+typedef timer_t FOSA_TIMER_ID_T_OPAQUE;
+
+#define FOSA_SYSTEM_CLOCK_OPAQUE CLOCK_MONOTONIC
+
+/* Mutex and conditional variables */
+/***********************************/
+typedef pthread_mutex_t FOSA_MUTEX_T_OPAQUE;
+typedef pthread_cond_t FOSA_COND_T_OPAQUE;
+
+
+/* Application defined Scheduling */
+/**********************************/
+#define FOSA_ADS_ACTIONS_T_OPAQUE struct \
+{ \
+ posix_appsched_actions_t actions; \
+ struct timespec *timeout_ptr; \
+ struct timespec timeout; \
+ bool rejected; \
+ bool suspended; \
+ bool activated; \
+}
+
+
+/* Local jump */
+/**************/
+#include "misc/marte_non_local_jmp.h"
+
+#define FOSA_LONG_JUMP_CONTEXT_T_OPAQUE struct { \
+ marte_nonlocaljmp_context_t marte_context; \
+ fosa_thread_id_t tid; \
+}
+
+
+/* Group clocks */
+/****************/
+typedef marte_thread_set_t FOSA_THREAD_SET_ID_T_OPAQUE;
+
+#define FOSA_NULL_THREAD_SET_ID_OPAQUE 0 /* In MaRTE-OS thread_set_t are
+ * pointers */
+
+/* FOSA errors */
+/***************/
+/** Not enough memory available **/
+#define FOSA_ENOMEM ENOMEM
+
+/** Invalid parameter **/
+#define FOSA_EINVAL EINVAL
+
+/** Still pending information **/
+#define FOSA_EAGAIN EAGAIN
+
+/** FOSA ADS errors **/
+#ifdef MARTE_OS
+#define EREJECT 201 /* (for linux_lib_arch) Appsched has rejected object */
+#endif
+
+#define FOSA_EREJECT EREJECT
+#define FOSA_EMASKED -2
+#define FOSA_EPOLICY -3
+
+#define FOSA_ETIMEDOUT ETIMEDOUT
+
+/* Not found in search (non existing thread, thread_set...) */
+#define FOSA_ESRCH ESRCH
+#define FOSA_ENOTSUP ENOTSUP
+
+#endif
+
+/////////////////////// End of MARTE_OS /////////////////////////////
+
+
+/////////////////////// RT_LINUX ///////////////////////////
+
+#ifdef RT_LINUX
+
+/* Very similar to MARTE_OS but I leave separate for clarity */
+
+#include <pthread.h>
+#include <signal.h>
+#include <time.h>
+#include <sched.h>
+#include <errno.h>
+#include <rtl_timer.h>
+
+
+/* Threads and signals */
+/***********************/
+#define FOSA_THREAD_ID_T_OPAQUE pthread_t
+
+typedef pthread_attr_t FOSA_THREAD_ATTR_T_OPAQUE;
+typedef int FOSA_SIGNAL_T_OPAQUE;
+/* Signal info is defined as a union in fosa_types.h */
+
+// The minimum and maximum signal numbers that may be used by the FRSH
+// implementation
+#define FOSA_SIGNAL_MIN SIGRTMIN
+#define FOSA_SIGNAL_MAX SIGRTMIN+0
+#define FOSA_NULL_SIGNAL 0
+
+/* Clocks and timers */
+/*********************/
+#define FOSA_CLOCK_ID_T_OPAQUE clockid_t
+#define FOSA_TIMER_ID_T_OPAQUE timer_t
+#define FOSA_SYSTEM_CLOCK_OPAQUE CLOCK_MONOTONIC
+
+/* Mutex and cond vars */
+/***********************/
+typedef pthread_mutex_t FOSA_MUTEX_T_OPAQUE;
+#define FOSA_COND_T_OPAQUE pthread_cond_t
+
+/* Thread groups */
+/*****************/
+typedef int FOSA_THREAD_SET_ID_T_OPAQUE
+
+/* FOSA Errors */
+/***************/
+/** Not enough memory available **/
+#define FOSA_ENOMEM ENOMEM
+/** Invalid parameter **/
+#define FOSA_EINVAL EINVAL
+/** Still pending information **/
+#define FOSA_EAGAIN EAGAIN
+
+/** FOSA ADS errors **/
+#define FOSA_EREJECT EREJECT
+#define FOSA_EMASKED -2
+#define FOSA_EPOLICY -3
+
+#define FOSA_ETIMEDOUT ETIMEDOUT
+
+#endif
+
+/////////////////////// End of RT_LINUX /////////////////////////////
+
+
+////////////////////////// OSE //////////////////////////////////////
+
+#ifdef OSE
+
+
+
+/* Put OSE dependent includes and defines here */
+
+#endif /* OSE */
+
+
+
+/////////////////////// AQuoSA ///////////////////////////
+
+#ifdef AQuoSA
+
+#include <unistd.h>
+#include <linux/unistd.h>
+
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 500
+#endif
+#ifndef __USE_UNIX98
+#define __USE_UNIX98
+#endif
+#include <pthread.h>
+
+#include <signal.h>
+#include <setjmp.h>
+#include <errno.h>
+#include <time.h>
+
+FOSA_CPP_BEGIN_DECLS
+
+/* Local Jump */
+/**************/
+typedef struct {
+ sigjmp_buf setjmp_context;
+ int setjmp_retvalue;
+} FOSA_LONG_JUMP_CONTEXT_T_OPAQUE;
+
+
+/* Threads and signals */
+/***********************/
+typedef struct {
+ pthread_t pthread_id;
+ pid_t linux_pid;
+ pid_t linux_tid;
+} FOSA_THREAD_ID_T_OPAQUE;
+
+
+typedef pthread_attr_t FOSA_THREAD_ATTR_T_OPAQUE;
+typedef int FOSA_SIGNAL_T_OPAQUE;
+
+
+// The minimum and maximum signal numbers that may be used by the FRSH
+// implementation
+#define FOSA_SIGNAL_MIN SIGRTMIN
+#define FOSA_SIGNAL_MAX SIGRTMIN+0
+
+#define FOSA_NULL_SIGNAL 0
+
+
+/* Thread groups */
+/*****************/
+typedef int FOSA_THREAD_SET_ID_T_OPAQUE;
+
+/* Clocks and signals */
+/**********************/
+#define FOSA_CLOCK_ID_T_OPAQUE clockid_t
+#define FOSA_SYSTEM_CLOCK_OPAQUE CLOCK_MONOTONIC
+#define FOSA_TIMER_ID_T_OPAQUE timer_t
+
+
+
+/* Mutex and cond vars */
+/***********************/
+typedef pthread_mutex_t FOSA_MUTEX_T_OPAQUE;
+#define FOSA_COND_T_OPAQUE pthread_cond_t
+
+
+/* Application Defined Scheduling */
+/**********************************/
+/* hack to get AQuoSA sources compile without having none
+ * of the application level scheduler header files and symbols */
+#define posix_appsched_actions_t int
+
+#define FOSA_ADS_ACTIONS_T_OPAQUE posix_appsched_actions_t
+
+
+/* FOSA Errors */
+
+/** Not enough memory available **/
+#define FOSA_ENOMEM ENOMEM
+
+/** Invalid parameter **/
+#define FOSA_EINVAL EINVAL
+
+/** Still pending information **/
+#define FOSA_EAGAIN EAGAIN
+
+#define FOSA_EREJECT EREJECT
+#define FOSA_EMASKED -2
+#define FOSA_EPOLICY -3
+
+#define FOSA_ETIMEDOUT ETIMEDOUT
+
+
+#endif
+////////////////// END of AQuoSA //////////////////////
+
+
+
+///////////////////////////////// PARTIKLE /////////////////////////////////////
+#if defined(PARTIKLE)
+
+#include <pthread.h>
+#include <signal.h>
+#include <time.h>
+#include <sched.h>
+#include <stdlib.h>
+#include <setjmp.h>
+#include <limits.h>
+
+typedef struct {
+ posix_appsched_actions_t actions;
+ struct timespec * timeout_ptr;
+ struct timespec timeout;
+ bool rejected;
+ bool suspended;
+ bool activated;
+} FOSA_ADS_ACTIONS_T_OPAQUE;
+
+
+typedef pthread_t FOSA_THREAD_ID_T_OPAQUE;
+typedef pthread_attr_t FOSA_THREAD_ATTR_T_OPAQUE;
+typedef int FOSA_SIGNAL_T_OPAQUE;
+typedef clockid_t FOSA_CLOCK_ID_T_OPAQUE;
+typedef timer_t FOSA_TIMER_ID_T_OPAQUE;
+typedef pthread_cond_t FOSA_COND_T_OPAQUE;
+typedef pthread_mutex_t FOSA_MUTEX_T_OPAQUE;
+typedef unsigned long FOSA_LONG_JUMP_CONTEXT_T_OPAQUE [32];
+typedef group_clock_t FOSA_THREAD_SET_ID_T_OPAQUE;
+
+#define FOSA_NULL_THREAD_SET_ID_OPAQUE 0x0;
+
+enum _fosa_clocks_e {
+ FOSA_SYSTEM_CLOCK_OPAQUE = CLOCK_MONOTONIC
+};
+
+#define LONGJMP_NSIG 3
+
+#if LONGJMP_NSIG > (RTSIG_MAX - 1)
+# error LONGJMP_NSIG too big (LONGJMP_NSIG > RTSIG_MAX - 1)
+#endif
+
+enum _fosa_signal_limits_e {
+ LONGJMP_FIRSTSIG = SIGRTMAX - LONGJMP_NSIG + 1,
+ FOSA_SIGNAL_MAX = LONGJMP_FIRSTSIG - 1,
+ FOSA_SIGNAL_MIN = SIGRTMIN,
+ FOSA_NULL_SIGNAL = -1,
+};
+
+
+enum _fosa_errors_e {
+ FOSA_EINVAL = EINVAL,
+ FOSA_EAGAIN = EAGAIN,
+ FOSA_EREJECT = EREJECT,
+ FOSA_EMASKED = EMASKED,
+ FOSA_EPOLICY = EPOLICY,
+ FOSA_ETIMEDOUT = ETIMEDOUT,
+ FOSA_ENOMEM = ENOMEM,
+};
+
+
+#endif
+/////////////////////////////// PARTIKLE END //////////////////////////////////
+
+
+
+////////////////////////// VIRTUAL TIME //////////////////////////////////////
+#ifdef VIRTUAL_TIME
+
+/* Time */
+/********/
+// typedef struct timespec fosa_rel_time_t;
+// typedef struct timespec fosa_abs_time_t;
+
+#include <fosa_vt.h>
+
+#define FOSA_THREAD_ID_T_OPAQUE vt_posix_process_t
+#define FOSA_THREAD_ATTR_T_OPAQUE fosa_thread_attr_t
+#define FOSA_SIGNAL_T_OPAQUE int
+
+#define FOSA_MUTEX_T_OPAQUE fosa_mutex_t
+
+// The minimum and maximum signal numbers that may be used by the FRSH
+// implementation
+#define FOSA_SIGNAL_MIN 8
+#define FOSA_SIGNAL_MAX 31
+
+// the min. and max. priority a fosa thread can have
+#define FOSA_PRIORITY_MAX VT_PRIORITY_MIN - 1
+#define FOSA_PRIORITY_MIN VT_PRIORITY_MAX
+
+#define FOSA_NULL_SIGNAL 0
+
+/* FOSA Errors and return values*/
+
+/** Invalid parameter **/
+#define FOSA_EINVAL -1
+
+/** Not enough memory available **/
+#define FOSA_ENOMEM -2
+
+/** Still pending information **/
+#define FOSA_EAGAIN -3
+
+/** Mutex not available **/
+#define FOSA_EBUSY -4
+
+/** Cond var timedout **/
+#define FOSA_ETIMEDOUT -5
+
+/** FOSA ADS errors **/
+#define FOSA_EREJECT -6
+#define FOSA_EMASKED -7
+
+
+/** Sched policy not correct */
+#define FOSA_EPOLICY -8
+
+/** the value given by thread_id is not valid for ADS */
+#define FOSA_ESRCH -9
+
+/** retval if no action performed **/
+#define FOSA_NO_ACTION 0
+
+#endif /* VIRTUAL_TIME */
+//////////////////////////End of VIRTUAL TIME ///////////////////////////////////
+
+
+////////////////////////// DUMMY_OS //////////////////////////////////////
+
+#if defined(DUMMY_OS)
+
+/* With this define we make sure that we are truly POSIX and OSE */
+/* independent at the FRSH code. */
+/*****************************************************************/
+
+/* Time */
+/********/
+// typedef struct timespec fosa_rel_time_t;
+// typedef struct timespec fosa_abs_time_t;
+
+/* Thread and signals */
+/**********************/
+typedef int FOSA_THREAD_ID_T_OPAQUE;
+typedef int FOSA_THREAD_ATTR_T_OPAQUE;
+
+typedef int FOSA_SIGNAL_T_OPAQUE;
+typedef int FOSA_SIGNAL_INFO_T_OPAQUE;
+
+/* Signal info is defined as a union in thread_and_signals */
+
+#define FOSA_SIGNAL_MIN 42
+#define FOSA_SIGNAL_MAX 44
+
+#define FOSA_NULL_SIGNAL 0
+
+/* Clocks and timers */
+/**********************/
+typedef int FOSA_CLOCK_ID_T_OPAQUE;
+typedef int FOSA_TIMER_ID_T_OPAQUE;
+
+#define FOSA_SYSTEM_CLOCK_OPAQUE 25
+
+/* Mutex and conditional variables */
+/***********************************/
+typedef int FOSA_MUTEX_T_OPAQUE;
+typedef int FOSA_COND_T_OPAQUE;
+
+/* Application defined Scheduling */
+/**********************************/
+#define FOSA_ADS_ACTIONS_T_OPAQUE int
+
+
+#endif /* DUMMY */
+//////////////////////////End of DUMMY_OS ////////////////////////////////////
+
+FOSA_CPP_END_DECLS
+
+
+#endif // _FOSA_OPAQUE_TYPES_H_
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_opaque_types_time.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+// Implementation dependent definitions
+
+#ifndef _FOSA_OPAQUE_TYPES_TIME_H_
+#define _FOSA_OPAQUE_TYPES_TIME_H_
+
+
+/////////////////////// MARTE_OS /////////////////////////////
+
+#ifdef MARTE_OS
+
+/**
+ Choose between:
+ - struct timespec
+ - numeric type (long, .long long, short)
+**/
+
+#define FOSA_TIME_TIMESPEC
+
+typedef struct timespec FOSA_REL_TIME_T_OPAQUE;
+typedef struct timespec FOSA_ABS_TIME_T_OPAQUE;
+
+
+/*
+
+#define FOSA_TIME_NUMERIC
+#define FOSA_TIME_BASE 9 // 9 for nanosecods
+ // 6 for microseconds
+ // 3 for miliseconds
+
+typedef long long FOSA_REL_TIME_T_OPAQUE;
+typedef unsigned long long FOSA_ABS_TIME_T_OPAQUE;
+
+*/
+
+/**
+ Possible additions: FOSA_ABS_TIME_MAX, FOSA_ABS_TIME_MIN,
+ FOSA_REL_TIME_MAX, FOSA_REL_TIME_MIN to protect
+ operations against possible overflows or handle circular
+ increments.
+**/
+
+#endif /* MARTE_OS */
+
+/////////////////////// End of MARTE_OS /////////////////////////////
+
+
+/////////////////////// RT_LINUX ///////////////////////////
+
+#ifdef RT_LINUX
+
+/**
+ Choose between:
+ - struct timespec
+ - numeric type (long, .long long, short)
+**/
+/*
+#define FOSA_TIME_TIMESPEC
+
+typedef struct timespec FOSA_REL_TIME_T_OPAQUE;
+typedef struct timespec FOSA_ABS_TIME_T_OPAQUE;
+
+*/
+
+/*
+
+#define FOSA_TIME_NUMERIC
+#define FOSA_TIME_BASE 9 // 9 for nanosecods
+ // 6 for microseconds
+ // 3 for miliseconds
+
+typedef long long FOSA_REL_TIME_T_OPAQUE;
+typedef unsigned long long FOSA_ABS_TIME_T_OPAQUE;
+
+*/
+
+/**
+ Possible additions: FOSA_ABS_TIME_MAX, FOSA_ABS_TIME_MIN,
+ FOSA_REL_TIME_MAX, FOSA_REL_TIME_MIN to protect
+ operations against possible overflows or handle circular
+ increments.
+**/
+
+#endif /* RT_LINUX */
+
+
+/////////////////////// End of RT_LINUX /////////////////////////////
+
+
+
+////////////////////////// OSE //////////////////////////////////////
+
+#ifdef OSE
+
+/**
+ Choose between:
+ - struct timespec
+ - numeric type (long, .long long, short)
+**/
+
+#define FOSA_TIME_TIMESPEC
+
+typedef struct timespec FOSA_REL_TIME_T_OPAQUE;
+typedef struct timespec FOSA_ABS_TIME_T_OPAQUE;
+
+/*
+#define FOSA_TIME_NUMERIC
+#define FOSA_TIME_BASE 9 // 9 for nanosecods
+ // 6 for microseconds
+ // 3 for miliseconds
+
+typedef long long FOSA_REL_TIME_T_OPAQUE;
+typedef unsigned long long FOSA_ABS_TIME_T_OPAQUE;
+
+*/
+
+/**
+ Possible additions: FOSA_ABS_TIME_MAX, FOSA_ABS_TIME_MIN,
+ FOSA_REL_TIME_MAX, FOSA_REL_TIME_MIN to protect
+ operations against possible overflows or handle circular
+ increments.
+**/
+
+
+#endif /* OSE */
+
+/////////////////////// End of OSE ///////////////////////////////////
+
+/////////////////////// AQuoSA ///////////////////////////
+
+#ifdef AQuoSA
+
+/**
+ Choose between:
+ - struct timespec
+ - numeric type (long, .long long, short)
+**/
+
+
+#define FOSA_TIME_TIMESPEC
+
+typedef struct timespec FOSA_REL_TIME_T_OPAQUE;
+typedef struct timespec FOSA_ABS_TIME_T_OPAQUE;
+
+
+/*
+
+#define FOSA_TIME_NUMERIC
+#define FOSA_TIME_BASE 9 // 9 for nanosecods
+ // 6 for microseconds
+ // 3 for miliseconds
+
+typedef long long FOSA_REL_TIME_T_OPAQUE;
+typedef unsigned long long FOSA_ABS_TIME_T_OPAQUE;
+
+*/
+/**
+ Possible additions: FOSA_ABS_TIME_MAX, FOSA_ABS_TIME_MIN,
+ FOSA_REL_TIME_MAX, FOSA_REL_TIME_MIN to protect
+ operations against possible overflows or handle circular
+ increments.
+**/
+
+
+#endif /* AQuoSA */
+
+/////////////////////// End of AQuoSA ////////////////////////////////
+
+
+/////////////////////// PARTIKLE ///////////////////////////
+
+#ifdef PARTIKLE
+
+/**
+ Choose between:
+ - struct timespec
+ - numeric type (long, .long long, short)
+**/
+
+
+#define FOSA_TIME_TIMESPEC
+
+typedef struct timespec FOSA_REL_TIME_T_OPAQUE;
+typedef struct timespec FOSA_ABS_TIME_T_OPAQUE;
+
+/*
+
+#define FOSA_TIME_NUMERIC
+#define FOSA_TIME_BASE 9 // 9 for nanosecods
+ // 6 for microseconds
+ // 3 for miliseconds
+
+typedef long long FOSA_REL_TIME_T_OPAQUE;
+typedef unsigned long long FOSA_ABS_TIME_T_OPAQUE;
+
+*/
+
+/**
+ Possible additions: FOSA_ABS_TIME_MAX, FOSA_ABS_TIME_MIN,
+ FOSA_REL_TIME_MAX, FOSA_REL_TIME_MIN to protect
+ operations against possible overflows or handle circular
+ increments.
+**/
+
+
+#endif /* PARTIKLE */
+
+/////////////////////// End of PARTIKLE ////////////////////////////////
+
+/////////////////////// VIRTUAL_TIME ///////////////////////////
+
+#ifdef VIRTUAL_TIME
+
+/**
+ Choose between:
+ - struct timespec
+ - numeric type (long, .long long, short)
+**/
+
+
+
+#define FOSA_TIME_TIMESPEC
+
+typedef struct timespec FOSA_REL_TIME_T_OPAQUE;
+typedef struct timespec FOSA_ABS_TIME_T_OPAQUE;
+
+
+/*
+
+#define FOSA_TIME_NUMERIC
+#define FOSA_TIME_BASE 9 // 9 for nanosecods
+ // 6 for microseconds
+ // 3 for miliseconds
+
+typedef long long FOSA_REL_TIME_T_OPAQUE;
+typedef unsigned long long FOSA_ABS_TIME_T_OPAQUE;
+
+*/
+
+/**
+ Possible additions: FOSA_ABS_TIME_MAX, FOSA_ABS_TIME_MIN,
+ FOSA_REL_TIME_MAX, FOSA_REL_TIME_MIN to protect
+ operations against possible overflows or handle circular
+ increments.
+**/
+
+
+#endif /* VIRTUAL_TIME */
+
+/////////////////////// End of VIRTUAL_TIME //////////////////////////
+
+/////////////////////// DUMMY_OS ///////////////////////////
+
+#ifdef DUMMY_OS
+
+/**
+ Choose between:
+ - struct timespec
+ - numeric type (long, .long long, short)
+**/
+
+
+#define FOSA_TIME_TIMESPEC
+
+typedef struct timespec FOSA_REL_TIME_T_OPAQUE;
+typedef struct timespec FOSA_ABS_TIME_T_OPAQUE;
+
+
+/*
+
+#define FOSA_TIME_NUMERIC
+#define FOSA_TIME_BASE 9 // 9 for nanosecods
+ // 6 for microseconds
+ // 3 for miliseconds
+
+typedef long long FOSA_REL_TIME_T_OPAQUE;
+typedef unsigned long long FOSA_ABS_TIME_T_OPAQUE;
+
+*/
+
+/**
+ Possible additions: FOSA_ABS_TIME_MAX, FOSA_ABS_TIME_MIN,
+ FOSA_REL_TIME_MAX, FOSA_REL_TIME_MIN to protect
+ operations against possible overflows or handle circular
+ increments.
+**/
+
+
+#endif /* DUMMY_OS */
+
+/////////////////////// End of DUMMY_OS //////////////////////////
+
+#endif /* FOSA_OPAQUE_TYPES_TIME_H */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_time.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+#ifndef FOSA_PLATFORM_VALUES_H_
+#define FOSA_PLATFORM_VALUES_H_
+
+#include "fosa_types.h"
+
+FOSA_CPP_BEGIN_DECLS
+
+typedef unsigned int fosa_resource_id_t;
+
+/**
+ * fosa_get_cpu_resource_id()
+ *
+ * Obtain the cpu resource id of the current node by making use of any
+ * mechanism that allows to distinguish between nodes (ie MAC addresses,
+ * configuration parameters, etc..)
+ */
+
+int fosa_get_cpu_resource_id(fosa_resource_id_t *cpu_id);
+
+FOSA_CPP_END_DECLS
+
+#endif // FOSA_PLATFORM_VALUES_H_
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_thread_and_signals.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+
+#ifndef FOSA_THREAD_AND_SIGNALS_H_
+#define FOSA_THREAD_AND_SIGNALS_H_
+
+#include "fosa_types.h"
+
+
+FOSA_CPP_BEGIN_DECLS
+
+
+/**
+ * @defgroup threadandsignals Thread and Signals
+ * @ingroup fosa
+ *
+ * This module defines the functions that manipulate fosa_threads and
+ * fosa_signals inside FRSH implementation.
+ *
+ * Applications can refer to FRSH threads but they cannot create them
+ * directly, instead they must use frsh_thread_create*() which in turn
+ * use fosa_thread_create().
+ *
+ * For signals, we assume that the OS provides a direct mapping
+ * for fosa_signal_t and fosa_signal_info_t in the native interface.
+ *
+ * @{
+ **/
+
+
+
+/*************************
+ * Thread identification
+ *************************/
+
+/**
+ * fosa_thread_equal()
+ *
+ * Compare two thread identifiers to determine if they refer to the
+ * same thread
+ **/
+bool fosa_thread_equal(fosa_thread_id_t t1, fosa_thread_id_t t2);
+
+
+/**
+ * fosa_thread_self()
+ *
+ * Return the thread id of the calling thread
+ **/
+fosa_thread_id_t fosa_thread_self();
+
+
+/*************************
+ * Thread attributes
+ *************************/
+
+/**
+ * fosa_thread_attr_init()
+ *
+ * Initialize a thread attributes object
+ *
+ * This function initializes the object pointed to by attr to all
+ * the default values defined by FRSH
+ *
+ * @return 0 if successful; otherwise it returns \n
+ * FOSA_ENOMEM: insufficient memory exists to initialize the thread
+ * attributes object
+ **/
+int fosa_thread_attr_init(fosa_thread_attr_t *attr);
+
+
+/**
+ * fosa_thread_attr_destroy()
+ *
+ * Destroy a thread attributes object
+ *
+ * This function is used to destroy the thread attributes object,
+ * pointed to by attr, and deallocate any system resources allocated for it
+ *
+ * Returns 0
+ */
+int fosa_thread_attr_destroy(fosa_thread_attr_t *attr);
+
+
+/**
+ * fosa_thread_attr_set_stacksize()
+ *
+ * Set the thread minimum stack size in a thread attributes object
+ *
+ * This function sets the minimum stack size of the thread attributes
+ * object attr to the value given by stacksize, in bytes. This
+ * function has no runtime effect on the stack size, except when the
+ * attributes object is used to create a thread, when it will be
+ * created with the specified minimum stack size
+ *
+ * @return 0 if successful, or the following error code:
+ * FOSA_EINVAL: the specified stacksize value is not supported in
+ * this implementation
+ */
+int fosa_thread_attr_set_stacksize(fosa_thread_attr_t *attr,
+ size_t stacksize);
+
+/**
+ * fosa_thread_attr_get_stacksize()
+ *
+ * Get the thread minimum stack size from a thread attributes object
+ *
+ * This function sets the variable pointed to by stacksize to the
+ * minimum stack size stored in the thread attributes object attr.
+ *
+ * @return 0
+ */
+int fosa_thread_attr_get_stacksize(const fosa_thread_attr_t *attr,
+ size_t *stacksize);
+
+
+/*************************
+ * Thread creation and termination
+ *************************/
+
+/**
+ * fosa_thread_create()
+ *
+ * This function creates a new thread using the attributes specified
+ * in attr. If attr is NULL, default attributes are used. The new
+ * thread starts running immediately, executing the function specified
+ * by code, with an argument equal to arg. Upon successful return, the
+ * variable pointed to by tid will contain the identifier of the newly
+ * created thread. The set of signals that may be synchronously
+ * accepted is inherited from the parent thread.
+ *
+ * Returns 0 if successful; otherwise it returs a code error:
+ *
+ * FOSA_EAGAIN: the system lacks the necessary resources to create a
+ * new thread or the maximum number of threads has been
+ * reached
+ *
+ * FOSA_EINVAL: the value specified by attr is invalid (for instance,
+ * it has not been correctly initialized)
+ *
+ * FOSA_EREJECT: the cretion of the thread was rejected by the frsh scheduler
+ * possibly because of incorrect attributes, or because the
+ * requested minimum capacity cannot be guaranteed
+ *
+ **/
+ int fosa_thread_create
+ (fosa_thread_id_t *tid, const fosa_thread_attr_t *attr,
+ fosa_thread_code_t code, void * arg);
+
+
+/**
+ * Note: no thread termination primitive is provided. The termination
+ * of a thread will be notified by the system to the FRSH scheduler
+ * through the scheduler API
+ **/
+
+
+/**************************************************
+ * Thread-specific data
+ * (extended with access from a different thread)
+ *
+ * Several data items (pointers) may be associated with each thread
+ * Each item is identified through a key, an integer value between 0
+ * and FOSA_MAX_KEYS-1. The caller is responsible of allocating and
+ * deallocating the memory area pointed to by the pointer
+ **************************************************/
+
+/**
+ * fosa_key_create()
+ *
+ * Create a new key for thread specific data.
+ *
+ * Prior to setting data in a key, we need ask the system to create
+ * one for us. The thread specific data of all the threads is set to
+ * the value NULL until changed to a different value via
+ * fosa_thread_set_specific_data().
+ *
+ * @return 0 if successful \n
+ * FOSA_EINVAL If we already have reached the FOSA_MAX_KEYS limit.
+ * FOSA_ENOMEM If there are no enough memory resources to
+ * create the key.
+ **/
+int fosa_key_create(int *key);
+
+/**
+ * fosa_key_destroy()
+ *
+ * Destroy a key
+ *
+ * This destroys the key and disables its use in the system
+ *
+ * @return 0 if successful \n
+ * FOSA_EINVAL The key is not initialised or is not in FOSA key range.
+ **/
+int fosa_key_destroy(int key);
+
+
+/**
+ * fosa_thread_set_specific_data()
+ *
+ * Set thread-specific data
+ *
+ * For the thread identified by tid, the thread-specifid data field
+ * identified by key will be set to the value specified by value
+ *
+ * Returns 0 if successful; otherwise, an error code is returned
+ * FOSA_EINVAL: the value of key is not between 0 and FOSA_MAX_KEYS-1
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+ int fosa_thread_set_specific_data
+ (int key, fosa_thread_id_t tid, const void * value);
+
+/**
+ * fosa_thread_get_specific_data()
+ *
+ * Get thread-specific data
+ *
+ * For the thread identified by tid, the thread-specifid data field
+ * identified by key will be copied to the variable pointed to by value
+ *
+ * Returns 0 if successful; otherwise, an error code is returned
+ * FOSA_EINVAL: the value of key is not between 0 and FOSA_MAX_KEYS-1
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_get_specific_data(int key, fosa_thread_id_t tid,
+ void ** value);
+
+
+/******************************************************************
+ * Thread scheduling
+ *
+ * This implementation of FRSH assumes an underlying fixed priority
+ * scheduler with priorities in a range, with a minimum and a
+ * maximumm, a number of priority levels with at least 31
+ * priorities. A larger number implies a larger priority. In systems
+ * in which the underlying scheduler uses the opposite convention, a
+ * mapping is automatically provided by the OS adaptation layer.
+ *******************************************************************/
+
+/**
+ * fosa_get_priority_max()
+ *
+ * Return the maximum priority value used in this implementation
+ **/
+int fosa_get_priority_max();
+
+/**
+ * fosa_get_priority_min()
+ *
+ * Return the minimum priority value used in this implementation
+ **/
+int fosa_get_priority_min();
+
+/**
+ * fosa_thread_attr_set_prio()
+ *
+ * Change the priority of a thread attributes object
+ *
+ * The priority of the thread attriutes object specified by attr is
+ * set to the value specified by prio. This function has no runtime
+ * effect on the priority, except when the attributes object is used
+ * to create a thread, when it will be created with the specified
+ * priority
+ *
+ * Returns 0 if successful, or the following error code:
+ * FOSA_EINVAL: the specified priority value is not between the
+ * minimum and the maximum priorities defined in this
+ * FRSH implementation
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_set_prio(fosa_thread_attr_t *attr, int prio);
+
+/**
+ * fosa_thread_attr_get_prio()
+ *
+ * Get the priority from a thread attributes object
+ *
+ * This function sets the variable pointed to by prio to the
+ * priority stored in the thread attributes object attr.
+ *
+ * Returns 0
+ **/
+ int fosa_thread_attr_get_prio
+ (const fosa_thread_attr_t *attr, int *prio);
+
+/**
+ * fosa_thread_set_prio()
+ *
+ * Dynamically change the priority of a thread
+ *
+ * The priority of the thread identified by tid is
+ * set to the value specified by prio.
+ *
+ * Returns 0 if successful, or the following error code:
+ * FOSA_EINVAL: the specified priority value is not between the
+ * minimum and the maximum priorities defined in this
+ * FRSH implementation
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_set_prio(fosa_thread_id_t tid, int prio);
+
+/**
+ * fosa_thread_get_prio()
+ *
+ * Dynamically get the priority of a thread
+ *
+ * This function sets the variable pointed to by prio to the
+ * priority of the thread identified by tid
+ *
+ * Returns 0
+ **/
+int fosa_thread_get_prio (fosa_thread_id_t tid, int *prio);
+
+
+
+/*******************************************************************
+ * Signals
+ *
+ * Signals represent events that may be notified by the system, or
+ * sent explicitly by the application, and for which a thread may
+ * synchronously wait. Signals carry an associated piece of
+ * information (an integer or a pointer) and are queued until they are
+ * accepted. Signals are identified by an integer signal number (of
+ * the type fosa_signal_t) in the range FOSA_SIGNAL_MIN,
+ * FOSA_SIGNAL_MAX. This range is required to have at least <tbd>
+ * values.
+ *******************************************************************/
+
+/**
+ * fosa_set_accepted_signals()
+ *
+ * Establish the set of signals that may be synchronously accepted
+ * by the calling thread
+ *
+ * The function uses the array of signal numbers specified by set,
+ * which must be of size equal to size
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the array contains one or more values which are not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size
+ * is less than 0
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_set_accepted_signals(fosa_signal_t set[], int size);
+
+/**
+ * fosa_signal_queue()
+ *
+ * Queue a signal
+ *
+ * This function is used to explicitly send a signal with a specified
+ * value
+ *
+ * The signal number specified by signal is sent together with the
+ * information specified by info, to the thread identified by
+ * receiver. In those implementations that do not support queueing a
+ * signal with information to a thread (such as POSIX), the signal may
+ * be sent to any thread that is waiting for this signal via
+ * fosa_signal_wait(). Portability can be ensured by having the receiver
+ * thread be the one who is waiting for the signal.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the signal specified by signal is not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX
+ *
+ * FOSA_EAGAIN: no resources are available to queue the signal; the
+ * maximum number of queued signals has been reached, or a
+ * systemwide resource limit has been exceeded
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_signal_queue
+ (fosa_signal_t signal, fosa_signal_info_t info,
+ fosa_thread_id_t receiver);
+
+
+
+
+/**
+ * fosa_signal_wait()
+ *
+ * Wait for a signal
+ *
+ * The function waits for the arrival of one of the signals in the
+ * array of signal numbers specified by set, which must be of size
+ * equal to size. If there is a signal already queued, the function
+ * returns immediately. If there is no signal of the specified set
+ * queued, the calling thread is suspended until a signal from that
+ * set arrives. Upon return, if signal_received is not NULL the number
+ * of the signal received is stored in the variable pointed to by
+ * signal_received; and if info is not NULL the associated information
+ * is stored in the variable pointed to by info.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the array contains one or more values which are not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size
+ * is less than 0
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+ int fosa_signal_wait
+ (fosa_signal_t set[], int size, fosa_signal_t *signal_received,
+ fosa_signal_info_t *info);
+
+/**
+ * fosa_signal_timedwait()
+ *
+ * Timed wait for a signal
+ *
+ * This function behaves the same as fosa_signal_wait(), except that
+ * the suspension time is limited to the time interval specified in
+ * the fosa_rel_time_t value referenced by timeout.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the array contains one or more values which are not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size
+ * is less than 0, or timeout is invalid
+ * FOSA_EAGAIN: The timeout expired
+ *
+ * Alternatively, in case of the FOSA_EINVAL error the implementation is
+ * allowed to notify it to the system console and then terminate the
+ * FRSH implementation and dependant applications
+ **/
+ int fosa_signal_timedwait
+ (fosa_signal_t set[], int size, fosa_signal_t *signal_received,
+ fosa_signal_info_t *info, const fosa_rel_time_t *timeout);
+
+/*}*/
+
+FOSA_CPP_END_DECLS
+
+#endif /* !FOSA_THREAD_AND_SIGNALS_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_time.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+#ifndef FOSA_TIME_H_
+#define FOSA_TIME_H_
+
+#include "fosa_types.h"
+
+FOSA_CPP_BEGIN_DECLS
+
+/* Arithmetic, comparison and conversion functions are defined in
+ subincludes */
+
+#ifdef FOSA_TIME_NUMERIC
+
+#include "fosa_time_numeric.h"
+
+#endif
+
+#ifdef FOSA_TIME_TIMESPEC
+
+#include "fosa_time_timespec.h"
+
+#endif
+
+
+/**
+ * fosa_eat()
+ *
+ * Eat some time using system clock facilities
+ **/
+void fosa_eat(const fosa_rel_time_t *cpu_time);
+
+FOSA_CPP_END_DECLS
+
+#endif /* !FOSA_TIME_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_time_numeric.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+#ifndef FOSA_TIME_NUMERIC_H_
+#define FOSA_TIME_NUMERIC_H_
+
+#include "fosa_types.h"
+
+/***************************************/
+/* C O N V E R S I O N M A C R O S */
+/***************************************/
+
+#if FOSA_TIME_BASE == 9 /* nanoseconds */
+
+#define fosa_time_to_msec(time) (time) / 1000000
+#define msec_to_fosa_time(msec) (msec) * 1000000
+#define fosa_time_to_usec(time) (time) / 1000
+#define usec_to_fosa_time(usec) (usec) * 1000
+#define fosa_time_to_nsec(time) (time)
+#define nsec_to_fosa_time(nsec) (nsec)
+
+
+#define timespec_to_fosa_time(time_type, tspec) ((time_type) (tspec).tv_sec) * 1000000000 + (time_type) (tspec).tv_nsec
+
+#define fosa_time_to_timespec(tspec, time) \
+do { \
+ (tspec).tv_sec = (time) / 1000000000; \
+ (tspec).tv_nsec = (time) % 1000000000; \
+} while(0)
+
+#define fosa_time_to_double(time) (double) (time) * 1e-9;
+#define fosa_double_to_time(time_type, time) (time_type) (time * 1e9)
+
+#endif
+
+#if FOSA_TIME_BASE == 6 /* microseconds */
+
+#define fosa_time_to_msec(time) (time) / 1000
+#define msec_to_fosa_time(msec) (msec) * 1000
+#define fosa_time_to_usec(time) (time)
+#define usec_to_fosa_time(usec) (usec)
+#define fosa_time_to_nsec(time) (time) * 1000
+#define nsec_to_fosa_time(nsec) (nsec) / 1000
+
+#define timespec_to_fosa_time(time_type, tspec) ( (time_type) (tspec).tv_sec) * 1000000 + (time_type) (tspec).tv_nsec/1000
+
+#define fosa_time_to_timespec(tspec,time) \
+do { \
+ (tspec).tv_sec = (time) / 1000000; \
+ (tspec).tv_nsec = ( (time) % 1000000) * 1000; \
+} while(0)
+
+#define fosa_time_to_double(time) (double) (time) * 1e-6;
+#define fosa_double_to_time(time_type, time) (time_type) (time * 1e6)
+
+#endif
+
+#if FOSA_TIME_BASE == 3 /* miliseconds */
+
+#define fosa_time_to_msec(time) (time)
+#define msec_to_fosa_time(msec) (msec)
+#define fosa_time_to_usec(time) (time) * 1000
+#define usec_to_fosa_time(usec) (usec) / 1000
+#define fosa_time_to_nsec(time) (time) * 1000000
+#define nsec_to_fosa_time(nsec) (nsec) / 1000000
+
+#define timespec_to_fosa_time(time_type, tspec) ( (time_type) (tspec).tv_sec) * 1000 + (time_type) (tspec).tv_nsec/1000000
+
+#define fosa_time_to_timespec(tspec, time) \
+do { \
+ (tspec).tv_sec = (time) / 1000; \
+ (tspec).tv_nsec = ( (time) % 1000) * 1000000; \
+} while(0)
+
+#define fosa_time_to_double(time) (double) (time) * 1e-3;
+#define fosa_double_to_time(time_type, time) (time_type) (time) * 1e3
+
+
+#endif
+
+
+
+/* Arithmetic and comparison */
+/*****************************/
+static inline fosa_abs_time_t fosa_abs_time_incr(fosa_abs_time_t base, fosa_rel_time_t interval)
+{
+ fosa_abs_time_t result;
+
+ result = base + interval;
+
+ return result;
+}
+
+
+// ---------------------------------------------------------
+
+static inline fosa_abs_time_t fosa_abs_time_decr(fosa_abs_time_t base, fosa_rel_time_t interval)
+{
+ fosa_abs_time_t result;
+
+ result = base - interval;
+
+ return result;
+}
+
+
+
+// ---------------------------------------------------------
+
+static inline fosa_rel_time_t fosa_abs_time_extract_interval(fosa_abs_time_t past, fosa_abs_time_t future)
+{
+ fosa_rel_time_t result;
+
+ result = future - past;
+
+ return result;
+}
+
+
+// ---------------------------------------------------------
+
+static inline fosa_rel_time_t fosa_rel_time_add(fosa_rel_time_t relt1, fosa_rel_time_t relt2)
+{
+ fosa_rel_time_t result;
+
+ result = relt1 + relt2;
+
+ return result;
+}
+
+
+
+// ---------------------------------------------------------
+
+static inline fosa_rel_time_t fosa_rel_time_decr(fosa_rel_time_t total, fosa_rel_time_t part)
+{
+ fosa_rel_time_t result;
+
+ result = total - part;
+
+ return result;
+}
+
+// ---------------------------------------------------------
+
+
+static inline fosa_rel_time_t fosa_rel_time_times_integer(fosa_rel_time_t time, long multiplier)
+{
+ fosa_rel_time_t result;
+
+ result = time * multiplier;
+
+ return result;
+}
+
+
+// ---------------------------------------------------------
+
+static inline fosa_rel_time_t fosa_rel_time_divided_by_integer(fosa_rel_time_t time, long divider)
+{
+ return time / divider;
+}
+
+
+
+
+
+/* Comparison */
+/**************/
+static inline bool fosa_abs_time_smaller(fosa_abs_time_t abst1, fosa_abs_time_t abst2)
+{
+ bool result;
+
+ result = abst1 < abst2;
+
+ return result;
+}
+
+// -----------------------------------------------------------
+
+static inline bool fosa_rel_time_smaller(fosa_rel_time_t relt1, fosa_rel_time_t relt2)
+{
+ bool result;
+
+ result = relt1 < relt2;
+
+ return result;
+}
+
+
+// -----------------------------------------------------------
+
+static inline bool fosa_abs_time_smaller_or_equal(fosa_abs_time_t abst1, fosa_abs_time_t abst2)
+{
+ bool result;
+
+ result = abst1 <= abst2;
+
+ return result;
+}
+
+
+// -----------------------------------------------------------
+
+static inline bool fosa_rel_time_smaller_or_equal(fosa_rel_time_t relt1, fosa_rel_time_t relt2)
+{
+ bool result;
+
+ result = relt1 <= relt2;
+
+ return result;
+}
+
+
+// -----------------------------------------------------------
+
+static inline bool fosa_rel_time_equal(fosa_rel_time_t relt1, fosa_rel_time_t relt2)
+{
+ bool result;
+
+ result = relt1 == relt2;
+
+ return result;
+}
+
+
+// -----------------------------------------------------------
+
+static inline bool fosa_abs_time_equal(fosa_abs_time_t abst1, fosa_abs_time_t abst2)
+{
+ bool result;
+
+ result = abst1 == abst2;
+
+ return result;
+}
+
+// -----------------------------------------------------------
+
+static inline bool fosa_rel_time_is_null(fosa_rel_time_t relt)
+{
+ bool result;
+
+ result = relt == 0;
+
+ return result;
+}
+
+
+// -----------------------------------------------------------
+
+static inline bool fosa_abs_time_is_null(fosa_abs_time_t abst)
+{
+ bool result;
+
+ result = abst == 0;
+
+ return result;
+}
+
+
+
+/* Conversion */
+/**************/
+static inline fosa_rel_time_t fosa_msec_to_rel_time(long msec)
+{
+ fosa_rel_time_t result;
+
+ result = msec_to_fosa_time( (fosa_rel_time_t) msec );
+
+ return result;
+}
+
+// --------------------------------------------------
+
+static inline long fosa_rel_time_to_msec(fosa_rel_time_t relt)
+{
+ long result;
+
+ result = fosa_time_to_msec(relt);
+
+ return result;
+}
+
+
+// --------------------------------------------------
+
+
+static inline fosa_rel_time_t fosa_msec_to_abs_time(long msec)
+{
+ fosa_abs_time_t result;
+
+ result = msec_to_fosa_time( (fosa_abs_time_t) msec);
+
+ return result;
+}
+
+// --------------------------------------------------
+
+static inline long fosa_abs_time_to_msec(fosa_abs_time_t abst)
+{
+ long result;
+
+ result = fosa_time_to_msec(abst);
+
+ return result;
+}
+
+
+// --------------------------------------------------
+
+static inline fosa_rel_time_t fosa_usec_to_rel_time(long usec)
+{
+ fosa_rel_time_t result;
+
+ result = usec_to_fosa_time((fosa_rel_time_t ) usec);
+
+ return result;
+}
+
+// --------------------------------------------------
+
+static inline long fosa_rel_time_to_usec(fosa_rel_time_t relt)
+{
+ long result;
+
+ result = fosa_time_to_usec(relt);
+
+ return result;
+}
+
+
+// --------------------------------------------------
+
+static inline fosa_abs_time_t fosa_usec_to_abs_time(long usec)
+{
+ fosa_abs_time_t result;
+
+ result = usec_to_fosa_time( (fosa_abs_time_t) usec);
+
+ return result;
+}
+
+// --------------------------------------------------
+
+static inline long fosa_abs_time_to_usec(fosa_abs_time_t abst)
+{
+ long result;
+
+ result = fosa_time_to_usec(abst);
+
+ return result;
+}
+
+
+
+// --------------------------------------------------
+
+static inline fosa_rel_time_t fosa_nsec_to_rel_time(long nsec)
+{
+ fosa_rel_time_t result;
+
+ result = nsec_to_fosa_time((fosa_rel_time_t ) nsec);
+
+ return result;
+}
+
+// --------------------------------------------------
+
+static inline long fosa_rel_time_to_nsec(fosa_rel_time_t relt)
+{
+ long result;
+
+ result = fosa_time_to_nsec(relt);
+
+ return result;
+}
+
+
+// --------------------------------------------------
+
+static inline fosa_abs_time_t fosa_nsec_to_abs_time(long nsec)
+{
+ fosa_abs_time_t result;
+
+ result = nsec_to_fosa_time( (fosa_abs_time_t) nsec);
+
+ return result;
+}
+
+// --------------------------------------------------
+
+static inline long fosa_abs_time_to_nsec(fosa_abs_time_t abst)
+{
+ long result;
+
+ result = fosa_time_to_nsec(abst);
+
+ return result;
+}
+
+// --------------------------------------------------
+
+static inline fosa_rel_time_t fosa_timespec_to_rel_time(struct timespec time_tspec)
+{
+ fosa_rel_time_t result;
+
+ result = timespec_to_fosa_time(fosa_rel_time_t, time_tspec);
+
+ return result;
+}
+
+// --------------------------------------------------
+
+static inline struct timespec fosa_rel_time_to_timespec(fosa_rel_time_t relt)
+{
+ struct timespec result;
+
+ fosa_time_to_timespec(result, relt);
+
+ return result;
+}
+
+// --------------------------------------------------
+
+static inline fosa_abs_time_t fosa_timespec_to_abs_time(struct timespec time_tspec)
+{
+ fosa_abs_time_t result;
+
+ result = timespec_to_fosa_time(fosa_abs_time_t, time_tspec);
+
+ return result;
+}
+
+// --------------------------------------------------
+
+static inline struct timespec fosa_abs_time_to_timespec(fosa_abs_time_t abst)
+{
+ struct timespec result;
+
+ fosa_time_to_timespec(result, abst);
+
+ return result;
+}
+
+
+
+// --------------------------------------------------
+
+static inline double fosa_rel_time_to_double(fosa_rel_time_t relt)
+{
+ double result;
+
+ result = fosa_time_to_double(relt);
+ return result;
+}
+
+
+// --------------------------------------------------
+
+static inline double fosa_double_to_rel_time(double time)
+{
+ fosa_rel_time_t result;
+
+ result = fosa_double_to_time(fosa_rel_time_t, time);
+ return result;
+}
+
+
+
+
+#endif /* !FOSA_TIME_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_time_timespec.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+#ifndef FOSA_TIME_TIMESPEC_H_
+#define FOSA_TIME_TIMESPEC_H_
+
+#include <stdlib.h>
+#include <assert.h>
+
+/**********************************/
+/* T I M E S P E C M A C R O S */
+/**********************************/
+
+#define normalize_timespec(t1) \
+do \
+{ \
+ if ((t1).tv_nsec >= 1000000000) \
+ { \
+ (t1).tv_sec++; \
+ (t1).tv_nsec -= 1000000000; \
+ } \
+} while(0)
+
+#define add_timespec(sum, t1, t2) \
+do { \
+ (sum).tv_sec = (t1).tv_sec + (t2).tv_sec; \
+ (sum).tv_nsec = (t1).tv_nsec + (t2).tv_nsec; \
+ normalize_timespec(sum); \
+} while(0)
+
+#define incr_timespec(t1, t2) \
+do { \
+ (t1).tv_sec += (t2).tv_sec; \
+ (t1).tv_nsec += (t2).tv_nsec; \
+ normalize_timespec(t1); \
+} while(0)
+
+// -------------------------------------------------------------------
+
+/* TODO: Test that for past > future we obtain a correct negative
+ * interval */
+#define substract_timespec(diff, base, interval) \
+do { \
+ if ((base).tv_nsec < (interval).tv_nsec) \
+ { \
+ (diff).tv_sec = (base).tv_sec - (interval).tv_sec - 1; \
+ (diff).tv_nsec = (base).tv_nsec + 1000000000 - (interval).tv_nsec; \
+ } \
+ else \
+ { \
+ (diff).tv_sec = (base).tv_sec - (interval).tv_sec; \
+ (diff).tv_nsec = (base).tv_nsec - (interval).tv_nsec; \
+ } \
+} while(0)
+
+
+// ---------------------------------------------------------
+
+#define smaller_timespec(t1, t2) \
+ ((t1).tv_sec < (t2).tv_sec || ((t1).tv_sec == (t2).tv_sec && (t1).tv_nsec < (t2).tv_nsec) )
+
+// ---------------------------------------------------------
+
+#define smaller_or_equal_timespec(t1, t2) \
+ ((t1).tv_sec < (t2).tv_sec || ((t1).tv_sec == (t2).tv_sec && (t1).tv_nsec <= (t2).tv_nsec) )
+
+// ---------------------------------------------------------
+
+#define msec_to_timespec(tspec, msec) \
+do { \
+ if ((msec) >= 1000) { \
+ (tspec).tv_sec = (msec)/1000; \
+ (tspec).tv_nsec = ((msec) % 1000) * 1000000; \
+ } else { \
+ (tspec).tv_sec = 0; \
+ (tspec).tv_nsec = (msec) * 1000000; \
+ } \
+} while (0)
+
+// ---------------------------------------------------------
+
+#define timespec_to_msec(t1) \
+ ( ((t1).tv_sec % 2147482) * 1000 + (t1).tv_nsec/1000000 )
+
+
+// ---------------------------------------------------------
+
+#define usec_to_timespec(tspec, usec) \
+do { \
+ if ((usec) >= 1000000) { \
+ (tspec).tv_sec = (usec)/1000000; \
+ (tspec).tv_nsec = ((usec) % 1000000) * 1000; \
+ } else { \
+ (tspec).tv_sec = 0; \
+ (tspec).tv_nsec = (usec) * 1000; \
+ } \
+} while(0)
+
+// ---------------------------------------------------------
+
+#define timespec_to_usec(t1) \
+ ( ((t1).tv_sec % 2148) * 1000000 + (t1).tv_nsec/1000 )
+
+
+// ---------------------------------------------------------
+
+#define nsec_to_timespec(tspec, nsec) \
+do { \
+ if ((nsec) >= 1000000000) { \
+ (tspec).tv_sec = (nsec)/1000000000; \
+ (tspec).tv_nsec = (nsec) % 1000000000; \
+ } else { \
+ (tspec).tv_sec = 0; \
+ (tspec).tv_nsec = (nsec); \
+ } \
+} while(0)
+
+// ---------------------------------------------------------
+
+#define timespec_to_nsec(t1) \
+ ( ((t1).tv_sec % 2) * 1000000000 + (t1).tv_nsec )
+
+
+
+// ---------------------------------------------------------
+
+#define timespec_equal(t1, t2) ( (t1).tv_sec == (t2).tv_sec ) && ( (t1).tv_nsec == (t2).tv_nsec )
+
+#define timespec_is_null(t1) ( (t1).tv_sec == 0 ) && ( (t1).tv_nsec == 0 )
+
+
+
+/***************************************/
+/* T I M E S P E C F U N C T I O N S */
+/***************************************/
+
+
+static inline fosa_abs_time_t fosa_abs_time_incr(fosa_abs_time_t base, fosa_rel_time_t interval)
+{
+ fosa_abs_time_t result;
+
+ add_timespec(result, base, interval);
+
+ return result;
+}
+
+
+// ---------------------------------------------------------
+
+static inline fosa_abs_time_t fosa_abs_time_decr(fosa_abs_time_t base, fosa_rel_time_t interval)
+{
+ fosa_abs_time_t result;
+
+ substract_timespec(result, base, interval);
+
+ return result;
+}
+
+
+
+// ---------------------------------------------------------
+
+static inline fosa_rel_time_t fosa_abs_time_extract_interval(fosa_abs_time_t past, fosa_abs_time_t future)
+{
+ fosa_rel_time_t result;
+
+ substract_timespec(result, future, past);
+
+ return result;
+}
+
+
+// ---------------------------------------------------------
+
+static inline fosa_rel_time_t fosa_rel_time_add(fosa_rel_time_t relt1, fosa_rel_time_t relt2)
+{
+ fosa_rel_time_t result;
+
+ add_timespec(result, relt1, relt2);
+
+ return result;
+}
+
+
+// ---------------------------------------------------------
+
+static inline fosa_rel_time_t fosa_rel_time_decr(fosa_rel_time_t total, fosa_rel_time_t part)
+{
+ fosa_rel_time_t result;
+
+ substract_timespec(result, total, part);
+
+ return result;
+}
+
+// ---------------------------------------------------------
+
+/**
+ * exact_long_multiply_smaller_10e5()
+ *
+ * Same as below but with operands smaller than 10000 which allows
+ * to perform all component multiplications without an overflow risk.
+ **/
+static inline struct timespec exact_long_multiply_smaller_10e5(long t, long k)
+{
+ /* Since operands are smaller than 10e5 we can use 1000 */
+ /* the base without risking to cause overflows in the */
+ /* operations. */
+ /********************************************************/
+ assert(t < 10000);
+ assert(k < 10000);
+
+ struct timespec result;
+
+ long base = 1000;
+
+ long t_high = t / base;
+ long t_low = t % base;
+ long k_high = k / base;
+ long k_low = k % base;
+
+ long thkh = t_high * k_high;
+ long thkl = t_high * k_low;
+ long tlkh = t_low * k_high;
+ long tlkl = t_low * k_low;
+
+ long thkl_high = thkl / base;
+ long tlkh_high = tlkh / base;
+ long thkl_low = thkl % base;
+ long tlkh_low = tlkh % base;
+
+ long c2 = thkh + thkl_high + tlkh_high; // Normalized at 10^6
+ long c1 = thkl_low + tlkh_low; // Normalized at 10^3
+ long c0 = tlkl;
+
+ result.tv_sec = c2/1000 + c1/1000000;
+ result.tv_nsec = (c2 % 1000) * 1000000 + (c1 % 1000000) * 1000 + c0;
+
+ result.tv_sec += (result.tv_nsec / 1000000000);
+ result.tv_nsec %= 1000000000;
+
+ return result;
+}
+
+
+// -------------------------------------------------------------
+
+
+
+/**
+ * exact_long_multiply()
+ *
+ * This function performs an exact long * long operations on operands
+ * lower than 1e9 without using more than 32bit (1e9) arithmetic.
+ *
+ * To achieve this we decompose the operands in high and low:
+ *
+ * num = (num/base) * base + (num % base)
+ * ^^^^^^^^ ^^^^^^^^^^^^
+ * high component low component
+ *
+ * t * k = (th*kh + th*kl/base + tl*kh/base )*base^2
+ * + (th*kl % base)*base + (tl*kh % base) * base + tl*kl
+ *
+ * The problem is that we cannot use an exact base because sqrt(1e9)
+ * is not a multiple of 1e9 (in fact it is not even integer).
+ *
+ * So we use as a base 100000 which means that the last term tl*kl may
+ * need another exact calculation with a lower base (100)
+ **/
+static inline struct timespec exact_long_multiply(long t, long k)
+{
+ struct timespec result;
+
+ long t_high;
+ long t_low;
+ long k_high;
+ long k_low;
+
+ long base = 100000; /* Power of 10 closest to sqrt(1e9) from
+ * above */
+
+ t_high = t / base;
+ t_low = t % base; // Between 0 99999
+ k_high = k / base;
+ k_low = k % base; // Between 0 99999
+
+ /* These numbers are always lower than 1e9 */
+ long thkh = t_high * k_high;
+ long thkl = t_high * k_low;
+ long tlkh = t_low * k_high;
+
+ long thkl_high = thkl / base;
+ long thkl_low = thkl % base;
+ long tlkh_high = tlkh / base;
+ long tlkh_low = tlkh % base;
+
+ /* We can calculate the base^2 term (note however that this is 10
+ * times the tv_sec component because it is multiplied by 10^10 */
+ long c2 = thkh + thkl_high + tlkh_high; // scaled to 10^10
+ long c1 = thkl_low + tlkh_low; // scaled to 10^5
+
+ struct timespec c0;
+
+ /* Now we can write the initial values of result */
+ result.tv_sec = c2*10 + c1/10000;
+ result.tv_nsec = (c1 % 10000) * 100000;
+
+ normalize_timespec(result);
+
+ /* To calculate c0 we must check if there is a risk of overflow */
+ /* Remember operands cannot be larger than 99999 and result */
+ /* larger than 1e9. */
+ /****************************************************************/
+ bool overflow_risk;
+ overflow_risk = false;
+
+ if (
+ ( (t_low > 31622) && (k_low >= 10000) ) ||
+ ( (k_low > 31622) && (t_low >= 10000) )
+ )
+ {
+ overflow_risk = true;
+ }
+
+ if (! overflow_risk)
+ {
+ c0.tv_sec = 0;
+ c0.tv_nsec = t_low * k_low;
+ normalize_timespec(c0);
+ }
+ else
+ {
+ c0 = exact_long_multiply_smaller_10e5(t_low, k_low);
+ }
+ add_timespec(result, result, c0);
+
+ return result;
+}
+
+// -------------------------------------------------------------
+
+
+static inline fosa_rel_time_t fosa_rel_time_times_integer(fosa_rel_time_t time, long multiplier)
+{
+ struct timespec result;
+ struct timespec intermediate;
+
+ result.tv_sec = time.tv_sec * multiplier; // No overflow check here
+ result.tv_nsec = 0;
+
+ intermediate = exact_long_multiply(time.tv_nsec, multiplier);
+
+ add_timespec(result, result, intermediate);
+
+ return result;
+}
+
+// ---------------------------------------------------------
+
+static inline fosa_rel_time_t fosa_rel_time_divided_by_integer(fosa_rel_time_t time, long divider)
+{
+ struct timespec result;
+ long reminder;
+
+
+ result.tv_sec = time.tv_sec / divider;
+ result.tv_nsec = 0;
+
+ /* We iterate until the reminder is lower than 2 (to later fit in
+ * a 32 bit signed integer multiplied by 1e9 */
+
+ reminder = time.tv_sec % divider;
+
+
+ if (reminder == 0)
+ {
+ /* We are lucky no reminder so no need to transfer it to the
+ nsec scale.
+ */
+ result.tv_nsec = time.tv_nsec/divider;
+ return result;
+ }
+
+ long enhacer;
+ long back_enhacer;
+ long next_dividend;
+ int next_numeral; /* Between 0 and 9 */
+ enhacer = 1;
+ do
+ {
+ enhacer *= 10;
+ back_enhacer = 1000000000 / enhacer;
+ next_numeral = (time.tv_nsec / back_enhacer) % 10;
+
+ // Note: a possible overflow may happen here with large denominators
+ if (reminder > 200000000)
+ {
+ /* An overflow is going to be produced */
+ abort();
+ }
+ next_dividend = reminder * 10 + next_numeral;
+
+ result.tv_nsec += (next_dividend / divider) * back_enhacer;
+ reminder = next_dividend % divider;
+ } while (back_enhacer > 1);
+
+
+ return result;
+}
+
+// ---------------------------------------------------------
+
+
+/* Comparison */
+/**************/
+static inline bool fosa_abs_time_smaller(fosa_abs_time_t abst1, fosa_abs_time_t abst2)
+{
+ bool result;
+
+ result = smaller_timespec(abst1, abst2);
+
+ return result;
+}
+
+// -----------------------------------------------------------
+
+static inline bool fosa_rel_time_smaller(fosa_rel_time_t relt1, fosa_rel_time_t relt2)
+{
+ bool result;
+
+ result = smaller_timespec(relt1, relt2);
+
+ return result;
+}
+
+
+// -----------------------------------------------------------
+
+static inline bool fosa_abs_time_smaller_or_equal(fosa_abs_time_t abst1, fosa_abs_time_t abst2)
+{
+ bool result;
+
+ result = smaller_or_equal_timespec(abst1, abst2);
+
+ return result;
+}
+
+
+// -----------------------------------------------------------
+
+static inline bool fosa_rel_time_smaller_or_equal(fosa_rel_time_t relt1, fosa_rel_time_t relt2)
+{
+ bool result;
+
+ result = smaller_or_equal_timespec(relt1, relt2);
+
+ return result;
+}
+
+
+// -----------------------------------------------------------
+
+static inline bool fosa_rel_time_equal(fosa_rel_time_t relt1, fosa_rel_time_t relt2)
+{
+ bool result;
+
+ result = timespec_equal(relt1, relt2);
+
+ return result;
+}
+
+
+// -----------------------------------------------------------
+
+static inline bool fosa_abs_time_equal(fosa_abs_time_t abst1, fosa_abs_time_t abst2)
+{
+ bool result;
+
+ result = timespec_equal(abst1, abst2);
+
+ return result;
+}
+
+// -----------------------------------------------------------
+
+static inline bool fosa_rel_time_is_null(fosa_rel_time_t relt)
+{
+ bool result;
+
+ result = timespec_is_null(relt);
+
+ return result;
+}
+
+
+// -----------------------------------------------------------
+
+static inline bool fosa_abs_time_is_null(fosa_abs_time_t abst)
+{
+ bool result;
+
+ result = timespec_is_null(abst);
+
+ return result;
+}
+
+
+
+
+/* Conversion */
+/**************/
+static inline fosa_rel_time_t fosa_msec_to_rel_time(long msec)
+{
+ fosa_rel_time_t result;
+
+ msec_to_timespec(result, msec);
+
+ return result;
+
+
+}
+
+// --------------------------------------------------
+
+static inline long fosa_rel_time_to_msec(fosa_rel_time_t relt)
+{
+ long result;
+
+ result = timespec_to_msec(relt);
+
+ return result;
+}
+
+
+// --------------------------------------------------
+
+
+static inline fosa_rel_time_t fosa_msec_to_abs_time(long msec)
+{
+ fosa_abs_time_t result;
+
+ msec_to_timespec(result, msec);
+
+ return result;
+}
+
+// --------------------------------------------------
+
+static inline long fosa_abs_time_to_msec(fosa_abs_time_t abst)
+{
+ long result;
+
+ result = timespec_to_msec(abst);
+
+ return result;
+}
+
+
+// --------------------------------------------------
+
+static inline fosa_rel_time_t fosa_usec_to_rel_time(long usec)
+{
+ fosa_rel_time_t result;
+
+ usec_to_timespec(result, usec);
+
+ return result;
+}
+
+// --------------------------------------------------
+
+static inline long fosa_rel_time_to_usec(fosa_rel_time_t relt)
+{
+ long result;
+
+ result = timespec_to_usec(relt);
+
+ return result;
+}
+
+
+// --------------------------------------------------
+
+static inline fosa_abs_time_t fosa_usec_to_abs_time(long usec)
+{
+ fosa_abs_time_t result;
+
+ usec_to_timespec(result, usec);
+
+ return result;
+}
+
+// --------------------------------------------------
+
+static inline long fosa_abs_time_to_usec(fosa_abs_time_t abst)
+{
+ long result;
+
+ result = timespec_to_usec(abst);
+
+ return result;
+}
+
+// --------------------------------------------------
+
+static inline fosa_rel_time_t fosa_nsec_to_rel_time(long nsec)
+{
+ fosa_rel_time_t result;
+
+ nsec_to_timespec(result, nsec);
+
+ return result;
+}
+
+// --------------------------------------------------
+
+static inline long fosa_rel_time_to_nsec(fosa_rel_time_t relt)
+{
+ long result;
+
+ result = timespec_to_nsec(relt);
+
+ return result;
+}
+
+
+// --------------------------------------------------
+
+static inline fosa_abs_time_t fosa_nsec_to_abs_time(long nsec)
+{
+ fosa_abs_time_t result;
+
+ nsec_to_timespec(result, nsec);
+
+ return result;
+}
+
+// --------------------------------------------------
+
+static inline long fosa_abs_time_to_nsec(fosa_abs_time_t abst)
+{
+ long result;
+
+ result = timespec_to_nsec(abst);
+
+ return result;
+}
+
+
+// --------------------------------------------------
+
+static inline fosa_rel_time_t fosa_timespec_to_rel_time(struct timespec time_tspec)
+{
+ return (fosa_rel_time_t) time_tspec;
+}
+
+// --------------------------------------------------
+
+static inline struct timespec fosa_rel_time_to_timespec(fosa_rel_time_t relt)
+{
+ return (struct timespec) relt;
+}
+
+// --------------------------------------------------
+
+static inline fosa_abs_time_t fosa_timespec_to_abs_time(struct timespec time_tspec)
+{
+ return (fosa_abs_time_t) time_tspec;
+}
+
+// --------------------------------------------------
+
+static inline struct timespec fosa_abs_time_to_timespec(fosa_abs_time_t abst)
+{
+ return (struct timespec) abst;
+}
+
+// --------------------------------------------------
+
+static inline double fosa_rel_time_to_double(fosa_rel_time_t relt)
+{
+ double result;
+
+ result = relt.tv_nsec*0.000000001 + (double)relt.tv_sec;
+
+ return result;
+}
+
+// --------------------------------------------------
+
+static inline fosa_rel_time_t fosa_double_to_rel_time(double time)
+{
+ fosa_rel_time_t result;
+
+ result.tv_sec = (long) time;
+ result.tv_nsec = (long) ( (time - (double)result.tv_sec) * 1e9 );
+
+ return result;
+}
+
+#endif /* !FOSA_TIME_TIMESPEC_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_types.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+
+#ifndef _FOSA_TYPES_H_
+#define _FOSA_TYPES_H_
+
+#include "fosa_opaque_types.h"
+
+FOSA_CPP_BEGIN_DECLS
+
+/**
+ * @addtogroup threadandsignals
+ *
+ * @{
+ **/
+
+/* Coming from FRSH-FOSA */
+
+/** identifier of a FOSA thread **/
+typedef FOSA_THREAD_ID_T_OPAQUE fosa_thread_id_t;
+
+
+/** thread attributes object **/
+typedef FOSA_THREAD_ATTR_T_OPAQUE fosa_thread_attr_t;
+
+typedef FOSA_SIGNAL_T_OPAQUE fosa_signal_t;
+
+/**
+ * The type references a function that may become a thread's
+ * code
+ **/
+typedef void * (*fosa_thread_code_t) (void *);
+
+
+/** information associated to a signal **/
+#if defined(VIRTUAL_TIME)
+
+#include <vt_ose.h>
+typedef vt_posix_signal_info_t fosa_signal_info_t;
+
+#else
+
+typedef union {int sival_int; void * sival_ptr; } fosa_signal_info_t;
+/* typedef FOSA_SIGNAL_INFO_T_OPAQUE fosa_signal_info_t; */
+
+#endif
+
+/* @} */
+
+
+/**
+ * @addtogroup clocksandtimers
+ *
+ * @{
+ **/
+// identifier of a clock
+// either a real-time clock or a cpu-time clock
+
+typedef FOSA_REL_TIME_T_OPAQUE fosa_rel_time_t;
+typedef FOSA_ABS_TIME_T_OPAQUE fosa_abs_time_t;
+
+typedef FOSA_CLOCK_ID_T_OPAQUE fosa_clock_id_t;
+
+#define FOSA_SYSTEM_CLOCK FOSA_SYSTEM_CLOCK_OPAQUE
+
+// identifier of a one-shot timer
+typedef FOSA_TIMER_ID_T_OPAQUE fosa_timer_id_t;
+
+/*@}*/
+
+/**
+ * @addtrogroup mutexesandcondvars
+ *
+ * @{
+ **/
+// a condition variable
+/** Mutex object. Attributes are handled by FOSA **/
+typedef FOSA_MUTEX_T_OPAQUE fosa_mutex_t;
+
+typedef FOSA_COND_T_OPAQUE fosa_cond_t;
+/*@}*/
+
+/**
+ * @addtogroup appdefsched
+ *
+ * @{
+ **/
+
+/*********
+ * ADS
+ *********/
+
+/**
+ * ADS actions
+ *
+ * This type is used to represent a list of scheduling actions that the
+ * scheduler will later request to be executed by the system. The pos-
+ * sible actions are of the following kinds:
+ * - reject a thread that has requested attachment to this scheduler
+ * - activate an application-scheduled thread with the desired value
+ * of urgency
+ * - suspend an application-scheduled thread
+ * - program a timeout
+ * - program a timed notification associated to a particular
+ * application-scheduled thread.
+ *
+ * No comparison or assignment operators are defined for this type
+ **/
+typedef FOSA_ADS_ACTIONS_T_OPAQUE fosa_ads_actions_t;
+
+/* FOSA_ADS_ACTIONS_T_OPAQUE */
+
+/**
+ * Causes of error in the appsched_error primitive operation
+ **/
+typedef enum {FOSA_ADS_THREAD_NOT_ATTACHED, FOSA_ADS_INVALID_ACTION}
+ fosa_ads_error_cause_t;
+
+
+/**
+ * The urgency used to orde the threads of the same priority in the
+ * underlying scheduler. Support for urgency scheduling is required
+ * for supporting the hierarchhical scheduling module
+ **/
+typedef int fosa_ads_urgency_t;
+
+
+/**
+ * Scheduler primitive operations
+ *
+ * This structure is used to create application schedulers. It
+ * contains pointers to the primitive operations that are invoked by
+ * the system when a scheduling event occurs:
+ *
+ * - The \b init() primitive operation is invoked by the system just after
+ * the scheduler has been created using fosa_ads_scheduler_create().
+ *
+ * - The \b new_thread() primitive operation is invoked by the system when
+ * a thread has requested attachment to this scheduler; this can be a
+ * newly created thread (via fosa_thread_create()), or an existing thread
+ * that was not running under ads scheduler (via
+ * fosa_ads_set_appscheduled()).\n \n
+ * .
+ * The thread can be rejected by the scheduler adding a
+ * reject-thread action to the actions parameter using
+ * fosa_ads_actions_add_reject(). If no reject-thread action is
+ * added, the thread is accepted.\n \n
+ * .
+ * Newly created threads shall be activated by the system after the
+ * execution of the new_thread() primitive operation. The urgency of
+ * an accepted thread (either newly created or existing) shall be set
+ * to a value of zero, unless an activate-thread action with a
+ * different value of urgency is added via
+ * fosa_ads_actions_add_activate().\n \n
+ * .
+ * If a request to attach a thread to this scheduler was made via
+ * fosa_ads_set_appscheduled(), at the finalization of the new_thread()
+ * primitive operation if the newly attached thread is blocked by the
+ * system (not by the scheduler itself via a suspend scheduling
+ * action), a thread-block event shall be generated for the scheduler
+ * immediately and, consequently, the thread_block() primitive
+ * operation shall be invoked by the system.
+ *
+ * - The \b thread_terminate() primitive operation is invoked by the system
+ * when a thread attached to this scheduler is terminating (via an
+ * explicit or implicit thread termination, or cancellation, or when
+ * it is no longer sceduled by the ads scheduler (via
+ * fosa_ads_setappscheduled()). \n\n
+ * .
+ * Before the thread_terminate() primitive operation is invoked by
+ * the system, all the thread-notification events programmed for that
+ * thread are cancelled. \n\n
+ * .
+ * In the case of a thread that is terminating, the
+ * thread_terminate() primitive operation is executed before the
+ * execution of the cleanup handlers and of the thread-specific data
+ * destructor functions. In that way, the thread parameter corresponds
+ * to a valid thread Id and the thread-specific data is valid and can
+ * be accessed from the thread_terminate() primitive operation. \n\n
+ * .
+ * Also for terminating threads, after the thread_terminate() primitive
+ * operation finishes, the system shall lower the urgency of the
+ * thread identified by thread to a value of zero, and shall deattach
+ * it from the ads scheduler. Then, the thread shall execute the
+ * cleanup handlers and the thread-specific data destructor functions
+ * outside the management of its former scheduler. Notice that in a
+ * multiprocessor system this may imply the suspension of the thread
+ * identified by parameter thread during the execution of the
+ * thread_terminate() primitive operation.
+ *
+ * - The \b thread_ready() primitive operation is invoked by the system
+ * when a thread attached to this scheduler that was blocked has
+ * become unblocked by the system.
+ *
+ * - The \b thread_block() primitive operation is invoked by the system
+ * when a thread attached to this scheduler has blocked.
+ *
+ * - The \b change_sched_param_thread() primitive operation is invoked
+ * by the system when the scheduling parameters of a thread attached
+ * to this scheduler have been changed OUTSIDE OF AN SCHEDULER
+ * CALLBACK, and the thread continues to run under this scheduler.
+ * .
+ * The change includes either the regular scheduling parameters
+ * (fosa_thread_set_prio() or the application-defined scheduling
+ * parameters, via fosa_ads_set_appsched_param().
+ *
+ * - The \b explicit_call_with_data() primitive operation is invoked by the
+ * system when a thread (identified by the thread parameter) has
+ * explicitly invoked the scheduler with a message containing
+ * scheduling information, and possibly requesting a reply message,
+ * via fosa_ads_invoke_withdata().
+ *
+ * - The \b notification_for_thread() primitive operation is invoked by the
+ * system when the time for a thread-notification previously programed
+ * by the scheduler via fosa_ads_actions_add_thread_notification()
+ * is reached. Parameter clock identifies the clock for which the
+ * thread-notification was programmed.
+ *
+ * - The \b timeout() primitive operation is invoked by the system when a
+ * timeout requested by the scheduler (via
+ * fosa_ads_actions_add_timeout()) has expired.
+ *
+ * - The \b signal() primitive operation is invoked by the system when a
+ * signal belonging to the set of signals for which the scheduler is
+ * waiting (via fosa_ads_set_handled_signal_set()) has been
+ * generated. \n\n
+ * .
+ * The signal number and its associated information (if any) are
+ * passed in the arguments signal and siginfo.\n\n
+ * .
+ * The signal is consumed with the invocation of this primitive
+ * operation, which implies that it will not cause the execution of
+ * any signal handler, nor it may be accepted by any thread waiting
+ * for this signal number.
+ *
+ * - The \b appsched_error() primitive operation is invoked by the system
+ * when an error in the scheduling actions list specified in a
+ * previous primitive operation is detected. The cause of the error is
+ * notified in the parameter cause. The defined causes of error are
+ * described fosa_ads_error_cause_t
+ *
+ * Every primitive operation receives the argument sched_data. It is a
+ * pointer to a memory area containing information shared by all the
+ * scheduler operations. It can be used to store the data structures
+ * required by the scheduler (for example, a ready queue and a delay
+ * queue). Scheduler operations should not use any other global data out
+ * of this memory area.
+ *
+ * The actions argument is used by the scheduler to request the operating
+ * system to execute a set of scheduling actions at the end of the
+ * primitive operation. It is passed empty by the system, and the
+ * scheduler may add multiple scheduling actions.
+ *
+ * The current_time argument contains the system time
+ * measured immediately before the invocation of the primitive operation
+ * using the FOSA_CLOCK_REALTIME clock
+ *
+ * In addition to these common parameters, most of the primitive
+ * operations receive a thread argument. This argument allows the
+ * primitive operations to know which is the thread that has produced or
+ * is related to the event.
+ **/
+typedef struct {
+ void (*init) (void * sched_data, void * arg);
+ void (*new_thread) (void * sched_data,
+ fosa_thread_id_t thread,
+ fosa_ads_actions_t * actions,
+ fosa_abs_time_t *current_time);
+ void (*thread_terminate) (void * sched_data,
+ fosa_thread_id_t thread,
+ fosa_ads_actions_t * actions,
+ fosa_abs_time_t *current_time);
+ void (*thread_ready) (void * sched_data,
+ fosa_thread_id_t thread,
+ fosa_ads_actions_t * actions,
+ fosa_abs_time_t *current_time);
+ void (*thread_block) (void * sched_data,
+ fosa_thread_id_t thread,
+ fosa_ads_actions_t * actions,
+ fosa_abs_time_t *current_time);
+ //void (*thread_yield) (void * sched_data,
+ // fosa_thread_id_t thread,
+ // fosa_ads_actions_t * actions,
+ // fosa_abs_time_t *current_time);
+ void (*change_sched_param_thread) (void * sched_data,
+ fosa_thread_id_t thread,
+ fosa_ads_actions_t * actions,
+ fosa_abs_time_t *current_time);
+ //void msg_from_scheduler(void * sched_data,
+ // fosa_ads_scheduler_id_t scheduler_id,
+ // const void * msg, size_t msg_size,
+ // fosa_ads_actions_t * actions,
+ // fosa_bas_time_t *current_time);
+ //void (*explicit_call) (void * sched_data,
+ // fosa_thread_id_t thread,
+ // int user_event_code,
+ // fosa_ads_actions_t * actions,
+ // fosa_abs_time_t *current_time);
+ void (*explicit_call_with_data) (void * sched_data,
+ fosa_thread_id_t thread,
+ const void * msg, size_t msg_size,
+ void *reply, size_t *reply_size,
+ fosa_ads_actions_t * actions,
+ fosa_abs_time_t *current_time);
+ void (*notification_for_thread) (void * sched_data,
+ fosa_thread_id_t thread,
+ fosa_clock_id_t clock,
+ fosa_ads_actions_t * actions,
+ fosa_abs_time_t *current_time);
+ void (*timeout) (void * sched_data,
+ fosa_ads_actions_t * actions,
+ fosa_abs_time_t *current_time);
+ void (*signal) (void * sched_data,
+ fosa_signal_t signal,
+ fosa_signal_info_t siginfo,
+ fosa_ads_actions_t * actions,
+ fosa_abs_time_t *current_time);
+ //void (*priority_inherit) (void * sched_data,
+ // fosa_thread_id_t thread,
+ // int sched_priority,
+ // fosa_ads_actions_t * actions,
+ // fosa_abs_time_t *current_time);
+ //void (*priority_uninherit) (void * sched_data,
+ // fosa_thread_id_t thread,
+ // int sched_priority,
+ // fosa_ads_actions_t * actions,
+ // fosa_abs_time_t *current_time);
+ void (*appsched_error) (void * sched_data,
+ fosa_thread_id_t thread,
+ fosa_ads_error_cause_t cause,
+ fosa_ads_actions_t * actions);
+} fosa_ads_scheduler_ops_t;
+
+
+/*@}*/
+
+/*********************
+ * LONG JUMPS
+ *********************/
+
+/**
+ * The fosa_jump_context_t type defines a data area where the context
+ * of a thread can be saved, so that a long jump to recover that context
+ * may be executed in the future, from a long jump handler.
+ */
+
+typedef FOSA_LONG_JUMP_CONTEXT_T_OPAQUE fosa_long_jump_context_t;
+
+
+/*********************
+ * GROUP CLOCKS
+ *********************/
+/**
+ * @addtogroup threadgroups
+ *
+ * @{
+ **/
+typedef FOSA_THREAD_SET_ID_T_OPAQUE fosa_thread_set_id_t;
+
+#define FOSA_NULL_THREAD_SET_ID FOSA_NULL_THREAD_SET_ID_OPAQUE
+
+/*@}*/
+
+FOSA_CPP_END_DECLS
+
+
+#endif // _FOSA_TYPES_H_
--- /dev/null
+ifeq ($(PLATFORM), MARTE_OS)
+ CC = mgcc
+ LD = mld
+else
+ CC = gcc
+ LD = ld
+endif
+
+LOWCASE_PLATFORM := $(shell echo $(PLATFORM) | tr "A-Z" "a-z")
+
+CFLAGS += -D$(PLATFORM) \
+ -I$(FOSA_PATH)/include -fno-strict-aliasing
+
+# This prevents mgcc from removing the debug information (stripping)
+LDFLAGS += -g
+
+# PaRTiKle uses its own compiler script
+ifeq ($(PLATFORM), PARTIKLE)
+ CC = pgcc
+ LD = ldkernel
+endif
+
+
+
+none:
+ @exec echo -e "\nPlease introduce a target, i.e: 'make test'";
+
+%.exe: %.c $(FOSA_PATH)/lib/libfosa_$(PLATFORM).a
+ @exec echo -e "\n>> Building $@: ";
+ $(CC) -c $(CFLAGS) $<
+ $(CC) $(LDFLAGS) -L$(FOSA_PATH)/lib $(patsubst %.c,%.o,$<) -lfosa_$(PLATFORM) -lm -o $@
+ @exec echo ">> [OK]";
+
+%.o: %.c $(LIBFOSA_SRCS) $(LIBFOSA_HDRS)
+ $(CC) $(CFLAGS) -c $<
+
+ifeq ($(PLATFORM), AQuoSA)
+libfosa: $(FOSA_PATH)/lib/libfosa_$(PLATFORM).a $(FOSA_PATH)/lib/libfosa_$(PLATFORM).so
+else
+libfosa: $(FOSA_PATH)/lib/libfosa_$(PLATFORM).a
+endif
+
+$(FOSA_PATH)/lib/libfosa_$(PLATFORM).a:
+ @exec echo -e "\n>> Compiling FOSA library (lib/libfosa_$(PLATFORM).a):";
+ @make -C $(FOSA_PATH)/src_$(LOWCASE_PLATFORM) all # Should be src_$(PLATFORM)
+ ar -rc libfosa_$(PLATFORM).a $(FOSA_PATH)/src_$(LOWCASE_PLATFORM)/*.o
+ @mv libfosa_$(PLATFORM).a $(FOSA_PATH)/lib/
+ @exec echo ">> [OK]"
+
+ifeq ($(PLATFORM), AQuoSA)
+$(FOSA_PATH)/lib/libfosa_$(PLATFORM).so:
+ @exec echo -e "\n>> Compiling FOSA library (lib/libfosa_$(PLATFORM).so):";
+ @make -C $(FOSA_PATH)/src_$(LOWCASE_PLATFORM) all # Should be src_$(PLATFORM)
+ $(CC) -shared -o $@ $(FOSA_PATH)/src_$(LOWCASE_PLATFORM)/*.o
+ @exec echo ">> [OK]"
+endif
+
+clean:
+ @exec echo -e "\n>> Cleaning... ";
+ @find \( -name '*.[oa]' -or -name '*~*' -or -name 'libfosa.a' \
+ -or -name '*.ali' -or -name 'b~*' \
+ -or -name '*.so' \
+ -or -name '*.exe' -or -name 'mprogram' -or -name 'a.out' \) -print -delete
+ @exec echo ">> [OK]"
+
+.PHONY: none libfosa clean all
--- /dev/null
+all: objs
+
+include ../config.mk
+include ../rules.mk
+
+CFLAGS += -fPIC -I$(FOSA_PATH)/src_aquosa
+
+SRCS := $(wildcard *.c)
+OBJS := $(patsubst %.c,%.o,$(wildcard *.c))
+LIBFOSA_SRCS := $(wildcard *.c)
+LIBFOSA_HDRS := $(wildcard $(FOSA_PATH)/include/*.h) $(wildcard *.h)
+
+objs: $(OBJS)
+
+%.o: %.c $(LIBFOSA_SRCS) $(LIBFOSA_HDRS)
+ $(CC) $(CFLAGS) -c $<
--- /dev/null
+SUBDIRS = $(ALL_OMK_SUBDIRS)
+
+lib_LIBRARIES=fosa
+shared_LIBRARIES=fosa
+fosa_SOURCES=$(notdir $(wildcard $(SOURCES_DIR)/*.c))
+
+default_CONFIG = CONFIG_NO_PRIO_INHERIT=n
+LOCAL_CONFIG_H = fosa_config.h
\ No newline at end of file
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_app_def_sched.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+#include "fosa.h"
+
+
+/***************************************************************
+ * Application-defined scheduling not implemented in POSIX/Linux
+ **************************************************************/
+
+/**
+ * fosa_ads_scheduler_create()
+ *
+ * Create the application defined scheduler
+ *
+ * The application defined scheduler is created with the primitive
+ * operations specified in the object pointed to by scheduler_ops.
+ *
+ * The clock used to read the time immediately before the invocation
+ * of each primitive operation, to be reported to the scheduler via
+ * the current_time parameter of each primitive operation is the
+ * FOSA_CLOCK_REALTIME clock.
+ *
+ * The scheduler_data_size parameter is used to request that a memory
+ * area of this size must be created and reserved for the scheduler to
+ * store its state. A pointer to this area is passed to the scheduler
+ * operations in the sched_data parameter.
+ *
+ * Parameter init_arg points to an area that contains configuration
+ * information for the scheduler. The function creates a memory area
+ * of init_arg_size bytes and copies into it the area pointed by
+ * arg. A pointer to this new created area will be passed to the
+ * primitive operation init() in its arg parameter.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of scheduler_ops was invalid
+ * EAGAIN: The system lacks enough resources to create the scheduler
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ *
+ * The fosa_ads_scheduler_create function must be called before any
+ * other function in this header file
+ **/
+int fosa_ads_scheduler_create(const fosa_ads_scheduler_ops_t * scheduler_ops,
+ size_t scheduler_data_size, void * init_args,
+ size_t init_args_size)
+{
+ return FOSA_EINVAL;
+}
+
+/**
+ * fosa_thread_attr_set_appscheduled()
+ *
+ * Set the appscheduled attribute of a thread attributes object
+ *
+ * This function is used to set the appscheduled attribute in the
+ * object pointed to by attr. This attribute controls the kind of
+ * scheduling used for threads created with it. If true, the thread is
+ * scheduled by the application scheduler. If not, it is scheduled by
+ * the system under a fixed priority scheduler
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of attr is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_set_appscheduled(fosa_thread_attr_t *attr,
+ bool appscheduled)
+{
+ return FOSA_EINVAL;
+}
+
+/**
+ * fosa_thread_attr_get_appscheduled()
+ *
+ * Get the appscheduled attribute of a thread attributes object
+ *
+ * This function is used to get the appscheduled attribute in the
+ * object pointed to by attr. This attribute controls the kind of
+ * scheduling used for threads created with it. If true, the thread is
+ * scheduled by the application scheduler. If not, it is scheduled by
+ * the system under a fixed priority scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of attr is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_get_appscheduled(const fosa_thread_attr_t *attr,
+ bool *appscheduled)
+{
+ return FOSA_EINVAL;
+}
+
+/**
+ * fosa_thread_attr_set_appsched_params()
+ *
+ * Set the appsched_param attribute of a thread attributes object
+ *
+ * This function is used to set the appsched_param attribute in the
+ * object pointed to by attr. For those threads with appscheduled set
+ * to true, this attribute represents the application-specific
+ * scheduling parameters. If successful, the function shall set the
+ * size of the appsched_param attribute to the value specified by
+ * paramsize, and shall copy the scheduling parameters occupying
+ * paramsize bytes and pointed to by param into that attribute
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of attr is invalid, or paramsize is less than
+ * zero or larger than FOSA_ADS_SCHEDPARAM_MAX
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_set_appsched_params(fosa_thread_attr_t *attr,
+ const void *param,
+ size_t paramsize)
+{
+ return FOSA_EINVAL;
+}
+
+/**
+ * fosa_thread_attr_get_appsched_params()
+ *
+ * Get the appsched_param attribute of a thread attributes object
+ *
+ * This function is used to get the appsched_param attribute from the
+ * object pointed to by attr. For those threads with appscheduled set
+ * to true, this attribute represents the application-specific
+ * scheduling parameters. If successful, the function shall set the
+ * value pointed to by paramsize to the size of the appsched_param
+ * attribute, and shall copy the scheduling parameters occupying
+ * paramsize bytes into the variable pointed to by param. This
+ * variable should be capable of storing a number of bytes equal to
+ * paramsize.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of attr is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_get_appsched_params(const fosa_thread_attr_t *attr,
+ void *param, size_t *paramsize)
+{
+ return FOSA_EINVAL;
+}
+
+/**
+ * fosa_ads_set_appscheduled()
+ *
+ * Dynamically set the appscheduled attribute of a thread
+ *
+ * This function is used to dynamically set the appscheduled attribute
+ * of the thread identified by thread. This attribute controls the
+ * kind of scheduling used for threads created with it. If true, the
+ * thread is scheduled by the application scheduler. If not, it is
+ * scheduled by the system under a fixed priority scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of thread is invalid
+ *
+ * EREJECT: the attachment of the thread to the frsh schehduler
+ * was rejected by the frsh scheduler possibly because of
+ * incorrect attributes, or because the requested minimum
+ * capacity cannot be guaranteed
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_set_appscheduled(fosa_thread_id_t thread, bool appscheduled)
+{
+ return FOSA_EINVAL;
+}
+
+/**
+ * fosa_ads_getappscheduled()
+ *
+ * Dynamically get the appscheduled attribute of a thread
+ *
+ * This function is used to dynamically get the appscheduled attribute
+ * of the thread identified by thread. This attribute controls the
+ * kind of scheduling used for threads created with it. If true, the
+ * thread is scheduled by the application scheduler. If not, it is
+ * scheduled by the system under a fixed priority scheduler
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of thread is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_get_appscheduled(fosa_thread_id_t thread, bool *appscheduled)
+{
+ return FOSA_EINVAL;
+}
+
+
+/**
+ * fosa_ads_setappschedparam()
+ *
+ * Dynamically set the appsched_param attribute of a thread
+ *
+ * This function is used to dynamically set the appsched_param
+ * attribute of the thread identified by thread. For those threads
+ * with appscheduled set to true, this attribute represents the
+ * application-specific scheduling parameters. If successful, the
+ * function shall set the size of the appsched_param attribute to the
+ * value specified by paramsize, and shall copy the scheduling
+ * parameters occupying paramsize bytes and pointed to by param into
+ * that attribute
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of thread is invalid, or paramsize is less than
+ * zero or larger than FOSA_ADS_SCHEDPARAM_MAX
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_set_appsched_params(fosa_thread_id_t thread,
+ const void *param, size_t paramsize)
+{
+ return FOSA_EINVAL;
+}
+
+/**
+ * fosa_ads_get_appsched_params()
+ *
+ * Dynamically get the appsched_param attribute of a thread
+ *
+ * This function is used to dynamically get the appsched_param
+ * attribute of the thread identified by thread. For those threads
+ * with appscheduled set to true, this attribute represents the
+ * application-specific scheduling parameters. If successful, the
+ * function shall set the variable pointed to by paramsize to the size
+ * of the appsched_param attribute, and shall copy the scheduling
+ * parameters occupying paramsize bytes into the variable pointed to
+ * by param. This variable should be capable of storing a number of
+ * bytes equal to paramsize.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of thread is invalid, or paramsize is less than
+ * zero or larger than FOSA_ADS_SCHEDPARAM_MAX
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications.
+ **/
+int fosa_ads_get_appsched_params(fosa_thread_id_t thread,
+ void *param, size_t *paramsize)
+{
+ return FOSA_EINVAL;
+}
+
+
+/*********************************
+ * ADS actions
+ *
+ * A scheduling actions object is used to specify a series of actions
+ * to be performed by the system at the end of a scheduler primitive
+ * operation. The order of the actions added to the object shall be
+ * preserved.
+ *
+ *********************************/
+
+/**
+ * fosa_adsactions_add_reject()
+ *
+ * Add a reject-thread action
+ *
+ * This function adds a thread-reject action to the object referenced
+ * by sched_actions, that will serve to notify that the thread
+ * identified by thread has not been accepted by the scheduler to be
+ * scheduled by it, possibly because the thread contained invalid
+ * application scheduling attributes, or because there are not enough
+ * resources for the new thread. At the end of the new_thread()
+ * scheduler primitive operation, the parent of the rejected thread
+ * waiting on a fosa_thread_create() or the rejected thread itself
+ * waiting on a fosa_ads_set_appscheduled() function shall complete the
+ * function with an error code of EREJECT. If no reject-thread action
+ * is added during the new_thread() scheduler primitive operation, the
+ * thread is accepted to be scheduled by the scheduler and the
+ * associated fosa_thread_create() or the fosa_ads_set_appscheduled()
+ * function shall be completed without error. For the function to
+ * succeed, it has to be called from the new_thread() primitive
+ * operation and for the thread that is requesting attachment to the
+ * scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * ENOMEM: There is insufficient memory to add this action
+ * FOSA_EPOLICY: The thread specified by thread is not the one requesting
+ * attachment to the scheduler, or the function is not being
+ * called from the new_thread primitive operation
+ * EINVAL: The value specified by sched_actions is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_reject(fosa_ads_actions_t *sched_actions,
+ fosa_thread_id_t thread)
+{
+ return FOSA_EINVAL;
+}
+
+/**
+ * fosa_adsactions_add_activate()
+ *
+ * Add a thread-activate action
+ *
+ * This function adds a thread-activate action to the object
+ * referenced by sched_actions. In case the thread had been previously
+ * suspended via posix_appsched_actions_addsuspend(), it will be
+ * activated at the end of the primitive operation.
+ *
+ * In those implementations that do not support urgency scheduling,
+ * the urgencu value is ignored. These implementations cannot support
+ * the frsh hierarchical scheduling module.
+ *
+ * In those implementations supporting urgency-scheduling, the action
+ * will cause the change of the urgency of the thread to the value
+ * specified in the urgency argument. Besides, if the thread was
+ * already active at the time the thread-activate action is executed,
+ * the change or urgency will imply a reordering of the thread in its
+ * priority queue, so that for threads of the same priority, those
+ * with more urgency will be scheduled before those of less urgency.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * ENOMEM: There is insufficient memory to add this action
+ * FOSA_EPOLICY: The thread specified by thread has its appscheduled
+ * attribute set to false,
+ * EINVAL: The value specified by sched_actions is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_activate(fosa_ads_actions_t *sched_actions,
+ fosa_thread_id_t thread,
+ fosa_ads_urgency_t urgency)
+{
+ return FOSA_EINVAL;
+}
+
+/**
+ * fosa_adsactions_add_suspend()
+ *
+ * Add a thread-suspend action
+ *
+ * This function adds a thread-suspend action to the object referenced
+ * by sched_actions, that will cause the thread identified by thread
+ * to be suspended waiting for a thread-activate action at the end of
+ * the scheduler operation. If the thread was already waiting for a
+ * thread-activate action the thread-suspend action has no effect. It
+ * is an error trying to suspend a thread that is blocked by the
+ * operating system.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * ENOMEM: There is insufficient memory to add this action
+ * FOSA_EPOLICY: The thread specified by thread has its appscheduled
+ * attribute set to false,
+ * EINVAL: The value specified by sched_actions is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_suspend(fosa_ads_actions_t *sched_actions,
+ fosa_thread_id_t thread)
+{
+ return FOSA_EINVAL;
+}
+
+/**
+ * fosa_adsactions_add_timeout()
+ *
+ * Add a timeout action
+ *
+ * This function adds a timeout action to the object referenced by
+ * sched_actions, that will cause the timeout() scheduler operation to
+ * be invoked if no other scheduler operation is invoked before
+ * timeout expires. The timeout shall expire when the clock specified by
+ * clock_id reaches the absolute time specified by the at_time
+ * argument.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * ENOMEM: There is insufficient memory to add this action
+ * EINVAL: The value specified by sched_actions is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_timeout(fosa_ads_actions_t *sched_actions,
+ fosa_clock_id_t clock_id,
+ const fosa_abs_time_t *at_time)
+{
+ return FOSA_EINVAL;
+}
+
+/**
+ * fosa_adsactions_add_thread_notification()
+ *
+ * Add a timed-thread-notification action
+ *
+ * This function adds a thread-notification action associated with the
+ * thread specified in the thread argument that will cause the
+ * notification_for_thread() scheduler operation to be invoked at the
+ * time specified by at_time. This operation shall be invoked when the
+ * clock specified by clock_id reaches the absolute time specified by
+ * the at_time argument. In particular, a cpu-time clock may be used
+ * for parameter clock_id.Only one thread-notification can be active
+ * for each thread and clock. Calling the function shall remove the
+ * former thread-notification, if any, that had been programmed for
+ * the same thread and clock. A value of NULL for parameter at_time is
+ * used to cancel a previous thread-notification, if any, for the
+ * thread specified by thread and the clock specified by clock_id.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * ENOMEM: There is insufficient memory to add this action
+ * FOSA_EPOLICY: The thread specified by thread has its appscheduled
+ * attribute set to false,
+ * EINVAL: The value specified by sched_actions is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_thread_notification(fosa_ads_actions_t *sched_actions,
+ fosa_thread_id_t thread,
+ fosa_clock_id_t clock_id,
+ const fosa_abs_time_t *at_time)
+{
+ return FOSA_EINVAL;
+}
+
+
+/**
+ * fosa_ads_set_handled_signal_set()
+ *
+ * Specifiy the set of signals that will be handled by the application
+ * scheduler
+ *
+ * This function is used to dynamically set the set of signals that
+ * are handled by the application scheduler. When a signal included
+ * in this set is generated, the signal() primitive operation of the
+ * application scheduler shall be executed. When a signal in tis set
+ * is generated, it shall always imply the execution of the signal()
+ * primitive operation, regardless of whether that signal could be
+ * accepted by some other thread. Once the signal() primitive
+ * operation is executed the signal is consumed, so no signal handlers
+ * shall be executed and no threads using a sigwait operation shall
+ * return for that particular signal instance. For this function to
+ * succeed, it has to be called from a primitive operation of a
+ * scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EPOLICY: The function has not been called from a scheduler
+ * primitive operation
+ * EINVAL: The value specified by set is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_set_handled_signal_set(fosa_signal_t set[], int size)
+{
+ return FOSA_EINVAL;
+}
+
+
+/**
+ * fosa_signal_queue_scheduler()
+ *
+ * Queue a signal destinated to the scheduler
+ *
+ * This is a special case of fosa_signal_queue() in which the
+ * destinator is the scheduler itself. It is needed by the service
+ * thread to notify the results to the scheduler.
+ *
+ * The problem with this case is that, depending on the implementation,
+ * this call would be translated to a true signal or to a scheduler
+ * notification message.
+ *
+ * Besides for the scheduler we don't have always a destinator
+ * thread_id needed in fosa_signal_queue for OSE.
+ *
+ * So the fosa implementation will solve this issue internally.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the signal specified by signal is not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX
+ *
+ * FOSA_EAGAIN: no resources are available to queue the signal; the
+ * maximum number of queued signals has been reached, or a
+ * systemwide resource limit has been exceeded
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_signal_queue_scheduler(fosa_signal_t signal, fosa_signal_info_t info)
+{
+ return FOSA_EINVAL;
+}
+
+/**
+ * fosa_ads_invoke_withdata()
+ *
+ * Explicitly invoke the scheduler, with data
+ *
+ * This function can be used by any thread in the process to invoke
+ * the ads scheduler or to share data with it.
+ *
+ * If successful, the function shall cause the execution of the
+ * primitive operation explicit_call_with_data() of the ads scheduler
+ * with its thread parameter equal to the thread ID of the calling
+ * thread, and its msg_size parameter equal to msg_size. In addition,
+ * if msg_size is larger than zero, the function shall make available
+ * to the scheduler a memory area whose contents are identical to the
+ * memory area pointed to by msg in the msg parameter of the
+ * explicit_call_with_data() primitive operation (note that copying
+ * the information is not needed).
+ *
+ * The function shall not return until the system has finished
+ * execution of the explicit_call_with_data() primitive operation. If
+ * the reply argument is non NULL, the memory area pointed to by the
+ * reply parameter of explicit_call_with_data() primitive operation is
+ * copied into the memory area pointed to by reply, and its size is
+ * copied into the variable pointed to by reply_size. The size of the
+ * reply information is limited to the value FOSA_ADS_SCHEDINFO_MAX.
+ *
+ * The function shall fail if the size specified by msg_size is larger
+ * than FOSA_ADS_SCHEDINFO_MAX. The function shall fail if primitive
+ * operation explicit_call_with_data() is set to NULL for the ads
+ * scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EPOLICY: The function been called from inside a scheduler
+ * primitive operation
+ * EINVAL: The value of msg_size is less than zero or larger than
+ * FOSA_ADS_SCHEDINFO_MAX
+ * FOSA_EMASKED: The operation cannot be executed because the primitive
+ * operation explicit_call_with_data() is set to NULL
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_invoke_withdata(const void *msg, size_t msg_size,
+ void *reply, size_t *reply_size)
+{
+ return FOSA_EINVAL;
+}
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include "fosa_time.h"
+#include "fosa_clocks_and_timers.h"
+
+static const struct timespec zero_time={0,0};
+
+
+/*************************
+ * Timing: Clocks
+ *************************/
+
+/**
+ * fosa_clock_get_time()
+ *
+ * Get the time from a clock
+ *
+ * This function sets the variable pointed to by current_time to the
+ * current value of the clock specified by clockid, which may be the
+ * FOSA_CLOCK_REALTIME constant or a value obtained with
+ * fosa_get_cputime_clock()
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of clockid is invalid
+ **/
+int fosa_clock_get_time(fosa_clock_id_t clockid,
+ fosa_abs_time_t *current_time)
+{
+ int ret;
+ struct timespec current_time_tspec;
+
+ ret = clock_gettime(clockid, ¤t_time_tspec);
+ if (ret) return errno;
+
+ *current_time = fosa_timespec_to_abs_time(current_time_tspec);
+
+ return 0;
+}
+
+/**
+ * fosa_get_cputime_clock()
+ *
+ * Get the identifier of a cpu-time clock
+ *
+ * This function stores in the variable pointed to by clockid the
+ * identifier of a cpu-time clock for the thread specified by tid.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of tid is invalid
+ **/
+int fosa_thread_get_cputime_clock(fosa_thread_id_t tid,
+ fosa_clock_id_t *clockid)
+{
+ int ret;
+
+ if (tid.linux_pid == tid.linux_tid) /* standard UNIX process */
+ ret = clock_getcpuclockid(tid.linux_pid, clockid);
+ else /* POSIX thread */
+ ret = pthread_getcpuclockid(tid.pthread_id, clockid);
+
+ return ret ? errno : 0;
+}
+
+/*************************
+ * Timing: Timers
+ *************************/
+
+/**
+ * fosa_create_timer()
+ *
+ * Create a one-shot timer
+ *
+ * This function creates a timer based on the clock specified by clock,
+ * and associates to this timer a notification mechanism consisting of
+ * a signal and associated information. Initially, the timer is in the
+ * disarmed state, i.e., not counting time. It can be armed to start
+ * counting time with fosa_timer_arm().
+ *
+ * The function stores the identifier of the newly created timer in the
+ * variable pointed to by timerid.
+ *
+ * When the timer expires, the signal number specified by signal will be
+ * sent together with the information specified by info, to the thread
+ * that armed the timer (@see fosa_timer_arm()).
+ *
+ * Note that, since this is a POSIX implementation, the signal will be sent
+ * to any thread waiting fot it (in a given UNIX process).
+ * No signal-waiting thread or similar strategy is implemented, the specific
+ * thread can be choosed (for example) by means of the signal number.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of clockid or signal is invalid
+ *
+ * EAGAIN: the system lacks enough resources to create the timer
+ **/
+int fosa_timer_create(fosa_clock_id_t clockid,
+ fosa_signal_t signal,
+ fosa_signal_info_t info,
+ fosa_timer_id_t *timerid)
+{
+ int ret;
+ struct sigevent event;
+
+ event.sigev_notify = SIGEV_SIGNAL;
+ event.sigev_signo = signal;
+ event.sigev_value = *((union sigval*) &info);
+
+ ret = timer_create(clockid, &event, timerid);
+
+ return ret ? errno : 0;
+}
+
+/**
+ * fosa_timer_create_with_receiver()
+ *
+ * Create a one-shot timer with a specific signal receiver thread
+ *
+ * This function creates a timer in the same way as fosa_timer_create,
+ * except that the signal generated when the timer expires is sent to
+ * the thread specified by receiver
+ *
+ * You have to use the "simple" fosa_timer_create.
+ **/
+ int fosa_timer_create_with_receiver(fosa_clock_id_t clockid,
+ fosa_signal_t signal,
+ fosa_signal_info_t info,
+ fosa_timer_id_t *timerid,
+ fosa_thread_id_t receiver)
+{
+ int ret;
+ struct sigevent event;
+
+ event.sigev_notify = SIGEV_SIGNAL;
+ event.sigev_signo = signal;
+ event.sigev_value = *((union sigval*) &info);
+ event.sigev_notify = SIGEV_THREAD_ID | SIGEV_SIGNAL;
+ event._sigev_un._tid = receiver.linux_tid;
+
+ ret = timer_create(clockid, &event, timerid);
+
+ return ret ? errno : 0;
+}
+
+/**
+ * Delete a timer
+ *
+ * The function deletes the timer specified by timerid, which becomes
+ * unusable. If the timer was armed, it is automatically disarmed before
+ * deletion.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of timerid is not valid
+ **/
+int fosa_timer_delete(fosa_timer_id_t timerid)
+{
+ int ret;
+
+ ret = timer_delete(timerid);
+
+ return ret ? errno : 0;
+}
+
+/**
+ * fosa_rel_timer_arm()
+ *
+ * Arm a timer with a relative time interval
+ *
+ * The timer specified by timer is armed and starts counting time.
+ *
+ * The value pointed to by value is the relative interval that must
+ * elapse for the timer to expire. Negative values cause the timer to
+ * expire immediately.
+ *
+ * The time is measured with the clock associated with the timer when
+ * it was created.
+ *
+ * If the timer was already armed, the previous time or interval is discarded
+ * and the timer is rearmed with the new value.
+ *
+ * When the timer expires, it is disarmed.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of timerid or value is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_rel_timer_arm(fosa_timer_id_t timerid, const fosa_rel_time_t *value)
+{
+ int ret;
+ struct itimerspec when;
+
+ /* non-periodic one shot timer */
+ when.it_value = fosa_abs_time_to_timespec(*value);
+ when.it_interval = zero_time;
+
+ ret = timer_settime(timerid, 0, &when, NULL);
+
+ return ret ? errno : 0;
+}
+
+
+/**
+ * fosa_abs_timer_arm()
+ *
+ * Arm a timer that will expire in an absolute time instant.
+ *
+ * The timer specified by timer is armed and starts counting time.
+ *
+ * The value pointed to by value is the absolute time at which the
+ * timer will expire. If value specifies a time instant in the past,
+ * the timer expires immediately.
+ *
+ * The time is measured with the clock associated with the timer when
+ * it was created.
+ *
+ * If the timer was already armed, the previous time or interval is discarded
+ * and the timer is rearmed with the new value.
+ *
+ * When the timer expires, it is disarmed.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of timerid or value is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_abs_timer_arm(fosa_timer_id_t timerid, const fosa_abs_time_t *value)
+{
+ int ret;
+ struct itimerspec when;
+
+ /* non-periodic one shot timer */
+ when.it_value = fosa_abs_time_to_timespec(*value);
+ when.it_interval = zero_time;
+
+ ret = timer_settime(timerid, TIMER_ABSTIME, &when, NULL);
+
+ return ret ? errno : 0;
+}
+
+/**
+ * fosa_timer_get_remaining_time()
+ *
+ * Get the remaining time for timer expiration
+ *
+ * Returns the relative remaining time for timer expiration. If the
+ * clock is a CPU clock it returns the time as if the thread was
+ * executing constantly.
+ *
+ * If the timer is disarmed it returns 0.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of timerid or value is invalid
+ **/
+int fosa_timer_get_remaining_time(fosa_timer_id_t timerid,
+ fosa_rel_time_t *remaining_time)
+{
+ int ret;
+ struct itimerspec time;
+
+ if (!remaining_time)
+ return FOSA_EINVAL;
+
+ ret = timer_gettime(timerid, &time);
+ *remaining_time = fosa_timespec_to_rel_time(time.it_value);
+
+ return ret ? errno : 0;
+}
+
+/**
+ * fosa_timer_disarm()
+ *
+ * Disarm a timer
+ *
+ * The timer specified by timer is disarmed, and will not expire unless
+ * it is rearmed. If the timer was already disramed, the function has
+ * no effect.
+ *
+ * If the pointer remaining_time is != NULL, the remaining time before
+ * expiration will be returned in that pointer. If the timer was
+ * disarmed a 0 value will be set.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of timerid or value is invalid
+ **/
+int fosa_timer_disarm(fosa_timer_id_t timerid,
+ struct timespec *remaining_time)
+{
+ int ret;
+ struct itimerspec time;
+
+ if (!remaining_time)
+ return FOSA_EINVAL;
+
+ ret = timer_gettime(timerid, &time);
+ if (ret) return errno;
+
+ *remaining_time = fosa_timespec_to_rel_time(time.it_value);
+
+ time.it_value = zero_time;
+ time.it_interval = zero_time;
+
+ ret = timer_settime(timerid, 0, &time, NULL);
+
+ return ret ? errno : 0;
+}
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_group_clocks.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+
+#include "fosa_group_clocks.h"
+
+/**
+ * fosa_thread_set_create()
+ *
+ * Create an empty thread set and return an identifier
+ *
+ * This function stores in the variable pointed to by set the
+ * identifier of a thread set that is created by the function.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EAGAIN: no resources are currently available to create the
+ * thread set
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_set_create(fosa_thread_set_id_t *set)
+{
+ return FOSA_EINVAL;
+}
+
+
+/**
+ * fosa_thread_set_destroy()
+ *
+ * Destroy a thread set
+ *
+ * This function destroys the thread set identified by set. The
+ * threads that were in the set are detached from the set. It is
+ * an error to use the identifier after this call. The effects of
+ * using a CPU-time clock associated with the destroyed thread are
+ * undefined.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: set is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_set_destroy(fosa_thread_set_id_t set)
+{
+ return FOSA_EINVAL;
+}
+
+
+/**
+ * fosa_thread_set_add()
+ *
+ * Add a thread to a thread set
+ *
+ * This function adds the thread identified with thread_id to the
+ * thread set identified by set.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: set is invalid
+ * FOSA_ENOTSUP: thread already a member of some other set
+ * FOSA_EAGAIN: no resources available to add the new thread
+ * FOSA_ESRCH: thread_id doesn't identify a valid thread
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_set_add(fosa_thread_set_id_t set, fosa_thread_id_t thread_id)
+{
+ return FOSA_EINVAL;
+}
+
+
+/**
+ * fosa_thread_set_del()
+ *
+ * Delete a thread from a thread set
+ *
+ * This function deletes the thread identified with thread_id from
+ * the thread set identified by set.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: set is invalid
+ * FOSA_EINVAL: thread is not a member of the set
+ * FOSA_ESRCH: thread_id doesn't identify a valid thread
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+
+int fosa_thread_set_del(fosa_thread_set_id_t set, fosa_thread_id_t thread_id)
+{
+ return FOSA_EINVAL;
+}
+
+
+/**
+ * fosa_get_groupcpu_clock()
+ *
+ * Get the identifier of a cpu-time clock associated to a thread
+ * set
+ *
+ * This function stores in the variable pointed to by clockid the
+ * identifier of a cpu-time clock for the thread set specified
+ * by set.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the set is invalid
+ * FOSA_EINVAL: clock_id is a null pointer
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_get_groupcpu_clock(const fosa_thread_set_id_t set,
+ fosa_clock_id_t *clock_id)
+{
+ return FOSA_EINVAL;
+}
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_long_jump.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+
+#include "fosa.h"
+
+/**
+ * fosa_long_jump_save_context
+ *
+ * Save the context of the current thread for a future long jump
+ *
+ * This function stores in context the information required to modify
+ * the stack of the calling thread so that a later long jump may be
+ * executed in the future to restore this context
+ *
+ * This function stores in 'context' the registers and the stack
+ * frame of the calling thread. This information can be used by
+ * 'restorecontext' to change the stack of the task so that when it
+ * is scheduled again it returns to the end of this function
+ *
+ * Depending on the underlying implementation, the first invocation
+ * of this function for a given thread may also install a signal
+ * handler or a signal handler thread that is capable of executing
+ * the actions required to restore the context of a thread from the
+ * appropriate context. For instance, in POSIX it is necesaray that
+ * the context is restored from the same thread being restored,
+ * usually from a signal handler of that thread.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of context is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ */
+int fosa_long_jump_save_context(fosa_long_jump_context_t *context)
+{
+ if (context == NULL)
+ return FOSA_EINVAL;
+
+ context->setjmp_retvalue = sigsetjmp(context->setjmp_context, 1);
+
+ return 0;
+}
+
+/**
+ * fosa_long_jump_was_performed
+ *
+ * Check whether the current thread suffered a long jump or not
+ *
+ * This function should be invoked after fosa_long_jump_save_context
+ * to determine whether the current thread is executing normally, or
+ * has suffered a long jump to the point where the context was
+ * saved. If invoked after a direct invocation to
+ * fosa_long_jump_save_context, the function shall return 0. If
+ * invoked after returning from fosa_long_jump_save_context due to a
+ * call to fosa_long_jump_restore_context, the function shall return
+ * 1.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of context is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ */
+int fosa_long_jump_was_performed(const fosa_long_jump_context_t *context,
+ int *jumped)
+{
+ if (context == NULL)
+ return FOSA_EINVAL;
+
+ *jumped = context->setjmp_retvalue != 0;
+
+ return 0;
+}
+
+/**
+ * Body of the long-jump handler thread
+ **/
+void __long_jump_handler(int n, siginfo_t *info, void *c)
+{
+ fosa_long_jump_context_t *context =
+ (fosa_long_jump_context_t*) info->si_ptr;
+
+ siglongjmp(context->setjmp_context, -1);
+}
+
+/**
+ * fosa_long_jump_install_handler
+ *
+ * Install a long jump handler for the calling thread
+ *
+ * This function shall install a handler that is capable of causing a
+ * long jump operation that restores the context of a thread to a
+ * previously saved value. If the handler has already been installed
+ * for this thread the previously installed handler will be used and
+ * the call shall succeed.
+ *
+ * The long-jump handler is waiting for a signal to notify that a
+ * thread context should be restored. This signal must carry attached
+ * to it a pointer to the variable where the thread context was
+ * saved. The thread referenced in that context will have its
+ * internal context restored to the point where it was saved. For
+ * this restore operation to work properly, the program frame where
+ * the thread saved its context must still be valid.
+ *
+ * Depending on the implementation a given thread may also install a signal
+ * handler or a signal handler thread that is capable of executing
+ * the actions required to restore the context of a thread from the
+ * appropriate context. For instance, in POSIX it is necesaray that
+ * the context is restored from the same thread being restored,
+ * usually from a signal handler of that thread.
+ *
+ * The function shall store in the variable pointed to by signal the
+ * identifier of the signal that must be used to notify the request
+ * for a long jump to be executed. In the variable pointed to by
+ * handler, it shall store the thread id to which the signal must be
+ * sent. The signal must be sent with its attached information set to
+ * a pointer to the variable of type fosa_long_jump_context_t where
+ * the context of the thread to be restored was saved.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of context is invalid
+ * FOSA_ENOMEM: there are no resources to satisfy the call at this time
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ */
+int fosa_long_jump_install_handler(fosa_signal_t *signal,
+ fosa_thread_id_t *handler)
+{
+ int ret;
+ struct sigaction sa_long_jump;
+
+ *signal = FOSA_LONG_JUMP_SIGNAL;
+ *handler = fosa_thread_self();
+
+ sa_long_jump.sa_handler = NULL;
+ sa_long_jump.sa_sigaction = __long_jump_handler;
+ sigemptyset(&sa_long_jump.sa_mask);
+ sa_long_jump.sa_flags = SA_SIGINFO;
+
+ ret = sigaction(*signal, &sa_long_jump, NULL);
+
+ return ret ? errno : 0;
+}
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_mutexes_and_condvars.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include "fosa_time.h"
+#include "fosa_configuration_parameters.h"
+#include "fosa_mutexes_and_condvars.h"
+
+#ifdef OMK_FOR_USER /* If compiled by OMK, use the config */
+#include "fosa_config.h"
+#endif
+
+/*******************************************************
+ * Mutexes with priority/bandwidth inheritance
+ ******************************************************/
+
+/**
+ * fosa_mutex_init()
+ *
+ * Initialize a frsh mutex
+ *
+ * The mutex pointed to by mutex is initialized as a mutex using
+ * the priority ceiling protocol. A priority ceiling of prioceiling
+ * is assigned to this mutex.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of prioceiling is invalid
+ * EAGAIN: the system lacked the necessary resources to create the mutex
+ * ENOMEM: Insufficient memory exists to initialize the mutex
+ * EBUSY: The system has detected an attempt to reinitialize the mutex
+ **/
+int fosa_mutex_init(fosa_mutex_t *mutex, int prioceiling)
+{
+ int ret;
+ pthread_mutexattr_t attr;
+
+ ret = pthread_mutexattr_init(&attr);
+ if (ret) return errno;
+
+#ifndef CONFIG_NO_PRIO_INHERIT /* Valgrind doesn't support this attribute */
+ ret = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
+ if (ret) return errno;
+#endif
+
+ ret = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+ if (ret) return errno;
+
+ return pthread_mutex_init(mutex, &attr);
+}
+
+/**
+ * fosa_mutex_destroy()
+ *
+ * Destroy a frsh mutex
+ *
+ * The mutex pointed to by mutex is destroyed
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of mutex is invalid
+ * EBUSY: The mutex is in use (is locked)
+ **/
+int fosa_mutex_destroy(fosa_mutex_t *mutex)
+{
+ return pthread_mutex_destroy(mutex);
+}
+
+/**
+ * fosa_mutex_set_prioceiling()
+ *
+ * Dynamically set the priority ceiling of a mutex
+ *
+ * Since in this implementation we use BandWidth Inheritance defining the
+ * ceiling of a mutex is meaningless, and so the function always returns
+ * EINVAL
+ **/
+int fosa_mutex_set_prioceiling(fosa_mutex_t *mutex,
+ int new_ceiling,
+ int *old_ceiling)
+{
+ return FOSA_EINVAL;
+}
+
+/**
+ * fosa_mutex_get_prioceiling()
+ *
+ * Dynamically get the priority ceiling of a mutex
+ *
+ * Since in this implementation we use BandWidth Inheritance defining the
+ * ceiling of a mutex is meaningless, and so the function always returns
+ * EINVAL
+ **/
+int fosa_mutex_get_prioceiling(const fosa_mutex_t *mutex, int *ceiling)
+{
+ return FOSA_EINVAL;
+}
+
+/**
+ * fosa_mutex_lock()
+ *
+ * Lock a mutex
+ *
+ * This function locks the mutex specified by mutex. If it is already
+ * locked, the calling thread blocks until the mutex becomes
+ * available. The operation returns with the mutex in the locked
+ * state, with the calling thread as its owner.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of mutex is invalid, or the priority of the
+ * calling thread is higher than the priority ceiling of the mutex
+ * EDEADLK: the current thread already owns this mutex
+ **/
+int fosa_mutex_lock(fosa_mutex_t *mutex)
+{
+ return pthread_mutex_lock(mutex);
+}
+
+/**
+ * fosa_mutex_trylock()
+ *
+ * Try locking a mutex
+ *
+ * This function is identical to fosa_mutex_lock() except that if the
+ * mutex is already locked the call returns immediately with an error
+ * indication.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of mutex is invalid, or the priority of the
+ * calling thread is higher than the priority ceiling of the mutex
+ * EBUSY: the mutex was already locked
+ **/
+int fosa_mutex_trylock(fosa_mutex_t *mutex)
+{
+ return pthread_mutex_trylock(mutex);
+}
+
+/**
+ * fosa_mutex_unlock()
+ *
+ * Unlock a mutex
+ *
+ * This function must be called by the owner of the mutex referenced
+ * by mutex, to unlock it. If there are threads blocked on the mutex
+ * the mutex becomes available and the highest priority thread is
+ * awakened to acquire the mutex.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of mutex is invalid
+ * EPERM: the calling thread is not the owner of the mutex
+ **/
+int fosa_mutex_unlock(fosa_mutex_t *mutex)
+{
+ return pthread_mutex_unlock(mutex);
+}
+
+/**********************
+ * Condition variables
+ *********************/
+
+/**
+ * fosa_cond_init()
+ *
+ * Initiatize a condition variable
+ *
+ * The condition variable referenced by cond is initialized with
+ * the attributes required by the FOSA implementation.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EAGAIN: the system lacked the necessary resources to create the
+ * condition variable
+ * ENOMEM: Insufficient memory exists to initialize the condition variable
+ * EBUSY: The system has detected an attempt to reinitialize the
+ * condition variable
+ **/
+int fosa_cond_init(fosa_cond_t *cond)
+{
+ int ret;
+ pthread_condattr_t attr;
+
+ ret = pthread_condattr_init(&attr);
+ if (ret) return errno;
+
+ ret = pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+ if (ret) return errno;
+
+ return pthread_cond_init(cond, &attr);
+}
+
+/**
+ * fosa_cond_destroy()
+ *
+ * Destroy a condition variable
+ *
+ * The condition variable pointed to by cond is destroyed
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of cond is invalid
+ * EBUSY: The condition variable is in use (a thread is waiting on it)
+ **/
+int fosa_cond_destroy(fosa_cond_t *cond)
+{
+ return pthread_cond_destroy(cond);
+}
+
+/**
+ * fosa_cond_signal()
+ *
+ * Signal a condition variable
+ *
+ * This call unblocks at least one of the threads that are waiting on
+ * the condition variable referenced by cond. If there are no threads
+ * waiting, the function has no effect
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of cond is invalid
+ **/
+int fosa_cond_signal(fosa_cond_t *cond)
+{
+ return pthread_cond_signal(cond);
+}
+
+/**
+ * fosa_cond_broadcast()
+ *
+ * Broadcast a condition variable
+ *
+ * This call unblocks all of the threads that are waiting on the
+ * condition variable referenced by cond. If there are no threads
+ * waiting, the function has no effect.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of cond is invalid
+ **/
+int fosa_cond_broadcast(fosa_cond_t *cond)
+{
+ return pthread_cond_broadcast(cond);
+}
+
+/**
+ * fosa_cond_wait()
+ *
+ * Wait at a condition variable
+ *
+ * This call is used to block on the condition variable referenced by
+ * cond. It shall be called with the mutex referenced by mutex
+ * locked. The function releases the mutex and blocks the calling
+ * thread until the condition is signalled by some other thread and
+ * the calling thread is awakened. Then it locks the mutex and
+ * returns with the mutex locked by the calling thread.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of cond or mutex is invalid, or different
+ * mutexes were used for concurrent wait operations on cond, or
+ * the mutex was not owned by the calling thread
+ **/
+int fosa_cond_wait(fosa_cond_t *cond, fosa_mutex_t *mutex)
+{
+ return pthread_cond_wait(cond, mutex);
+}
+
+/**
+ * fosa_cond_timedwait()
+ *
+ * Wait at a condition variable, with a timeout
+ *
+ * This function is equal to fosa_cond_wait(), except that the maximum
+ * wait time is limited to the absolute time referenced by abstime, as
+ * measured by the FOSA_CLOCK_ABSOLUTE clock.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of cond or mutex or abstime is invalid, or different
+ * mutexes were used for concurrent wait operations on cond, or
+ * the mutex was not owned by the calling thread
+ * ETIMEDOUT: the timeout expired
+ **/
+int fosa_cond_timedwait(fosa_cond_t *cond,
+ fosa_mutex_t *mutex,
+ const fosa_abs_time_t *abstime)
+{
+ struct timespec abstime_tspec;
+
+ abstime_tspec = fosa_abs_time_to_timespec(*abstime);
+ return pthread_cond_timedwait(cond, mutex, &abstime_tspec);
+}
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+#include "fosa_platform_values.h"
+
+/**
+ * fosa_get_cpu_resource_id()
+ *
+ * Obtain the cpu resource id of the current node by making use of any
+ * mechanism that allows to distinguish between nodes (ie MAC addresses,
+ * configuration parameters, etc..)
+ */
+
+#if 1
+#include <stdio.h>
+#define DEBUG(x,args...) printf("%s: " x, __func__ , ##args)
+#else
+#define DEBUG(x,args...)
+#endif
+
+int fosa_get_cpu_resource_id(fosa_resource_id_t *cpu_id)
+{
+ return FOSA_EINVAL;
+}
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include "fosa_time.h"
+#include "fosa_configuration_parameters.h"
+#include "fosa_threads_and_signals.h"
+
+#ifdef OMK_FOR_USER /* If compiled by OMK, use the config */
+#include "fosa_config.h"
+#endif
+
+/*************************
+ * Storage of thread-specific keys
+ *************************/
+
+static pthread_key_t key_list[FOSA_MAX_KEYS];
+static bool key_in_use[FOSA_MAX_KEYS];
+static pthread_mutex_t key_lock;
+
+
+/* Initialize the keys data structure */
+int init_keys()
+{
+ int i, ret;
+ pthread_mutexattr_t attr;
+
+ for(i = 0; i < FOSA_MAX_KEYS; i++)
+ key_in_use[i] = false;
+
+ ret = pthread_mutexattr_init(&attr);
+ if (ret) return errno;
+
+#ifndef CONFIG_NO_PRIO_INHERIT /* Not supported on older systems */
+ ret = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
+ if (ret) return errno;
+#endif
+
+ ret = pthread_mutex_init(&key_lock,&attr);
+ if (ret) return errno;
+
+ return 0;
+}
+
+/*************************
+ * Thread identification
+ *************************/
+
+/**
+ * fosa_thread_equal()
+ *
+ * Compare two thread identifiers to determine if they refer to the
+ * same thread
+ **/
+bool fosa_thread_equal(fosa_thread_id_t t1, fosa_thread_id_t t2)
+{
+ return t1.linux_pid == t2.linux_pid &&
+ t1.linux_tid == t2.linux_tid &&
+ pthread_equal(t1.pthread_id, t2.pthread_id);
+}
+
+/**
+ * fosa_thread_self()
+ *
+ * Return the thread id of the calling thread
+ **/
+fosa_thread_id_t fosa_thread_self()
+{
+ fosa_thread_id_t thread_self;
+ /**
+ * NB. Remember:
+ * fosa_thread_id_t => struct {
+ * pthread_t pthread_id;
+ * pid_t linux_pid;
+ * tid_t linux_tid;
+ * };
+ **/
+ thread_self.pthread_id = pthread_self();
+ thread_self.linux_pid = getpid();
+ thread_self.linux_tid = syscall(__NR_gettid); /* gettid() */
+
+ return thread_self;
+}
+
+/*************************
+ * Thread attributes
+ *************************/
+
+static inline int __fosa_check_thread(const fosa_thread_id_t *tid)
+{
+ if (tid->linux_pid == tid->linux_tid)
+ return 0;
+
+ return 1;
+}
+
+/**
+ * fosa_thread_attr_init()
+ *
+ * Initialize a thread attributes object
+ *
+ * This function initializes the object pointed to by attr to all
+ * the default values defined by FRSH
+ *
+ * return 0 if successful; otherwise it returns
+ * FOSA_ENOMEM: insufficient memory exists to initialize the thread
+ * attributes object
+ **/
+int fosa_thread_attr_init(fosa_thread_attr_t *attr)
+{
+ return pthread_attr_init(attr);
+}
+
+/**
+ * fosa_thread_attr_destroy()
+ *
+ * Destroy a thread attributes object
+ *
+ * This function is used to destroy the thread attributes object,
+ * pointed to by attr, and deallocate any system resources allocated for it
+ *
+ * Returns 0
+ **/
+int fosa_thread_attr_destroy(fosa_thread_attr_t *attr)
+{
+ return pthread_attr_destroy(attr);
+}
+
+/**
+ * fosa_thread_attr_set_stacksize()
+ *
+ * Set the thread minimum stack size in a thread attributes object
+ *
+ * This function sets the minimum stack size of the thread attributes
+ * object attr to the value given by stacksize, in bytes. This
+ * function has no runtime effect on the stack size, except when the
+ * attributes object is used to create a thread, when it will be
+ * created with the specified minimum stack size
+ *
+ * return 0 if successful, or the following error code:
+ * FOSA_EINVAL: the specified stacksize value is not supported in
+ * this implementation
+ **/
+int fosa_thread_attr_set_stacksize(fosa_thread_attr_t *attr,
+ size_t stacksize)
+{
+ return pthread_attr_setstacksize(attr, stacksize);
+}
+
+/**
+ * fosa_thread_attr_get_stacksize()
+ *
+ * Get the thread minimum stack size from a thread attributes object
+ *
+ * This function sets the variable pointed to by stacksize to the
+ * minimum stack size stored in the thread attributes object attr.
+ *
+ * return 0
+ **/
+int fosa_thread_attr_get_stacksize(const fosa_thread_attr_t *attr,
+ size_t *stacksize)
+{
+ return pthread_attr_getstacksize(attr, stacksize);
+}
+
+/*************************
+ * Thread creation and termination
+ *************************/
+
+/**
+ * fosa_thread_create()
+ *
+ * This function creates a new thread using the attributes specified
+ * in attr. If attr is NULL, default attributes are used. The new
+ * thread starts running immediately, executing the function specified
+ * by code, with an argument equal to arg. Upon successful return, the
+ * variable pointed to by tid will contain the identifier of the newly
+ * created thread. The set of signals that may be synchronously
+ * accepted is inherited from the parent thread.
+ *
+ * Returns 0 if successful; otherwise it returs a code error:
+ *
+ * EAGAIN: the system lacks the necessary resources to create a
+ * new thread or the maximum number of threads has been
+ * reached
+ *
+ * EINVAL: the value specified by attr is invalid (for instance,
+ * it has not been correctly initialized)
+ *
+ * EREJECT: the cretion of the thread was rejected by the frsh scheduler
+ * possibly because of incorrect attributes, or because the
+ * requested minimum capacity cannot be guaranteed
+ **/
+int fosa_thread_create(fosa_thread_id_t *tid,
+ const fosa_thread_attr_t *attr,
+ fosa_thread_code_t code,
+ void *arg)
+{
+ return pthread_create(&tid->pthread_id, attr, code, arg);
+}
+
+/**
+ * Note: no thread termination primitive is provided. The termination
+ * of a thread will be notified by the system to the FRSH scheduler
+ * through the scheduler API
+ **/
+
+/**************************************************
+ * Thread-specific data
+ * (extended with access from a different thread)
+ *
+ * Several data items (pointers) may be associated with each thread
+ * Each item is identified through a key, an integer value between 0
+ * and FOSA_MAX_KEYS-1. The caller is responsible of allocating and
+ * deallocating the memory area pointed to by the pointer
+ **************************************************/
+
+/**
+ * fosa_key_create()
+ *
+ * Create a new key for thread specific data.
+ *
+ * Prior to setting data in a key, we need ask the system to create
+ * one for us.
+ *
+ * return 0 if successful \n
+ * FOSA_EINVAL If we already have reached the FOSA_MAX_KEYS limit.
+ * FOSA_ENOMEM If there are no enough memory resources to
+ * create the key.
+ **/
+int fosa_key_create(int *key)
+{
+ int i, ret;
+ bool found = false;
+
+ ret = pthread_mutex_lock(&key_lock);
+ if (ret) return ret;
+
+ /* find an unused key */
+ for (i = 0; i < FOSA_MAX_KEYS; i++) {
+ if (!key_in_use[i]) {
+ ret = pthread_key_create(&(key_list[i]), NULL);
+ if (ret) return ret;
+
+ *key = i;
+ key_in_use[i] = true;
+ found = true;
+
+ break;
+ }
+ }
+
+ ret = pthread_mutex_unlock(&key_lock);
+ if (ret) return ret;
+
+ return (!found ? FOSA_EINVAL : ret);
+}
+
+/**
+ * fosa_key_destroy()
+ *
+ * Destroy a key
+ *
+ * This destroys the key and isables its use in the system
+ *
+ * return 0 if successful
+ * FOSA_EINVAL The key is not initialised or is not in FOSA key range.
+ **/
+int fosa_key_destroy(int key)
+{
+ int ret;
+
+ ret = pthread_mutex_lock(&key_lock);
+ if (ret) return ret;
+
+ ret = pthread_key_delete(key_list[key]);
+ if (ret) return ret;
+
+ key_in_use[key]=false;
+
+ ret = pthread_mutex_unlock(&key_lock);
+ if (ret) return ret;
+
+ return 0;
+}
+
+
+/**
+ * fosa_thread_set_specific_data()
+ *
+ * Set thread-specific data
+ *
+ * For the thread identified by tid, the thread-specifid data field
+ * identified by key will be set to the value specified by value
+ *
+ * In this implementation, according to POSIX, the accessed data field
+ * is the one of the calling thread, not the one specified via tid.
+ *
+ * Returns 0 if successful; otherwise, an error code is returned
+ * EINVAL: the value of key is not between 0 and FOSA_MAX_KEYS-1
+ **/
+ int fosa_thread_set_specific_data(int key,
+ fosa_thread_id_t tid,
+ const void * value)
+{
+ int ret;
+
+ /* only POSIX threads can have specific data */
+ if (!__fosa_check_thread(&tid))
+ return FOSA_EINVAL;
+
+ ret = pthread_setspecific(key_list[key], value);
+
+ return ret ? ret : 0;
+}
+
+/**
+ * fosa_thread_get_specific_data()
+ *
+ * Get thread-specific data
+ *
+ * For the thread identified by tid, the thread-specifid data field
+ * identified by key will be copied to the variable pointed to by value
+ *
+ * In this implementation, according to POSIX, the accessed data field
+ * is the one of the calling thread, not the one specified via tid.
+ *
+ * Returns 0 if successful; otherwise, an error code is returned
+ * EINVAL: the value of key is not between 0 and FOSA_MAX_KEYS-1
+ **/
+int fosa_thread_get_specific_data(int key,
+ fosa_thread_id_t tid,
+ void ** value)
+{
+ /* only POSIX threads can have specific data */
+ if (!__fosa_check_thread(&tid))
+ return EINVAL;
+
+ *value = pthread_getspecific(key_list[key]);
+
+ return !value ? FOSA_EINVAL : 0;
+}
+
+/******************************************************************
+ * Thread scheduling
+ *
+ * This implementation of FRSH assumes an underlying fixed priority
+ * scheduler with priorities in a range, with a minimum and a
+ * maximumm, a number of priority levels with at least 31
+ * priorities. A larger number implies a larger priority. In systems
+ * in which the underlying scheduler uses the opposite convention, a
+ * mapping is automatically provided by the OS adaptation layer.
+ *******************************************************************/
+
+/**
+ * fosa_get_priority_max()
+ *
+ * Return the maximum priority value used in this implementation
+ **/
+int fosa_get_priority_max()
+{
+ int ret;
+
+ ret = sched_get_priority_max(SCHED_RR);
+
+ return ret ? errno : 0;
+}
+
+/**
+ * fosa_get_priority_min()
+ *
+ * Return the minimum priority value used in this implementation
+ **/
+int fosa_get_priority_min()
+{
+ int ret;
+
+ ret = sched_get_priority_min(SCHED_RR);
+
+ return ret ? errno : 0;
+}
+
+/**
+ * fosa_thread_attr_set_prio()
+ *
+ * Change the priority of a thread attributes object
+ *
+ * The priority of the thread attriutes object specified by attr is
+ * set to the value specified by prio. This function has no runtime
+ * effect on the priority, except when the attributes object is used
+ * to create a thread, when it will be created with the specified
+ * priority
+ *
+ * Returns 0 if successful, or the following error code:
+ * EINVAL: the specified priority value is not between the
+ * minimum and the maximum priorities defined in this
+ * FRSH implementation
+ **/
+int fosa_thread_attr_set_prio(fosa_thread_attr_t *attr, int prio)
+{
+ int ret;
+ struct sched_param param;
+
+ param.sched_priority = prio;
+ ret = pthread_attr_setschedpolicy(attr, SCHED_RR);
+ if (ret) return ret;
+
+ return pthread_attr_setschedparam(attr, ¶m);
+}
+
+/**
+ * fosa_thread_attr_get_prio()
+ *
+ * Get the priority from a thread attributes object
+ *
+ * This function sets the variable pointed to by prio to the
+ * priority stored in the thread attributes object attr.
+ *
+ * Returns 0
+ **/
+int fosa_thread_attr_get_prio(const fosa_thread_attr_t *attr, int *prio)
+{
+ int ret;
+ struct sched_param param;
+
+ ret = pthread_attr_getschedparam(attr, ¶m);
+ if (ret) return ret;
+
+ *prio = param.sched_priority;
+
+ return 0;
+}
+
+/**
+ * fosa_thread_set_prio()
+ *
+ * Dynamically change the priority of a thread
+ *
+ * The priority of the thread identified by tid is
+ * set to the value specified by prio.
+ *
+ * Returns 0 if successful, or the following error code:
+ * EINVAL: the specified priority value is not between the
+ * minimum and the maximum priorities defined in this
+ * FRSH implementation
+ **/
+int fosa_thread_set_prio(fosa_thread_id_t tid, int prio)
+{
+ int ret;
+ struct sched_param param;
+
+ param.sched_priority = prio;
+
+ ret = sched_setscheduler(0, SCHED_RR, ¶m);
+
+ return ret ? errno : 0;
+}
+
+/**
+ * fosa_thread_get_prio()
+ *
+ * Dynamically get the priority of a thread
+ *
+ * This function sets the variable pointed to by prio to the
+ * priority of the thread identified by tid
+ *
+ * Returns 0
+ **/
+int fosa_thread_get_prio(fosa_thread_id_t tid, int *prio)
+{
+ struct sched_param param;
+ int ret;
+
+ ret = sched_getparam(0, ¶m);
+ *prio = param.sched_priority;
+
+ return ret ? errno : 0;
+}
+
+/*******************************************************************
+ * Signals
+ *
+ * Signals represent events that may be notified by the system, or
+ * sent explicitly by the application, and for which a thread may
+ * synchronously wait. Signals carry an associated piece of
+ * information (an integer or a pointer) and are queued until they are
+ * accepted. Signals are identified by an integer signal number (of
+ * the type fosa_signal_t) in the range FOSA_SIGNAL_MIN,
+ * FOSA_SIGNAL_MAX. This range is required to have at least <tbd>
+ * values.
+ *******************************************************************/
+
+/**
+ * fosa_set_accepted_signals()
+ *
+ * Establish the set of signals that may be synchronously accepted
+ * by the calling thread
+ *
+ * The function uses the array of signal numbers specified by set,
+ * which must be of size equal to size
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the array contains one or more values which are not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size
+ * is less than 0
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_set_accepted_signals(fosa_signal_t set[], int size)
+{
+ int i, ret;
+ fosa_thread_id_t self;
+ sigset_t sigset;
+ struct sigaction action;
+
+ ret = sigemptyset(&sigset);
+ if (ret) goto err;
+
+ action.sa_handler = SIG_DFL;
+ action.sa_mask = sigset;
+ action.sa_flags = SA_SIGINFO;
+ action.sa_sigaction = NULL;
+
+ for (i = 0; i < size; i++) {
+ ret = sigaddset(&sigset, set[i]);
+ if (ret) goto err;
+ ret = sigaction(set[i], &action, NULL);
+ if (ret) goto err;
+ }
+
+ self = fosa_thread_self();
+ if (__fosa_check_thread(&self)) {
+ ret = pthread_sigmask(SIG_BLOCK, &sigset, NULL);
+ if (ret) return ret;
+ } else {
+ ret = sigprocmask(SIG_BLOCK, &sigset, NULL);
+ if (ret) goto err;
+ }
+
+ return 0;
+err:
+ return errno;
+}
+
+/**
+ * fosa_signal_queue()
+ *
+ * Queue a signal
+ *
+ * This function is used to explicitly send a signal with a specified
+ * value
+ *
+ * The signal number specified by signal is sent together with the
+ * information specified by info, to the thread identified by
+ * receiver. In those implementations that do not support queueing a
+ * signal with information to a thread (such as POSIX), the signal may
+ * be sent to any thread that is waiting for this signal via
+ * fosa_signal_wait(). Portability can be ensured by having the receiver
+ * thread be the one who is waiting for the signal.
+ *
+ * In this implementation, this limitation has been overcome by means
+ * of the Linux specific capability of sending a timer event directly
+ * to a specific thread. Thus, we program a fake timer to fire immediately
+ * and notify such event to the requested receiver thread.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the signal specified by signal is not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX
+ *
+ * EAGAIN: no resources are available to queue the signal; the
+ * maximum number of queued signals has been reached, or a
+ * systemwide resource limit has been exceeded
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_signal_queue(fosa_signal_t signal,
+ fosa_signal_info_t info,
+ fosa_thread_id_t receiver)
+{
+ int ret;
+ timer_t fake_timer;
+ struct itimerspec fake_time;
+ struct sigevent fake_event;
+
+ ret = timer_create(FOSA_CLOCK_REALTIME, &fake_event, &fake_timer);
+ if (ret) goto err;
+
+ fake_time.it_value.tv_sec = fake_time.it_value.tv_nsec = 0;
+ fake_time.it_interval.tv_sec = fake_time.it_interval.tv_nsec = 0;
+ fake_event.sigev_notify = SIGEV_THREAD_ID | SIGEV_SIGNAL;
+ fake_event.sigev_signo = SIGRTMIN;
+ fake_event.sigev_value.sival_int = info.sival_int;
+ fake_event._sigev_un._tid = receiver.linux_tid;
+
+ ret = timer_settime(fake_timer, TIMER_ABSTIME, &fake_time, NULL);
+ if (ret) {
+ timer_delete(fake_timer);
+ goto err;
+ }
+
+ ret = timer_delete(fake_timer);
+ if (ret) goto err;
+
+ return 0;
+err:
+ return errno;
+}
+
+/**
+ * fosa_signal_wait()
+ *
+ * Wait for a signal
+ *
+ * The function waits for the arrival of one of the signals in the
+ * array of signal numbers specified by set, which must be of size
+ * equal to size. If there is a signal already queued, the function
+ * returns immediately. If there is no signal of the specified set
+ * queued, the calling thread is suspended until a signal from that
+ * set arrives. Upon return, if signal_received is not NULL the number
+ * of the signal received is stored in the variable pointed to by
+ * signal_received; and if info is not NULL the associated information
+ * is stored in the variable pointed to by info.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the array contains one or more values which are not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size
+ * is less than 0
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_signal_wait(fosa_signal_t set[], int size,
+ fosa_signal_t *signal_received,
+ fosa_signal_info_t *info)
+{
+ int i, ret;
+ sigset_t sigset;
+ siginfo_t siginfo;
+
+ ret = sigemptyset(&sigset);
+ if (ret) goto err;
+
+ for (i = 0; i < size; i++) {
+ ret = sigaddset(&sigset,set[i]);
+ if (ret) goto err;
+ }
+
+ ret = sigwaitinfo(&sigset, &siginfo);
+ if (ret) goto err;
+
+ if (info != NULL && signal_received != NULL)
+ *signal_received = siginfo.si_signo;
+ if (info != NULL)
+ *info = (fosa_signal_info_t) siginfo.si_value.sival_int;
+
+ return 0;
+err:
+ return errno;
+}
+
+/**
+ * fosa_signal_timedwait()
+ *
+ * Timed wait for a signal
+ *
+ * This function behaves the same as fosa_signal_wait(), except that
+ * the suspension time is limited to the time interval specified in
+ * the timespec structure referenced by timeout.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the array contains one or more values which are not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size
+ * is less than 0, or timeout is invalid
+ * EAGAIN: The timeout expired
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_signal_timedwait(fosa_signal_t set[], int size,
+ fosa_signal_t *signal_received,
+ fosa_signal_info_t *info,
+ const struct timespec *timeout)
+{
+ int i, ret;
+ sigset_t signalset;
+ siginfo_t siginfo;
+
+ ret = sigemptyset(&signalset);
+ if (ret) goto err;
+
+ for (i = 0; i < size; i++) {
+ ret = sigaddset(&signalset,set[i]);
+ if (ret) goto err;
+ }
+
+ ret = sigtimedwait(&signalset,&siginfo,timeout);
+ if (ret) goto err;
+
+ if (signal_received != NULL)
+ *signal_received = siginfo.si_signo;
+ if (info != NULL)
+ *info = (fosa_signal_info_t) siginfo.si_value.sival_int;
+
+ return 0;
+err:
+ return errno;
+}
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+// fosa_time.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include "fosa_time.h"
+#include "fosa_clocks_and_timers.h"
+#include "fosa_threads_and_signals.h"
+
+/**
+ * fosa_eat()
+ *
+ * Eat some time using system clock facilities
+ **/
+void inline fosa_eat(const struct timespec *cpu_time)
+{
+ int ret;
+ fosa_thread_id_t self;
+ clockid_t clock_id;
+ struct timespec current_time, time_to_go;
+
+ self = fosa_thread_self();
+ ret = fosa_thread_get_cputime_clock(self, &clock_id);
+ if (ret) return;
+
+ ret = clock_gettime(clock_id, ¤t_time);
+ if (ret) return;
+
+ time_to_go = fosa_abs_time_incr(current_time, *cpu_time);
+ while (fosa_abs_time_smaller_or_equal(current_time, time_to_go)) {
+ ret = clock_gettime(clock_id, ¤t_time);
+ if (ret) return;
+ }
+}
--- /dev/null
+all: objs
+
+include ../config.mk
+include ../rules.mk
+
+CFLAGS += -I$(FOSA_PATH)/src_marte_os
+
+SRCS := $(wildcard *.c)
+OBJS := $(patsubst %.c,%.o,$(wildcard *.c))
+LIBFOSA_SRCS := $(wildcard *.c)
+LIBFOSA_HDRS := $(wildcard $(FOSA_PATH)/include/*.h) $(wildcard *.h)
+
+objs: $(OBJS)
+
+%.o: %.c $(LIBFOSA_SRCS) $(LIBFOSA_HDRS)
+ $(CC) $(CFLAGS) -c $<
\ No newline at end of file
--- /dev/null
+SUBDIRS = tests
+
+lib_LIBRARIES=fosa
+fosa_SOURCES=$(notdir $(wildcard $(SOURCES_DIR)/*.c))
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_app_def_sched.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+// 26-Jun-07 SANGORRIN: comment scheduler mutex because signal_set can only be
+// set from the scheduler itself (don't delete because it might be useful in
+// the future).
+//
+// 25-Jun-07 SANGORRIN: when posix_appsched_execute_actions had an error code
+// was wrong. Now we clear actions before (and added destroy operation!), then
+// execute scheduler op and then go back to main loop (when error it continued
+// executing the rest of actions)
+//
+// 10-Jul-07 SANGORRIN: in the new_thread callback we need to accept the thread
+// before suspend or activate it.
+// -----------------------------------------------------------------------
+
+#include "fosa.h"
+
+#include <pthread.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <sched.h>
+#include <errno.h>
+#include <sys/marte_sched_events_codes.h>
+
+#include <misc/error_checks.h>
+
+// Full error checking option
+// --------------------------
+// Uncomment the following definition if full error checking is desired
+// Beware that this option will introduce overhead in each context switch
+
+#define FULL_ERROR_CHECKING
+
+/********************************
+ * Application-defined scheduling
+ ********************************/
+
+/**
+ * We make the following ASSUMPTIONS:
+ *
+ * - The ADS always executes in the user memory space, so we don't
+ * need to manage the memory space translation.
+ *
+ * - Only one application scheduler exists, so we don't need a
+ * scheduler_id.
+ **/
+
+
+/**
+ * Data structures for the scheduler thread
+ **/
+
+// data structure that is passed to the scheduler thread
+struct scheduler_thread_data {
+ fosa_ads_scheduler_ops_t scheduler_ops; // entry points
+ size_t scheduler_data_size; // size of scheduler data
+ void * scheduler_data; // pointer to scheduler data
+ void * init_args; // pointer to init args
+ size_t init_args_size; // size of init args
+ sigset_t sch_signal_set; // set of signals used by the
+ // scheduler
+// pthread_mutex_t sch_mutex; // mutex used to share info with
+ // the scheduler
+ pthread_key_t clock_key; // key to thread-specific data where
+ // a clock id is stored
+ pthread_key_t msg_key; // key to thread-specific data with
+ // a pointer to the messages for
+ // explicit invoke operations
+};
+
+// data structure used in the explicit call with data operation
+struct explicit_call_info {
+ size_t info_size;
+ void * info_ptr;
+ size_t reply_size;
+ void * reply_ptr;
+};
+
+// static variables
+static struct scheduler_thread_data schedthreaddata;
+static pthread_t scheduler_thread_id;
+
+/**
+ * Code of application-defined thread. The current version of MaRTE OS
+ * requires a thread to perform the scheduler actions.
+ * In the future it is expected that this thread will not be necessary.
+ **/
+void * scheduler_thread_code(void *arg) {
+ fosa_ads_actions_t sched_actions;
+ struct posix_appsched_event event;
+ struct scheduler_thread_data *sch_thread_data=
+ (struct scheduler_thread_data *) arg;
+ void * scheduler_data = sch_thread_data->scheduler_data;
+ posix_appsched_eventset_t event_set;
+ fosa_abs_time_t current_time;
+ struct timespec current_time_tspec;
+ struct explicit_call_info *call_info;
+ clockid_t clk;
+ int err;
+
+ // set the clock to be used by the scheduler
+ CHK(posix_appschedattr_setclock(FOSA_CLOCK_REALTIME));
+
+ // set the timeouts to be used in the scheduler to be absolute
+ CHK(posix_appschedattr_setflags (POSIX_APPSCHED_ABSTIMEOUT));
+
+ // set the mask of events to mask all events except for those
+ // corresponding to non-null entry points
+ CHK(posix_appsched_fillset(&event_set));
+ // new_thread
+ if (sch_thread_data->scheduler_ops.new_thread!=NULL) {
+ CHK(posix_appsched_delset(&event_set,POSIX_APPSCHED_NEW));
+ }
+ // thread_terminate
+ if (sch_thread_data->scheduler_ops.thread_terminate!=NULL) {
+ CHK(posix_appsched_delset(&event_set,POSIX_APPSCHED_TERMINATE));
+ }
+ // thread_ready
+ if (sch_thread_data->scheduler_ops.thread_ready!=NULL) {
+ CHK(posix_appsched_delset(&event_set,POSIX_APPSCHED_READY));
+ }
+ // thread_block
+ if (sch_thread_data->scheduler_ops.thread_block!=NULL) {
+ CHK(posix_appsched_delset(&event_set,POSIX_APPSCHED_BLOCK));
+ }
+ // change_sched_param_thread
+ if (sch_thread_data->scheduler_ops.change_sched_param_thread!=NULL) {
+ CHK(posix_appsched_delset(&event_set, POSIX_APPSCHED_CHANGE_SCHED_PARAM));
+ }
+ // explicit_call_with_data
+ if (sch_thread_data->scheduler_ops.explicit_call_with_data!=NULL) {
+ CHK(posix_appsched_delset(&event_set, POSIX_APPSCHED_EXPLICIT_CALL));
+ }
+ // notification_for_thread
+ if (sch_thread_data->scheduler_ops.notification_for_thread!=NULL) {
+ CHK(posix_appsched_delset(&event_set,POSIX_APPSCHED_TASK_NOTIFICATION));
+ }
+ // timeout
+ if (sch_thread_data->scheduler_ops.timeout!=NULL) {
+ CHK(posix_appsched_delset(&event_set,POSIX_APPSCHED_TIMEOUT));
+ }
+ // signal
+ if (sch_thread_data->scheduler_ops.signal!=NULL) {
+ CHK(posix_appsched_delset(&event_set,POSIX_APPSCHED_SIGNAL));
+ }
+ // set the event mask
+ CHK(posix_appschedattr_seteventmask(&event_set));
+
+ // invoke the init entry point
+ sch_thread_data->scheduler_ops.init(scheduler_data,
+ sch_thread_data->init_args);
+
+ // clear the scheduling actions data structure
+ CHK(posix_appsched_actions_init(&(sched_actions.actions)));
+ sched_actions.timeout_ptr=NULL;
+ sched_actions.rejected=false;
+ sched_actions.activated=false;
+ sched_actions.suspended=false;
+
+ // lock the scheduler mutex
+ // CHK(pthread_mutex_lock(&(sch_thread_data->sch_mutex)));
+
+ // main scheduler loop
+ while (true) {
+
+ // NOTE: Put here code shared with app to be protected with the mutex
+
+ // unlock the scheduler mutex before waiting
+ // CHK(pthread_mutex_unlock(&(sch_thread_data->sch_mutex)));
+
+ // execute pending scheduling actions and wait for next event
+ err=posix_appsched_execute_actions
+ (&(sched_actions.actions),&(sch_thread_data->sch_signal_set),
+ sched_actions.timeout_ptr,¤t_time_tspec,&event);
+
+ current_time = fosa_timespec_to_abs_time(current_time_tspec);
+
+ // clear the scheduling actions data structure
+ CHK(posix_appsched_actions_destroy (&(sched_actions.actions)));
+ CHK(posix_appsched_actions_init(&(sched_actions.actions)));
+ sched_actions.timeout_ptr=NULL;
+ sched_actions.rejected=false;
+ sched_actions.activated=false;
+ sched_actions.suspended=false;
+
+ // lock the scheduler mutex to perform scheduler operations
+ // in mutual exclusion
+ // CHK(pthread_mutex_lock(&(sch_thread_data->sch_mutex)));
+
+ if (err==0) {
+ // determine which kind of event has arrived, and invoke appropriate
+ // entry point
+ switch (event.event_code) {
+ case POSIX_APPSCHED_NEW:
+ sch_thread_data->scheduler_ops.new_thread
+ (scheduler_data,
+ event.thread,
+ &sched_actions,
+ ¤t_time);
+ if (!sched_actions.rejected) {
+ // create a memory area for the explicit messages
+ call_info=(struct explicit_call_info *)
+ malloc(sizeof(struct explicit_call_info));
+ if (call_info==NULL) {
+ CHK(posix_appsched_actions_addreject
+ (&(sched_actions.actions),event.thread));
+ } else {
+ // clear actions, we need to accept the thread first
+ CHK(posix_appsched_actions_destroy (&(sched_actions.actions)));
+ CHK(posix_appsched_actions_init(&(sched_actions.actions)));
+ // accept the thread
+ CHK(posix_appsched_actions_addaccept
+ (&(sched_actions.actions),event.thread));
+ // store the memory area in thread-specific data
+ CHK(pthread_setspecific_for
+ (schedthreaddata.msg_key,event.thread,call_info));
+ // and activate or suspend the thread
+ if (sched_actions.suspended) {
+ CHK(posix_appsched_actions_addsuspend
+ (&(sched_actions.actions),event.thread));
+ } else {
+ CHK(posix_appsched_actions_addactivate
+ (&(sched_actions.actions),event.thread));
+ }
+ }
+ }
+ break;
+ case POSIX_APPSCHED_TERMINATE:
+ sch_thread_data->scheduler_ops.thread_terminate
+ (scheduler_data,
+ event.thread,
+ &sched_actions,
+ ¤t_time);
+ break;
+ case POSIX_APPSCHED_READY:
+ sch_thread_data->scheduler_ops.thread_ready
+ (scheduler_data,
+ event.thread,
+ &sched_actions,
+ ¤t_time);
+ // activate the thread unless suspended or already activated
+ if (!sched_actions.suspended && !sched_actions.activated) {
+ CHK(posix_appsched_actions_addactivate
+ (&(sched_actions.actions),event.thread));
+ }
+ break;
+ case POSIX_APPSCHED_BLOCK:
+ sch_thread_data->scheduler_ops.thread_block
+ (scheduler_data,
+ event.thread,
+ &sched_actions,
+ ¤t_time);
+ break;
+ case POSIX_APPSCHED_CHANGE_SCHED_PARAM:
+ sch_thread_data->scheduler_ops.change_sched_param_thread
+ (scheduler_data,
+ event.thread,
+ &sched_actions,
+ ¤t_time);
+ break;
+ //case POSIX_APPSCHED_EXPLICIT_CALL_WITH_DATA:
+ //sch_thread_data->scheduler_ops.explicit_call_with_data
+ // (scheduler_data,
+ // event.thread,
+ // event.event_info.info,event.info_size,
+ // &reply, &reply_size,
+ // &sched_actions,
+ // ¤t_time);
+ case POSIX_APPSCHED_EXPLICIT_CALL:
+ CHK(pthread_getspecific_from
+ (schedthreaddata.msg_key,event.thread,(void **)(&call_info)));
+ sch_thread_data->scheduler_ops.explicit_call_with_data
+ (scheduler_data,
+ event.thread,
+ call_info->info_ptr,
+ call_info->info_size,
+ call_info->reply_ptr,
+ &(call_info->reply_size),
+ &sched_actions,
+ ¤t_time);
+ // activate the thread unless suspended or already activated
+ if (!sched_actions.suspended && !sched_actions.activated) {
+ CHK(posix_appsched_actions_addactivate
+ (&(sched_actions.actions),event.thread));
+ }
+ break;
+ case POSIX_APPSCHED_TASK_NOTIFICATION:
+ clk=(clockid_t) pthread_getspecific(sch_thread_data->clock_key);
+ sch_thread_data->scheduler_ops.notification_for_thread
+ (scheduler_data,
+ event.thread,
+ clk,
+ &sched_actions,
+ ¤t_time);
+ // t.b.d. check if state of thread is suspended by default
+ break;
+ case POSIX_APPSCHED_TIMEOUT:
+ sch_thread_data->scheduler_ops.timeout
+ (scheduler_data,
+ &sched_actions,
+ ¤t_time);
+ break;
+ case POSIX_APPSCHED_SIGNAL:
+ sch_thread_data->scheduler_ops.signal
+ (scheduler_data,
+ event.event_info.siginfo.si_signo,
+ *((fosa_signal_info_t *)(&(event.event_info.siginfo.si_value))),
+ // the above casting construct is used to overcome the compiler
+ // restriction that does not allow casts between unions
+ &sched_actions,
+ ¤t_time);
+ break;
+ default:
+ ASSERT_INFO(true,"Unexpected scheduling event received in scheduler");
+ } // end switch on event code
+ } else if (err==EINVAL) {
+ sch_thread_data->scheduler_ops.appsched_error
+ (scheduler_data, event.thread,
+ FOSA_ADS_THREAD_NOT_ATTACHED, &sched_actions);
+ } else if (err==ESRCH) {
+ sch_thread_data->scheduler_ops.appsched_error
+ (scheduler_data, event.thread,
+ FOSA_ADS_INVALID_ACTION, &sched_actions);
+ }
+ } // end of main scheduler loop
+
+}
+
+/**
+ * fosa_ads_scheduler_create()
+ *
+ * Create the application defined scheduler
+ *
+ * The application defined scheduler is created with the primitive
+ * operations specified in the object pointed to by scheduler_ops.
+ *
+ * The clock used to read the time immediately before the invocation
+ * of each primitive operation, to be reported to the scheduler via
+ * the current_time parameter of each primitive operation is the
+ * FOSA_CLOCK_REALTIME clock.
+ *
+ * The scheduler_data_size parameter is used to request that a memory
+ * area of this size must be created and reserved for the scheduler to
+ * store its state. A pointer to this area is passed to the scheduler
+ * operations in the sched_data parameter.
+ *
+ * Parameter init_arg points to an area that contains configuration
+ * information for the scheduler. The function creates a memory area
+ * of init_arg_size bytes and copies into it the area pointed by
+ * arg. A pointer to this new created area will be passed to the
+ * primitive operation init() in its arg parameter.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of scheduler_ops was invalid
+ * EAGAIN: The system lacks enough resources to create the scheduler
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ *
+ * The fosa_ads_scheduler_create function must be called before any
+ * other function in this header file
+ **/
+int fosa_ads_scheduler_create
+ (const fosa_ads_scheduler_ops_t * scheduler_ops,
+ size_t scheduler_data_size,
+ void * init_args,
+ size_t init_args_size)
+{
+ pthread_attr_t attr;
+ // pthread_mutexattr_t mattr;
+ int err;
+ struct sched_param param;
+
+#ifdef FULL_ERROR_CHECKING
+ // check for NULL scheduler operations
+ if (scheduler_ops==NULL) {
+ return EINVAL;
+ }
+#endif // end if FULL_ERROR_CHECKING
+
+ // copy arguments in scheduler data
+ schedthreaddata.scheduler_ops=*scheduler_ops;
+ schedthreaddata.scheduler_data_size=scheduler_data_size;
+ schedthreaddata.init_args_size=init_args_size;
+
+ // create scheduler memory area
+ schedthreaddata.scheduler_data=malloc(scheduler_data_size);
+ if (schedthreaddata.scheduler_data==NULL) {
+ return EAGAIN;
+ }
+
+ // create init args memory area and copy the init args
+ schedthreaddata.init_args=malloc(init_args_size);
+ if (schedthreaddata.init_args==NULL) {
+ return EAGAIN;
+ }
+ memcpy(schedthreaddata.init_args,init_args,init_args_size);
+
+ // initialize the set of signals used by the scheduler to none
+ CHKE(sigemptyset(&(schedthreaddata.sch_signal_set)));
+
+ // calculate the priority
+ param.sched_priority=sched_get_priority_max(SCHED_FIFO)-
+ FOSA_ADS_SCHEDULER_PRIO_DIFF;
+
+ // initialize the mutex used to share data with the scheduler
+ // CHK(pthread_mutexattr_init(&mattr));
+ // we use the priority protect protocol
+ // CHK(pthread_mutexattr_setprotocol(&mattr,PTHREAD_PRIO_PROTECT));
+ // set priority ceiling
+ // CHK(pthread_mutexattr_setprioceiling(&mattr,param.sched_priority));
+ // initialize mutex
+ // CHK(pthread_mutex_init(&(schedthreaddata.sch_mutex),&mattr));
+ // CHK(pthread_mutexattr_destroy(&mattr));
+
+ // create the thread-specific data key for the clock id
+ CHK(pthread_key_create(&schedthreaddata.clock_key,NULL));
+
+ // create the thread-specific data key for the message pointers
+ CHK(pthread_key_create(&schedthreaddata.msg_key,NULL));
+
+ // set the attributes for the scheduler thread
+ err=pthread_attr_init(&attr);
+ if (err!=0) {
+ return err;
+ }
+ CHK(pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED));
+ CHK(pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED));
+ CHK(pthread_attr_setschedpolicy(&attr,SCHED_FIFO));
+ CHK(pthread_attr_setschedparam(&attr,¶m));
+ CHK(pthread_attr_setappschedulerstate(&attr,PTHREAD_APPSCHEDULER));
+ CHK(pthread_attr_setpreemptionlevel(&attr,FOSA_ADS_SCHEDULER_LEVEL));
+
+ // create the scheduler thread
+ return pthread_create(&scheduler_thread_id,&attr,
+ scheduler_thread_code, (void *) &schedthreaddata);
+}
+
+/**
+ * fosa_thread_attr_set_appscheduled()
+ *
+ * Set the appscheduled attribute of a thread attributes object
+ *
+ * This function is used to set the appscheduled attribute in the
+ * object pointed to by attr. This attribute controls the kind of
+ * scheduling used for threads created with it. If true, the thread is
+ * scheduled by the application scheduler. If not, it is scheduled by
+ * the system under a fixed priority scheduler
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of attr is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_set_appscheduled
+ (fosa_thread_attr_t *attr,
+ bool appscheduled)
+{
+ int error_code;
+
+ // set the application-defined scheduler thread
+ error_code=pthread_attr_setappscheduler(attr,scheduler_thread_id);
+ if (error_code!=0) return error_code;
+
+ if (appscheduled) {
+ return pthread_attr_setschedpolicy(attr,SCHED_APP);
+ } else {
+ return pthread_attr_setschedpolicy(attr,SCHED_FIFO);
+ }
+}
+
+/**
+ * fosa_thread_attr_get_appscheduled()
+ *
+ * Get the appscheduled attribute of a thread attributes object
+ *
+ * This function is used to get the appscheduled attribute in the
+ * object pointed to by attr. This attribute controls the kind of
+ * scheduling used for threads created with it. If true, the thread is
+ * scheduled by the application scheduler. If not, it is scheduled by
+ * the system under a fixed priority scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of attr is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_get_appscheduled
+ (const fosa_thread_attr_t *attr,
+ bool *appscheduled)
+{
+ int policy, ret_value;
+
+ ret_value=pthread_attr_getschedpolicy(attr,&policy);
+ if (ret_value==0) {
+ if (policy==SCHED_APP) {
+ *appscheduled=true;
+ } else {
+ *appscheduled=false;
+ }
+ }
+ return ret_value;
+}
+
+/**
+ * fosa_thread_attr_set_appsched_params()
+ *
+ * Set the appsched_param attribute of a thread attributes object
+ *
+ * This function is used to set the appsched_param attribute in the
+ * object pointed to by attr. For those threads with appscheduled set
+ * to true, this attribute represents the application-specific
+ * scheduling parameters. If successful, the function shall set the
+ * size of the appsched_param attribute to the value specified by
+ * paramsize, and shall copy the scheduling parameters occupying
+ * paramsize bytes and pointed to by param into that attribute
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of attr is invalid, or paramsize is less than
+ * zero or larger than FOSA_ADS_SCHEDPARAM_MAX
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_set_appsched_params
+ (fosa_thread_attr_t *attr,
+ const void *param,
+ size_t paramsize)
+{
+ return pthread_attr_setappschedparam(attr,param,paramsize);
+}
+
+/**
+ * fosa_thread_attr_get_appsched_params()
+ *
+ * Get the appsched_param attribute of a thread attributes object
+ *
+ * This function is used to get the appsched_param attribute from the
+ * object pointed to by attr. For those threads with appscheduled set
+ * to true, this attribute represents the application-specific
+ * scheduling parameters. If successful, the function shall set the
+ * value pointed to by paramsize to the size of the appsched_param
+ * attribute, and shall copy the scheduling parameters occupying
+ * paramsize bytes into the variable pointed to by param. This
+ * variable should be capable of storing a number of bytes equal to
+ * paramsize.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of attr is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_get_appsched_params
+ (const fosa_thread_attr_t *attr,
+ void *param,
+ size_t *paramsize)
+{
+ return pthread_attr_getappschedparam(attr,param,paramsize);
+}
+
+/**
+ * fosa_ads_set_appscheduled()
+ *
+ * Dynamically set the appscheduled attribute of a thread
+ *
+ * This function is used to dynamically set the appscheduled attribute
+ * of the thread identified by thread. This attribute controls the
+ * kind of scheduling used for threads created with it. If true, the
+ * thread is scheduled by the application scheduler. If not, it is
+ * scheduled by the system under a fixed priority scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of thread is invalid
+ *
+ * EREJECT: the attachment of the thread to the frsh schehduler
+ * was rejected by the frsh scheduler possibly because of
+ * incorrect attributes, or because the requested minimum
+ * capacity cannot be guaranteed
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_set_appscheduled
+ (fosa_thread_id_t thread,
+ bool appscheduled)
+{
+ int error_code = 0;
+ int current_policy, new_policy;
+ struct sched_param param;
+
+ // switch to the appropriate scheduling policy
+ CHK(pthread_getschedparam(thread,¤t_policy,¶m));
+ if (((current_policy==SCHED_APP) && (!appscheduled)) ||
+ ((current_policy!=SCHED_APP) && appscheduled)) {
+ if (appscheduled) {
+ new_policy=SCHED_APP;
+ // set the application-defined scheduler thread
+ error_code=pthread_setappscheduler(thread,scheduler_thread_id);
+ if (error_code!=0) return error_code;
+ } else {
+ new_policy=SCHED_FIFO;
+ }
+ error_code=pthread_setschedparam(thread,new_policy,¶m);
+ }
+ return error_code;
+}
+
+/**
+ * fosa_ads_getappscheduled()
+ *
+ * Dynamically get the appscheduled attribute of a thread
+ *
+ * This function is used to dynamically get the appscheduled attribute
+ * of the thread identified by thread. This attribute controls the
+ * kind of scheduling used for threads created with it. If true, the
+ * thread is scheduled by the application scheduler. If not, it is
+ * scheduled by the system under a fixed priority scheduler
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of thread is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_get_appscheduled
+ (fosa_thread_id_t thread,
+ bool *appscheduled)
+{
+ int error_code, policy;
+ struct sched_param param;
+
+ error_code=pthread_getschedparam(thread,&policy,¶m);
+ if (error_code!=0) {
+ return error_code;
+ } else {
+ *appscheduled = (policy==SCHED_APP);
+ return 0;
+ }
+}
+
+
+/**
+ * fosa_ads_setappschedparam()
+ *
+ * Dynamically set the appsched_param attribute of a thread
+ *
+ * This function is used to dynamically set the appsched_param
+ * attribute of the thread identified by thread. For those threads
+ * with appscheduled set to true, this attribute represents the
+ * application-specific scheduling parameters. If successful, the
+ * function shall set the size of the appsched_param attribute to the
+ * value specified by paramsize, and shall copy the scheduling
+ * parameters occupying paramsize bytes and pointed to by param into
+ * that attribute
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of thread is invalid, or paramsize is less than
+ * zero or larger than FOSA_ADS_SCHEDPARAM_MAX
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_set_appsched_params
+ (fosa_thread_id_t thread,
+ const void *param,
+ size_t paramsize)
+{
+ return pthread_setappschedparam(thread,param,paramsize);
+}
+
+/**
+ * fosa_ads_get_appsched_params()
+ *
+ * Dynamically get the appsched_param attribute of a thread
+ *
+ * This function is used to dynamically get the appsched_param
+ * attribute of the thread identified by thread. For those threads
+ * with appscheduled set to true, this attribute represents the
+ * application-specific scheduling parameters. If successful, the
+ * function shall set the variable pointed to by paramsize to the size
+ * of the appsched_param attribute, and shall copy the scheduling
+ * parameters occupying paramsize bytes into the variable pointed to
+ * by param. This variable should be capable of storing a number of
+ * bytes equal to paramsize.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of thread is invalid, or paramsize is less than
+ * zero or larger than FOSA_ADS_SCHEDPARAM_MAX
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications.
+ **/
+int fosa_ads_get_appsched_params
+ (fosa_thread_id_t thread,
+ void *param,
+ size_t *paramsize)
+{
+ return pthread_getappschedparam(thread,param,paramsize);
+}
+
+
+/*********************************
+ * ADS actions
+ *
+ * A scheduling actions object is used to specify a series of actions
+ * to be performed by the system at the end of a scheduler primitive
+ * operation. The order of the actions added to the object shall be
+ * preserved.
+ *
+ *********************************/
+
+/**
+ * fosa_adsactions_add_reject()
+ *
+ * Add a reject-thread action
+ *
+ * This function adds a thread-reject action to the object referenced
+ * by sched_actions, that will serve to notify that the thread
+ * identified by thread has not been accepted by the scheduler to be
+ * scheduled by it, possibly because the thread contained invalid
+ * application scheduling attributes, or because there are not enough
+ * resources for the new thread. At the end of the new_thread()
+ * scheduler primitive operation, the parent of the rejected thread
+ * waiting on a fosa_thread_create() or the rejected thread itself
+ * waiting on a fosa_ads_set_appscheduled() function shall complete the
+ * function with an error code of EREJECT. If no reject-thread action
+ * is added during the new_thread() scheduler primitive operation, the
+ * thread is accepted to be scheduled by the scheduler and the
+ * associated fosa_thread_create() or the fosa_ads_set_appscheduled()
+ * function shall be completed without error. For the function to
+ * succeed, it has to be called from the new_thread() primitive
+ * operation and for the thread that is requesting attachment to the
+ * scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * ENOMEM: There is insufficient memory to add this action
+ * FOSA_EPOLICY: The thread specified by thread is not the one requesting
+ * attachment to the scheduler, or the function is not being
+ * called from the new_thread primitive operation
+ * EINVAL: The value specified by sched_actions is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_reject(
+ fosa_ads_actions_t *sched_actions,
+ fosa_thread_id_t thread)
+{
+#ifdef FULL_ERROR_CHECKING
+ // check errors
+ if (!pthread_equal(pthread_self(),scheduler_thread_id)) {
+ return FOSA_EPOLICY;
+ }
+#endif // end if FULL_ERROR_CHECKING
+ sched_actions->rejected=true;
+ return posix_appsched_actions_addreject(&(sched_actions->actions),thread);
+}
+
+/**
+ * fosa_adsactions_add_activate()
+ *
+ * Add a thread-activate action
+ *
+ * This function adds a thread-activate action to the object
+ * referenced by sched_actions. In case the thread had been previously
+ * suspended via posix_appsched_actions_addsuspend(), it will be
+ * activated at the end of the primitive operation.
+ *
+ * In those implementations that do not support urgency scheduling,
+ * the urgencu value is ignored. These implementations cannot support
+ * the frsh hierarchical scheduling module.
+ *
+ * In those implementations supporting urgency-scheduling, the action
+ * will cause the change of the urgency of the thread to the value
+ * specified in the urgency argument. Besides, if the thread was
+ * already active at the time the thread-activate action is executed,
+ * the change or urgency will imply a reordering of the thread in its
+ * priority queue, so that for threads of the same priority, those
+ * with more urgency will be scheduled before those of less urgency.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * ENOMEM: There is insufficient memory to add this action
+ * FOSA_EPOLICY: The thread specified by thread has its appscheduled
+ * attribute set to false,
+ * EINVAL: The value specified by sched_actions is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_activate(
+ fosa_ads_actions_t *sched_actions,
+ fosa_thread_id_t thread,
+ fosa_ads_urgency_t urgency)
+{
+ sched_actions->activated=true;
+ return posix_appsched_actions_addactivate(&(sched_actions->actions),thread);
+}
+
+/**
+ * fosa_adsactions_add_suspend()
+ *
+ * Add a thread-suspend action
+ *
+ * This function adds a thread-suspend action to the object referenced
+ * by sched_actions, that will cause the thread identified by thread
+ * to be suspended waiting for a thread-activate action at the end of
+ * the scheduler operation. If the thread was already waiting for a
+ * thread-activate action the thread-suspend action has no effect. It
+ * is an error trying to suspend a thread that is blocked by the
+ * operating system.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * ENOMEM: There is insufficient memory to add this action
+ * FOSA_EPOLICY: The thread specified by thread has its appscheduled
+ * attribute set to false,
+ * EINVAL: The value specified by sched_actions is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_suspend(
+ fosa_ads_actions_t *sched_actions,
+ fosa_thread_id_t thread)
+{
+ sched_actions->suspended=true;
+ return posix_appsched_actions_addsuspend(&(sched_actions->actions),thread);
+}
+
+/**
+ * fosa_adsactions_add_timeout()
+ *
+ * Add a timeout action
+ *
+ * This function adds a timeout action to the object referenced by
+ * sched_actions, that will cause the timeout() scheduler operation to
+ * be invoked if no other scheduler operation is invoked before
+ * timeout expires. The timeout shall expire when the clock specified by
+ * clock_id reaches the absolute time specified by the at_time
+ * argument.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * ENOMEM: There is insufficient memory to add this action
+ * EINVAL: The value specified by sched_actions is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_timeout(
+ fosa_ads_actions_t *sched_actions,
+ fosa_clock_id_t clock_id,
+ const fosa_abs_time_t *at_time)
+{
+ sched_actions->timeout= fosa_abs_time_to_timespec(*at_time);
+ sched_actions->timeout_ptr=&(sched_actions->timeout);
+ return 0;
+}
+
+/**
+ * fosa_adsactions_add_thread_notification()
+ *
+ * Add a timed-thread-notification action
+ *
+ * This function adds a thread-notification action associated with the
+ * thread specified in the thread argument that will cause the
+ * notification_for_thread() scheduler operation to be invoked at the
+ * time specified by at_time. This operation shall be invoked when the
+ * clock specified by clock_id reaches the absolute time specified by
+ * the at_time argument. In particular, a cpu-time clock may be used
+ * for parameter clock_id.Only one thread-notification can be active
+ * for each thread and clock. Calling the function shall remove the
+ * former thread-notification, if any, that had been programmed for
+ * the same thread and clock. A value of NULL for parameter at_time is
+ * used to cancel a previous thread-notification, if any, for the
+ * thread specified by thread and the clock specified by clock_id.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * ENOMEM: There is insufficient memory to add this action
+ * FOSA_EPOLICY: The thread specified by thread has its appscheduled
+ * attribute set to false,
+ * EINVAL: The value specified by sched_actions is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_thread_notification(
+ fosa_ads_actions_t *sched_actions,
+ fosa_thread_id_t thread,
+ fosa_clock_id_t clock_id,
+ const fosa_abs_time_t *at_time)
+{
+#ifdef FULL_ERROR_CHECKING
+ // check errors
+ struct sched_param param;
+ int policy;
+
+ CHK(pthread_getschedparam(thread,&policy,¶m));
+ if (policy!=SCHED_APP) {
+ return FOSA_EPOLICY;
+ }
+#endif // end if FULL_ERROR_CHECKING
+
+ // the implementation uses a timer that generates a signal
+ // with the thread id encoded in the signal info
+ // the clock id is stored in thread-specific data
+
+ // store the clock id in thread-specific data
+ CHK(pthread_setspecific(schedthreaddata.clock_key,(void *) clock_id));
+
+ // t.b.d. this function is currently not used,
+ // therefore we don't implement it yet
+ return ENOSYS;
+}
+
+
+/**
+ * fosa_ads_set_handled_signal_set()
+ *
+ * Specifiy the set of signals that will be handled by the application
+ * scheduler
+ *
+ * This function is used to dynamically set the set of signals that
+ * are handled by the application scheduler. When a signal included
+ * in this set is generated, the signal() primitive operation of the
+ * application scheduler shall be executed. When a signal in tis set
+ * is generated, it shall always imply the execution of the signal()
+ * primitive operation, regardless of whether that signal could be
+ * accepted by some other thread. Once the signal() primitive
+ * operation is executed the signal is consumed, so no signal handlers
+ * shall be executed and no threads using a sigwait operation shall
+ * return for that particular signal instance. For this function to
+ * succeed, it has to be called from a primitive operation of a
+ * scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EPOLICY: The function has not been called from a scheduler
+ * primitive operation
+ * EINVAL: The value specified by set is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_set_handled_signal_set(fosa_signal_t set[], int size)
+{
+ int i;
+
+#ifdef FULL_ERROR_CHECKING
+ // check errors
+ if (!pthread_equal(pthread_self(),scheduler_thread_id)) {
+ return FOSA_EPOLICY;
+ }
+#endif // end if FULL_ERROR_CHECKING
+ // empty the signal set
+ CHKE(sigemptyset(&(schedthreaddata.sch_signal_set)));
+ // loop for all signals in set, to add them to the set of signals used
+ // by the scheduler
+ for(i=0;i<size;i++) {
+ CHKE(sigaddset(&(schedthreaddata.sch_signal_set),set[i]));
+ }
+ return 0;
+}
+
+
+/**
+ * fosa_signal_queue_scheduler()
+ *
+ * Queue a signal destinated to the scheduler
+ *
+ * This is a special case of fosa_signal_queue() in which the
+ * destinator is the scheduler itself. It is needed by the service
+ * thread to notify the results to the scheduler.
+ *
+ * The problem with this case is that, depending on the implementation,
+ * this call would be translated to a true signal or to a scheduler
+ * notification message.
+ *
+ * Besides for the scheduler we don't have always a destinator
+ * thread_id needed in fosa_signal_queue for OSE.
+ *
+ * So the fosa implementation will solve this issue internally.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the signal specified by signal is not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX
+ *
+ * FOSA_EAGAIN: no resources are available to queue the signal; the
+ * maximum number of queued signals has been reached, or a
+ * systemwide resource limit has been exceeded
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_signal_queue_scheduler(fosa_signal_t signal, fosa_signal_info_t info)
+{
+ // In MaRTE OS this function is completely equivalent to
+ // fosa_signal_queue, because there is no notion of receiver.
+ fosa_thread_id_t receiver = 0; // Dummy value, not used by MaRTE OS
+ return fosa_signal_queue(signal, info, receiver);
+}
+
+/**
+ * fosa_ads_invoke_withdata()
+ *
+ * Explicitly invoke the scheduler, with data
+ *
+ * This function can be used by any thread in the process to invoke
+ * the ads scheduler or to share data with it.
+ *
+ * If successful, the function shall cause the execution of the
+ * primitive operation explicit_call_with_data() of the ads scheduler
+ * with its thread parameter equal to the thread ID of the calling
+ * thread, and its msg_size parameter equal to msg_size. In addition,
+ * if msg_size is larger than zero, the function shall make available
+ * to the scheduler a memory area whose contents are identical to the
+ * memory area pointed to by msg in the msg parameter of the
+ * explicit_call_with_data() primitive operation (note that copying
+ * the information is not needed).
+ *
+ * The function shall not return until the system has finished
+ * execution of the explicit_call_with_data() primitive operation. If
+ * the reply argument is non NULL, the memory area pointed to by the
+ * reply parameter of explicit_call_with_data() primitive operation is
+ * copied into the memory area pointed to by reply, and its size is
+ * copied into the variable pointed to by reply_size. The size of the
+ * reply information is limited to the value FOSA_ADS_SCHEDINFO_MAX.
+ *
+ * The function shall fail if the size specified by msg_size is larger
+ * than FOSA_ADS_SCHEDINFO_MAX. The function shall fail if primitive
+ * operation explicit_call_with_data() is set to NULL for the ads
+ * scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EPOLICY: The function been called from inside a scheduler
+ * primitive operation
+ * EINVAL: The value of msg_size is less than zero or larger than
+ * FOSA_ADS_SCHEDINFO_MAX
+ * FOSA_EMASKED: The operation cannot be executed because the primitive
+ * operation explicit_call_with_data() is set to NULL
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_invoke_withdata
+ (const void *msg, size_t msg_size, void *reply, size_t *reply_size)
+{
+ // The corresponding function in MaRTE OS is not yet implemented
+ // We implement this function by creating a memory area for each thread
+ // and using the invoke with no data function
+ struct explicit_call_info * call_info;
+ int error_code;
+
+#ifdef FULL_ERROR_CHECKING
+ // check errors
+ if (pthread_equal(pthread_self(),scheduler_thread_id)) {
+ return FOSA_EPOLICY;
+ }
+ if (msg_size>FOSA_ADS_SCHEDINFO_MAX) {
+ return EINVAL;
+ }
+ if (schedthreaddata.scheduler_ops.explicit_call_with_data==NULL) {
+ return FOSA_EMASKED;
+ }
+#endif // end if FULL_ERROR_CHECKING
+
+ call_info = (struct explicit_call_info *)
+ pthread_getspecific(schedthreaddata.msg_key);
+ ASSERT_INFO(call_info!=NULL,
+ "Error in access to specific data for explicit call");
+ if (call_info==NULL) return EINVAL;
+ call_info->info_size=msg_size;
+ // the following type cast is to avoid warnings, but should be OK
+ call_info->info_ptr=(void *)msg;
+ call_info->reply_ptr=reply;
+ error_code=posix_appsched_invoke_scheduler(0);
+ if (reply != NULL) {
+ *reply_size=call_info->reply_size;
+ }
+ return error_code;
+}
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_clocks_and_timers.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+
+#include <pthread.h>
+#include <time.h>
+#include <stdio.h>
+
+#include "fosa_time.h"
+#include "fosa_clocks_and_timers.h"
+
+static const struct timespec zero_time={0,0};
+
+
+/*************************
+ * Timing: Clocks
+ *************************/
+
+/**
+ * fosa_get_time()
+ *
+ * Get the time from a clock
+ *
+ * This function sets the variable pointed to by current_time to the
+ * current value of the clock specified by clockid, which may be the
+ * FOSA_CLOCK_REALTIME constant or a value obtained with
+ * fosa_get_cputime_clock()
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of clockid is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_clock_get_time(fosa_clock_id_t clockid, fosa_abs_time_t *current_time)
+{
+ struct timespec current_time_tspec;
+ int ret_value;
+
+ ret_value = clock_gettime(clockid, ¤t_time_tspec);
+ *current_time = fosa_timespec_to_abs_time(current_time_tspec);
+
+ return ret_value;
+}
+
+
+/**
+ * fosa_get_cputime_clock()
+ *
+ * Get the identifier of a cpu-time clock
+ *
+ * This function stores in the variable pointed to by clockid the
+ * identifier of a cpu-time clock for the thread specified by tid.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of tid is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_get_cputime_clock
+ (fosa_thread_id_t tid, fosa_clock_id_t *clockid)
+{
+ return pthread_getcpuclockid(tid,clockid);
+}
+
+
+/*************************
+ * Timing: Timers
+ *************************/
+
+/**
+ * fosa_create_timer()
+ *
+ * Create a one-shot timer
+ *
+ * This function creates a timer based on the clock specified by clock,
+ * and associates to this timer a notification mechanism consisting of
+ * a signal and associated information. Initially, the timer is in the
+ * disarmed state, i.e., not counting time. It can be armed to start
+ * counting time with fosa_timer_arm().
+ *
+ * The function stores the identifier of the newly created timer in the
+ * variable pointed to by timerid.
+ *
+ * When the timer expires, the signal number specified by signal will be
+ * sent together with the information specified by info, to the thread
+ * that armed the timer (@see fosa_timer_arm()).
+ *
+ * In those implementations that do not support queueing a
+ * signal with information to a thread (such as POSIX), the signal may
+ * be sent to any thread that is waiting for this signal via
+ * fosa_signal_wait(). Portability can be ensured by having the receiver
+ * thread be the one who is waiting for the signal.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of clockid or signal is invalid
+ *
+ * EAGAIN: the system lacks enough resources to create the timer
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+ int fosa_timer_create
+ (fosa_clock_id_t clockid, fosa_signal_t signal, fosa_signal_info_t info,
+ fosa_timer_id_t *timerid)
+{
+ struct sigevent evp;
+ evp.sigev_notify=SIGEV_SIGNAL;
+ evp.sigev_signo=signal;
+ evp.sigev_value=* ((union sigval *) &info);
+ // the above casting construct is used to overcome the compiler
+ // restriction that does not allow casts between unions
+ return timer_create(clockid,&evp,timerid);
+}
+
+/**
+ * fosa_timer_create_with_receiver()
+ *
+ * Create a one-shot timer with a specific signal receiver thread
+ *
+ * This function creates a timer in the same way as fosa_timer_create,
+ * except that the signal generated when the timer expires is sent to
+ * the thread specified by receiver
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of clockid or signal is invalid
+ *
+ * FOSA_EAGAIN: the system lacks enough resources to create the timer
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+ int fosa_timer_create_with_receiver
+ (fosa_clock_id_t clockid, fosa_signal_t signal, fosa_signal_info_t info,
+ fosa_timer_id_t *timerid, fosa_thread_id_t receiver)
+{
+ // in POSIX the receiver thread cannot be specified
+ return fosa_timer_create(clockid,signal,info,timerid);
+}
+
+
+/**
+ * Delete a timer
+ *
+ * The function deletes the timer specified by timerid, which becomes
+ * unusable. If the timer was armed, it is automatically disarmed before
+ * deletion.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of timerid is not valid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_timer_delete(fosa_timer_id_t timerid)
+{
+ return timer_delete(timerid);
+}
+
+
+/**
+ * fosa_rel_timer_arm()
+ *
+ * Arm a timer with a relative time interval
+ *
+ * The timer specified by timer is armed and starts counting time.
+ *
+ * The value pointed to by value is the relative interval that must
+ * elapse for the timer to expire. Negative values cause the timer to
+ * expire immediately.
+ *
+ * The time is measured with the clock associated with the timer when
+ * it was created.
+ *
+ * If the timer was already armed, the previous time or interval is discarded
+ * and the timer is rearmed with the new value.
+ *
+ * When the timer expires, it is disarmed.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of timerid or value is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_rel_timer_arm
+ (fosa_timer_id_t timerid, const fosa_rel_time_t *value)
+{
+ struct itimerspec timer_value;
+
+ // set the timer to the specified value, one shot only
+ timer_value.it_value= fosa_rel_time_to_timespec(*value);
+ timer_value.it_interval=zero_time;
+
+ // arm the timer
+ return timer_settime(timerid, 0, &timer_value,NULL);
+}
+
+
+/**
+ * fosa_abs_timer_arm()
+ *
+ * Arm a timer that will expire in an absolute time instant.
+ *
+ * The timer specified by timer is armed and starts counting time.
+ *
+ * The value pointed to by value is the absolute time at which the
+ * timer will expire. If value specifies a time instant in the past,
+ * the timer expires immediately.
+ *
+ * The time is measured with the clock associated with the timer when
+ * it was created.
+ *
+ * If the timer was already armed, the previous time or interval is discarded
+ * and the timer is rearmed with the new value.
+ *
+ * When the timer expires, it is disarmed.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of timerid or value is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_abs_timer_arm
+ (fosa_timer_id_t timerid, const fosa_abs_time_t *value)
+{
+ struct itimerspec timer_value;
+
+ // set the timer to the specified value, one shot only
+ timer_value.it_value= fosa_abs_time_to_timespec(*value);
+ timer_value.it_interval=zero_time;
+
+ // arm the timer
+ return timer_settime(timerid, TIMER_ABSTIME,&timer_value,NULL);
+}
+
+
+
+
+/**
+ * fosa_timer_get_remaining_time()
+ *
+ * Get the remaining time for timer expiration
+ *
+ * Returns the relative remaining time for timer expiration. If the
+ * clock is a CPU clock it returns the time as if the thread was
+ * executing constantly.
+ *
+ * If the timer is disarmed it returns 0.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of timerid or value is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_timer_get_remaining_time
+ (fosa_timer_id_t timerid, fosa_rel_time_t *remaining_time)
+{
+ struct itimerspec timer_value;
+ int error_code;
+
+ if (remaining_time == NULL) {
+ return EINVAL;
+ }
+ error_code=timer_gettime(timerid,&timer_value);
+ if (error_code==-1) return errno;
+
+ *remaining_time = fosa_timespec_to_rel_time(timer_value.it_value);
+
+ return 0;
+}
+
+/**
+ * fosa_timer_disarm()
+ *
+ * Disarm a timer
+ *
+ * The timer specified by timer is disarmed, and will not expire unless
+ * it is rearmed. If the timer was already disramed, the function has
+ * no effect.
+ *
+ * If the pointer remaining_time is != NULL, the remaining time before
+ * expiration will be returned in that pointer. If the timer was
+ * disarmed a 0 value will be set.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of timerid or value is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_timer_disarm
+ (fosa_timer_id_t timerid,
+ fosa_rel_time_t *remaining_time)
+{
+ struct itimerspec timer_value;
+ int error_code;
+
+ if (remaining_time!=NULL) {
+ error_code=timer_gettime(timerid,&timer_value);
+ if (error_code==-1) return errno;
+ *remaining_time = fosa_timespec_to_rel_time(timer_value.it_value);
+ }
+ timer_value.it_value=zero_time;
+ timer_value.it_interval=zero_time;
+ return timer_settime(timerid,0,&timer_value,NULL);
+}
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_group_clocks.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+
+#include <thread_sets.h>
+
+#include "fosa_group_clocks.h"
+
+/**
+ * fosa_thread_set_create()
+ *
+ * Create an empty thread set and return an identifier
+ *
+ * This function stores in the variable pointed to by set the
+ * identifier of a thread set that is created by the function.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EAGAIN: no resources are currently available to create the
+ * thread set
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_set_create(fosa_thread_set_id_t *set)
+{
+ int error;
+
+ error = marte_threadset_create( (marte_thread_set_t *) set);
+
+ return error;
+}
+
+
+/**
+ * fosa_thread_set_destroy()
+ *
+ * Destroy a thread set
+ *
+ * This function destroys the thread set identified by set. The
+ * threads that were in the set are detached from the set. It is
+ * an error to use the identifier after this call. The effects of
+ * using a CPU-time clock associated with the destroyed thread are
+ * undefined.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: set is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_set_destroy(fosa_thread_set_id_t set)
+{
+ int error;
+
+ error = marte_threadset_destroy(set);
+
+ return error;
+}
+
+
+/**
+ * fosa_thread_set_add()
+ *
+ * Add a thread to a thread set
+ *
+ * This function adds the thread identified with thread_id to the
+ * thread set identified by set.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: set is invalid
+ * FOSA_ENOTSUP: thread already a member of some other set
+ * FOSA_EAGAIN: no resources available to add the new thread
+ * FOSA_ESRCH: thread_id doesn't identify a valid thread
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_set_add(fosa_thread_set_id_t set,
+ fosa_thread_id_t thread_id)
+{
+ int error;
+
+ error = marte_threadset_add(set, thread_id);
+
+ return error;
+}
+
+
+/**
+ * fosa_thread_set_del()
+ *
+ * Delete a thread from a thread set
+ *
+ * This function deletes the thread identified with thread_id from
+ * the thread set identified by set.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: set is invalid
+ * FOSA_EINVAL: thread is not a member of the set
+ * FOSA_ESRCH: thread_id doesn't identify a valid thread
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+
+int fosa_thread_set_del(fosa_thread_set_id_t set,
+ fosa_thread_id_t thread_id)
+{
+ int error;
+
+ error = marte_threadset_del(set, thread_id);
+
+ return error;
+}
+
+
+/**
+ * fosa_get_groupcpu_clock()
+ *
+ * Get the identifier of a cpu-time clock associated to a thread
+ * set
+ *
+ * This function stores in the variable pointed to by clockid the
+ * identifier of a cpu-time clock for the thread set specified
+ * by set.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the set is invalid
+ * FOSA_EINVAL: clock_id is a null pointer
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_get_groupcpu_clock(const fosa_thread_set_id_t set,
+ fosa_clock_id_t *clock_id)
+{
+ int error;
+
+ error = marte_getgroupcpuclockid(set, clock_id);
+ return error;
+}
+
+
+
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_long_jump.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "fosa.h"
+#include <misc/marte_non_local_jmp.h>
+
+/**
+ * Global variables
+ */
+
+static int handler_installed=0;
+static fosa_thread_id_t handler_tid;
+
+/**
+ * fosa_long_jump_save_context
+ *
+ * Save the context of the current thread for a future long jump
+ *
+ * This function stores in context the information required to modify
+ * the stack of the calling thread so that a later long jump may be
+ * executed in the future to restore this context
+ *
+ * This function stores in 'context' the registers and the stack
+ * frame of the calling thread. This information can be used by
+ * 'restorecontext' to change the stack of the task so that when it
+ * is scheduled again it returns to the end of this function
+ *
+ * Depending on the underlying implementation, the first invocation
+ * of this function for a given thread may also install a signal
+ * handler or a signal handler thread that is capable of executing
+ * the actions required to restore the context of a thread from the
+ * appropriate context. For instance, in POSIX it is necesaray that
+ * the context is restored from the same thread being restored,
+ * usually from a signal handler of that thread.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of context is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ */
+int fosa_long_jump_save_context
+ (fosa_long_jump_context_t * context)
+{
+ if (context==NULL) {
+ return FOSA_EINVAL;
+ } else {
+ marte_nonlocaljmp_savecontext (&(context->marte_context));
+ context->tid=pthread_self();
+ return 0;
+ }
+}
+
+
+/**
+ * fosa_long_jump_was_performed
+ *
+ * Check whether the current thread suffered a long jump or not
+ *
+ * This function should be invoked after fosa_long_jump_save_context
+ * to determine whether the current thread is executing normally, or
+ * has suffered a long jump to the point where the context was
+ * saved. If invoked after a direct invocation to
+ * fosa_long_jump_save_context, the function shall return 0. If
+ * invoked after returning from fosa_long_jump_save_context due to a
+ * call to fosa_long_jump_restore_context, the function shall return
+ * 1.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of context is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ */
+int fosa_long_jump_was_performed
+(const fosa_long_jump_context_t * context, int * jumped)
+{
+ if (context==NULL) {
+ return FOSA_EINVAL;
+ } else {
+ *jumped=marte_nonlocaljmp_afterjmp (&(context->marte_context));
+ return 0;
+ }
+}
+
+
+/**
+ * Body of the long-jump handler thread
+ */
+
+void * fosa_long_jump_handler (void * arg) {
+
+ fosa_signal_t set[1];
+ fosa_signal_t sig;
+ fosa_signal_info_t siginfo;
+
+ fosa_long_jump_context_t *info;
+
+ // initialize signal handling
+ set[0]=FOSA_LONG_JUMP_SIGNAL;
+ if (fosa_set_accepted_signals(set, 1) !=0) {
+ printf("FOSA_ERR_INTERNAL_ERROR, Error setting the signal mask\n");
+ exit(1);
+ }
+
+ // main thread loop
+ while (1) {
+ // Wait for a budget overrun signal
+ if ((fosa_signal_wait(set, 1, &sig, &siginfo)) == -1) {
+ printf("FOSA_ERR_INTERNAL_ERROR, signal wait in long jump handler\n");
+ exit(1);
+ }
+ // Restore thread's context
+ info=((fosa_long_jump_context_t*) (siginfo.sival_ptr));
+ marte_nonlocaljmp_restorecontext(info->tid,&(info->marte_context));
+ }
+}
+
+
+
+/**
+ * fosa_long_jump_install_handler
+ *
+ * Install a long jump handler for the calling thread
+ *
+ * This function shall install a handler that is capable of causing a
+ * long jump operation that restores the context of a thread to a
+ * previously saved value. If the handler has already been installed
+ * for this thread the previously installed handler will be used and
+ * the call shall succeed.
+ *
+ * The long-jump handler is waiting for a signal to notify that a
+ * thread context should be restored. This signal must carry attached
+ * to it a pointer to the variable where the thread context was
+ * saved. The thread referenced in that context will have its
+ * internal context restored to the point where it was saved. For
+ * this restore operation to work properly, the program frame where
+ * the thread saved its context must still be valid.
+ *
+ * Depending on the implementation a given thread may also install a signal
+ * handler or a signal handler thread that is capable of executing
+ * the actions required to restore the context of a thread from the
+ * appropriate context. For instance, in POSIX it is necesaray that
+ * the context is restored from the same thread being restored,
+ * usually from a signal handler of that thread.
+ *
+ * The function shall store in the variable pointed to by signal the
+ * identifier of the signal that must be used to notify the request
+ * for a long jump to be executed. In the variable pointed to by
+ * handler, it shall store the thread id to which the signal must be
+ * sent. The signal must be sent with its attached information set to
+ * a pointer to the variable of type fosa_long_jump_context_t where
+ * the context of the thread to be restored was saved.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the value of context is invalid
+ * FOSA_ENOMEM: there are no resources to satisfy the call at this time
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ */
+int fosa_long_jump_install_handler
+(fosa_signal_t *signal, fosa_thread_id_t *handler)
+{
+ fosa_thread_attr_t attr;
+ int err;
+
+ if (!handler_installed) {
+
+ handler_installed=1;
+
+ //////////////////////////////////////////////////
+ // create the long jump handler thread
+ //////////////////////////////////////////////////
+
+ // Create the thread attributes object
+ err=fosa_thread_attr_init (&attr);
+ if (err != 0) {
+ printf("Error while initializing the attributes\n");
+ return err;
+ }
+
+ // set the maximum priority level for the handler
+ err=fosa_thread_attr_set_prio (&attr,fosa_get_priority_max());
+ if (err != 0) {
+ printf("Error while setting schedparam\n");
+ return err;
+ }
+
+ /* create the signal handler thread */
+ err = fosa_thread_create(&handler_tid, &attr,
+ fosa_long_jump_handler, NULL);
+ if (err) {
+ printf("pthread_create signal handler\n");
+ return err;
+ }
+
+ // destroy the thread attributes object
+ err=fosa_thread_attr_destroy (&attr);
+ if (err != 0) {
+ printf("Error while destroying the attributes\n");
+ return err;
+ }
+
+ } // if handler not installed
+
+ // return handler and signal information
+ *handler=handler_tid;
+ *signal=FOSA_LONG_JUMP_SIGNAL;
+ return 0;
+
+}
+
+
+
+/*@}*/
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_mutexes_and_condvars.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include "fosa_mutexes_and_condvars.h"
+
+#include <pthread.h>
+#include <stdio.h>
+
+#include <misc/error_checks.h>
+
+#include "fosa_time.h"
+
+/*******************************************************
+ * Mutexes with priority ceiling
+ ******************************************************/
+
+/**
+ * fosa_mutex_init()
+ *
+ * Initialize a frsh mutex
+ *
+ * The mutex pointed to by mutex is initialized as a mutex using
+ * the priority ceiling protocol. A priority ceiling of prioceiling
+ * is assigned to this mutex.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of prioceiling is invalid
+ * EAGAIN: the system lacked the necessary resources to create the mutex
+ * ENOMEM: Insufficient memory exists to initialize the mutex
+ * EBUSY: The system has detected an attempt to reinitialize the mutex
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_mutex_init(fosa_mutex_t *mutex, int prioceiling)
+{
+ pthread_mutexattr_t attr;
+ int ret_value;
+
+ // create the attributes object and set the mutex to use the
+ // priority ceiling protocol and the desired priority ceiling
+ ret_value=pthread_mutexattr_init(&attr);
+ if (ret_value!=0) return ret_value;
+
+ CHK(pthread_mutexattr_setprotocol(&attr,PTHREAD_PRIO_PROTECT));
+ ret_value=pthread_mutexattr_setprioceiling(&attr,prioceiling);
+
+ if (ret_value==0) {
+ // create the mutex
+ ret_value=pthread_mutex_init(mutex,&attr);
+ }
+ // destroy the mutex attributes object
+ pthread_mutexattr_destroy(&attr);
+
+ return ret_value;
+}
+
+/**
+ * fosa_mutex_destroy()
+ *
+ * Destroy a frsh mutex
+ *
+ * The mutex pointed to by mutex is destroyed
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of mutex is invalid
+ * EBUSY: The mutex is in use (is locked)
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_mutex_destroy(fosa_mutex_t *mutex)
+{
+ return pthread_mutex_destroy(mutex);
+}
+
+/**
+ * fosa_mutex_set_prioceiling()
+ *
+ * Dynamically set the priority ceiling of a mutex
+ *
+ * This function locks the mutex (blocking the calling thread if
+ * necessary) and after it is locked it changes its priority ceiling
+ * to the value specified by new_ceiling, and then it unlocks the
+ * mutex. The previous value of the ceiling is returned in
+ * old_ceiling.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of mutex or prioceiling is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_mutex_set_prioceiling
+ (fosa_mutex_t *mutex, int new_ceiling, int *old_ceiling)
+{
+ return pthread_mutex_setprioceiling(mutex,new_ceiling,old_ceiling);
+}
+
+/**
+ * fosa_mutex_get_prioceiling()
+ *
+ * Dynamically get the priority ceiling of a mutex
+ *
+ * This function copies into the variable pointed to by ceiling the
+ * current priority ceiling of the mutex referenced by mutex
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of mutex is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_mutex_get_prioceiling(const fosa_mutex_t *mutex, int *ceiling)
+{
+ return pthread_mutex_getprioceiling(mutex,ceiling);
+}
+
+/**
+ * fosa_mutex_lock()
+ *
+ * Lock a mutex
+ *
+ * This function locks the mutex specified by mutex. If it is already
+ * locked, the calling thread blocks until the mutex becomes
+ * available. The operation returns with the mutex in the locked
+ * state, with the calling thread as its owner.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of mutex is invalid, or the priority of the
+ * calling thread is higher than the priority ceiling of the mutex
+ * EDEADLK: the current thread already owns this mutex
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_mutex_lock(fosa_mutex_t *mutex)
+{
+ return pthread_mutex_lock(mutex);
+}
+
+/**
+ * fosa_mutex_trylock()
+ *
+ * Try locking a mutex
+ *
+ * This function is identical to fosa_mutex_lock() except that if the
+ * mutex is already locked the call returns immediately with an error
+ * indication.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of mutex is invalid, or the priority of the
+ * calling thread is higher than the priority ceiling of the mutex
+ * EBUSY: the mutex was already locked
+ *
+ * Alternatively, except for EBUSY, in case of error the
+ * implementation is allowed to notify it to the system console and
+ * then terminate the FRSH implementation and dependant applications
+ **/
+int fosa_mutex_trylock(fosa_mutex_t *mutex)
+{
+ return pthread_mutex_trylock(mutex);
+}
+
+/**
+ * fosa_mutex_unlock()
+ *
+ * Unlock a mutex
+ *
+ * This function must be called by the owner of the mutex referenced
+ * by mutex, to unlock it. If there are threads blocked on the mutex
+ * the mutex becomes available and the highest priority thread is
+ * awakened to acquire the mutex.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of mutex is invalid
+ * EPERM: the calling thread is not the owner of the mutex
+ *
+ * Alternatively, except for EBUSY, in case of error the
+ * implementation is allowed to notify it to the system console and
+ * then terminate the FRSH implementation and dependant applications
+ **/
+int fosa_mutex_unlock(fosa_mutex_t *mutex)
+{
+ return pthread_mutex_unlock(mutex);
+}
+
+
+/**********************
+ * Condition variables
+ *********************/
+
+/**
+ * fosa_cond_init()
+ *
+ * Initiatize a condition variable
+ *
+ * The condition variable referenced by cond is initialized with
+ * the attributes required by the FOSA implementation.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EAGAIN: the system lacked the necessary resources to create the
+ * condition variable
+ * ENOMEM: Insufficient memory exists to initialize the condition variable
+ * EBUSY: The system has detected an attempt to reinitialize the
+ * condition variable
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_cond_init(fosa_cond_t *cond)
+{
+ // initialize condition variable with default attributes
+ // TODO: cond var attr timer to monotonic when supported by marte
+ return pthread_cond_init(cond,NULL);
+}
+
+/**
+ * fosa_cond_destroy()
+ *
+ * Destroy a condition variable
+ *
+ * The condition variable pointed to by cond is destroyed
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of cond is invalid
+ * EBUSY: The condition variable is in use (a thread is waiting on it)
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_cond_destroy(fosa_cond_t *cond)
+{
+ return pthread_cond_destroy(cond);
+}
+
+/**
+ * fosa_cond_signal()
+ *
+ * Signal a condition variable
+ *
+ * This call unblocks at least one of the threads that are waiting on
+ * the condition variable referenced by cond. If there are no threads
+ * waiting, the function has no effect
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of cond is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_cond_signal(fosa_cond_t *cond)
+{
+ return pthread_cond_signal(cond);
+}
+
+/**
+ * fosa_cond_broadcast()
+ *
+ * Broadcast a condition variable
+ *
+ * This call unblocks all of the threads that are waiting on the
+ * condition variable referenced by cond. If there are no threads
+ * waiting, the function has no effect.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of cond is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_cond_broadcast(fosa_cond_t *cond)
+{
+ return pthread_cond_broadcast(cond);
+}
+
+/**
+ * fosa_cond_wait()
+ *
+ * Wait at a condition variable
+ *
+ * This call is used to block on the condition variable referenced by
+ * cond. It shall be called with the mutex referenced by mutex
+ * locked. The function releases the mutex and blocks the calling
+ * thread until the condition is signalled by some other thread and
+ * the calling thread is awakened. Then it locks the mutex and
+ * returns with the mutex locked by the calling thread.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of cond or mutex is invalid, or different
+ * mutexes were used for concurrent wait operations on cond, or
+ * the mutex was not owned by the calling thread
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_cond_wait(fosa_cond_t *cond, fosa_mutex_t *mutex)
+{
+ return pthread_cond_wait(cond,mutex);
+}
+
+/**
+ * fosa_cond_timedwait()
+ *
+ * Wait at a condition variable, with a timeout
+ *
+ * This function is equal to fosa_cond_wait(), except that the maximum
+ * wait time is limited to the absolute time referenced by abstime, as
+ * measured by the FOSA_CLOCK_ABSOLUTE clock.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of cond or mutex or abstime is invalid, or different
+ * mutexes were used for concurrent wait operations on cond, or
+ * the mutex was not owned by the calling thread
+ * ETIMEDOUT: the timeout expired
+ *
+ * Alternatively, except for ETIMEDOUT, in case of error the
+ * implementation is allowed to notify it to the system console and
+ * then terminate the FRSH implementation and dependant applications
+ **/
+int fosa_cond_timedwait(fosa_cond_t *cond, fosa_mutex_t *mutex,
+ const fosa_abs_time_t *abstime)
+{
+ struct timespec abstime_tspec;
+
+ abstime_tspec = fosa_abs_time_to_timespec(*abstime);
+
+ return pthread_cond_timedwait(cond,mutex, &abstime_tspec);
+}
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_time.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+#include "fosa_platform_values.h"
+
+/**
+ * fosa_get_cpu_resource_id()
+ *
+ * Obtain the cpu resource id of the current node by making use of any
+ * mechanism that allows to distinguish between nodes (ie MAC addresses,
+ * configuration parameters, etc..)
+ */
+
+#ifdef MARTE_OS
+#include <sys/marte_configuration_parameters.h>
+#if MARTE_ARCHITECTURE == ARCH_X86
+
+#include <drivers/if_ether.h>
+#include <drivers/eth_ioctl.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+#include <string.h>
+
+#define MAC_WIFI1 "00:0E:0C:5B:1D:BD"
+#define MAC_WIFI2 "00:0E:0C:5B:1E:28"
+
+#define STATION_0 MAC_WIFI1
+#define STATION_1 MAC_WIFI2
+
+#if 1
+#include <stdio.h>
+#define DEBUG(x,args...) printf("%s: " x, __func__ , ##args)
+#else
+#define DEBUG(x,args...)
+#endif
+
+int fosa_get_cpu_resource_id(fosa_resource_id_t *cpu_id)
+{
+
+
+ int err, fd;
+ struct ether_addr mac, mac_tmp;
+ char mac_str[18];
+
+ fd = open("/dev/eth0", O_RDWR);
+ assert(fd != -1);
+
+ err = ioctl(fd, ETH_HWADDR, mac.ether_addr_octet);
+ assert(err == 0);
+
+ ether_ntoa (&mac, mac_str);
+ DEBUG("I am %s\n", mac_str);
+
+ err = ether_aton(STATION_0, &mac_tmp);
+ assert(err == 0);
+
+ if (memcmp(&mac_tmp, &mac, sizeof(mac)) == 0) {
+ DEBUG("STATION_0\n");
+ *cpu_id = 0;
+ }
+
+ err = ether_aton(STATION_1, &mac_tmp);
+ assert(err == 0);
+
+ if (memcmp(&mac_tmp, &mac, sizeof(mac)) == 0) {
+ DEBUG("STATION_1\n");
+ *cpu_id = 1;
+ }
+
+ return 0;
+}
+
+#endif // ARCH_X86
+#endif // MARTE_OS
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_threads_and_signals.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include "fosa_threads_and_signals.h"
+#include "fosa_configuration_parameters.h"
+
+#include <pthread.h>
+#include <stdio.h>
+#include <sched.h>
+
+#include <misc/error_checks.h>
+
+/**
+ * @defgroup threadandsignals Thread and Signals
+ * @ingroup fosa
+ *
+ * This module defines the functions that manipulate frsh_threads and
+ * frsh_signals inside FRSH implementation.
+ *
+ * Applications can refer to FRSH threads but they cannot create them
+ * directly, instead they must use frsh_thread_create*() which in turn
+ * use fosa_thread_create().
+ *
+ * For signals, we assume that the OS provides a direct mapping
+ * for frsh_signal_t and frsh_signal_info_t in the native interface.
+ *
+ * @{
+ **/
+
+//////////////////////////////////////////////////////////////////
+// Storage of thread-specific keys
+// - key_list is an array containing the keys
+// - key_in_use is an array of booleans
+// - key_lock is a mutex that locks the data structure
+// while creating a new key
+// - keys_initialized indicates whether the key_in_use array and
+// the key_lock mutex are initialized or not; it is declared
+// volatile as it may be accessed concurrently
+//////////////////////////////////////////////////////////////////
+
+static pthread_key_t key_list[FOSA_MAX_KEYS];
+static bool key_in_use[FOSA_MAX_KEYS];
+static pthread_once_t keys_initialized=PTHREAD_ONCE_INIT;
+static pthread_mutex_t key_lock;
+
+
+// Initialize the keys data structure
+// This function should be called from pthread_once() to ensure
+// one single initialization
+
+void init_keys() {
+ pthread_mutexattr_t attr;
+ int i;
+
+ // initialize the key_in_use array and the mutex
+ for(i=0; i<FOSA_MAX_KEYS;i++) {
+ key_in_use[i]=false;
+ }
+ // Initialize the mutex
+ CHK(pthread_mutexattr_init(&attr));
+ // we use the priority inheritance protocol because we don't know which
+ // tasks will be using the mutex
+ CHK(pthread_mutexattr_setprotocol(&attr,PTHREAD_PRIO_INHERIT));
+ CHK(pthread_mutex_init(&key_lock,&attr));
+ CHK(pthread_mutexattr_destroy(&attr));
+}
+
+/*************************
+ * Thread identification
+ *************************/
+
+/**
+ * fosa_thread_equal()
+ *
+ * Compare two thread identifiers to determine if they refer to the
+ * same thread
+ **/
+bool fosa_thread_equal(fosa_thread_id_t t1, fosa_thread_id_t t2)
+{
+ return pthread_equal(t1,t2);
+}
+
+
+/**
+ * fosa_thread_self()
+ *
+ * Return the thread id of the calling thread
+ **/
+fosa_thread_id_t fosa_thread_self()
+{
+ return pthread_self();
+}
+
+/*************************
+ * Thread attributes
+ *************************/
+
+/**
+ * fosa_thread_attr_init()
+ *
+ * Initialize a thread attributes object
+ *
+ * This function initializes the object pointed to by attr to all
+ * the default values defined by FRSH
+ *
+ * @return 0 if successful; otherwise it returns \n
+ * FOSA_ENOMEM: insufficient memory exists to initialize the thread
+ * attributes object
+ **/
+int fosa_thread_attr_init(fosa_thread_attr_t *attr)
+{
+ int ret_value;
+
+ ret_value=pthread_attr_init(attr);
+ if (ret_value==0) {
+ // set the default values
+
+
+ // inheritsched = explicit, so that we can explicitly set the attributes
+ CHK(pthread_attr_setinheritsched(attr,PTHREAD_EXPLICIT_SCHED));
+
+ // schedpolicy = fixed priorities
+ CHK(pthread_attr_setschedpolicy(attr,SCHED_FIFO));
+
+ // detachstate = detached thread (no join operation allowed)
+ CHK(pthread_attr_setdetachstate(attr,PTHREAD_CREATE_DETACHED));
+
+ }
+ return ret_value;
+}
+
+/**
+ * fosa_thread_attr_destroy()
+ *
+ * Destroy a thread attributes object
+ *
+ * This function is used to destroy the thread attributes object,
+ * pointed to by attr, and deallocate any system resources allocated for it
+ *
+ * Returns 0
+ */
+int fosa_thread_attr_destroy(fosa_thread_attr_t *attr)
+{
+ return pthread_attr_destroy(attr);
+}
+
+/**
+ * fosa_thread_attr_set_stacksize()
+ *
+ * Set the thread minimum stack size in a thread attributes object
+ *
+ * This function sets the minimum stack size of the thread attributes
+ * object attr to the value given by stacksize, in bytes. This
+ * function has no runtime effect on the stack size, except when the
+ * attributes object is used to create a thread, when it will be
+ * created with the specified minimum stack size
+ *
+ * @return 0 if successful, or the following error code:
+ * FOSA_EINVAL: the specified stacksize value is not supported in
+ * this implementation
+ */
+int fosa_thread_attr_set_stacksize
+ (fosa_thread_attr_t *attr, size_t stacksize)
+{
+ return pthread_attr_setstacksize(attr,stacksize);
+}
+
+/**
+ * fosa_thread_attr_get_stacksize()
+ *
+ * Get the thread minimum stack size from a thread attributes object
+ *
+ * This function sets the variable pointed to by stacksize to the
+ * minimum stack size stored in the thread attributes object attr.
+ *
+ * @return 0
+ */
+int fosa_thread_attr_get_stacksize
+ (const fosa_thread_attr_t *attr, size_t *stacksize)
+{
+ return pthread_attr_getstacksize(attr,stacksize);
+}
+
+
+/*************************
+ * Thread creation and termination
+ *************************/
+
+/**
+ * fosa_thread_create()
+ *
+ * This function creates a new thread using the attributes specified
+ * in attr. If attr is NULL, default attributes are used. The new
+ * thread starts running immediately, executing the function specified
+ * by code, with an argument equal to arg. Upon successful return, the
+ * variable pointed to by tid will contain the identifier of the newly
+ * created thread. The set of signals that may be synchronously
+ * accepted is inherited from the parent thread.
+ *
+ * Returns 0 if successful; otherwise it returs a code error:
+ *
+ * EAGAIN: the system lacks the necessary resources to create a
+ * new thread or the maximum number of threads has been
+ * reached
+ *
+ * EINVAL: the value specified by attr is invalid (for instance,
+ * it has not been correctly initialized)
+ *
+ * EREJECT: the cretion of the thread was rejected by the frsh scheduler
+ * possibly because of incorrect attributes, or because the
+ * requested minimum capacity cannot be guaranteed
+ *
+ **/
+ int fosa_thread_create
+ (fosa_thread_id_t *tid, const fosa_thread_attr_t *attr,
+ fosa_thread_code_t code, void * arg)
+{
+ return pthread_create(tid,attr,code,arg);
+}
+
+
+/**
+ * Note: no thread termination primitive is provided. The termination
+ * of a thread will be notified by the system to the FRSH scheduler
+ * through the scheduler API
+ **/
+
+
+/**************************************************
+ * Thread-specific data
+ * (extended with access from a different thread)
+ *
+ * Several data items (pointers) may be associated with each thread
+ * Each item is identified through a key, an integer value between 0
+ * and FOSA_MAX_KEYS-1. The caller is responsible of allocating and
+ * deallocating the memory area pointed to by the pointer
+ **************************************************/
+
+/**
+ * fosa_key_create()
+ *
+ * Create a new key for thread specific data.
+ *
+ * Prior to setting data in a key, we need ask the system to create
+ * one for us.
+ *
+ * @return 0 if successful \n
+ * FOSA_EINVAL If we already have reached the FOSA_MAX_KEYS limit.
+ * FOSA_ENOMEM If there are no enough memory resources to
+ * create the key.
+ **/
+int fosa_key_create(int *key)
+{
+ int i,ret_value;
+ bool found=false;
+
+ ret_value = 0;
+ // initialize the keys data structure if needed
+ CHK(pthread_once(&keys_initialized, init_keys));
+
+ // lock the mutex
+ CHK(pthread_mutex_lock(&key_lock));
+
+ // find an unused key
+ for(i=0; i<FOSA_MAX_KEYS;i++) {
+ if (!key_in_use[i]) {
+ *key=i;
+ key_in_use[i]=true;
+ ret_value=pthread_key_create(&(key_list[i]),NULL);
+ found=true;
+ break;
+ }
+ }
+ // unlock the mutex before returning
+ CHK(pthread_mutex_unlock(&key_lock));
+ if (!found) {
+ // all keys are in use; max keys reached
+ ret_value=FOSA_EINVAL;
+ }
+ return ret_value;
+}
+
+/**
+ * fosa_key_destroy()
+ *
+ * Destroy a key
+ *
+ * This destroys the key and isables its use in the system
+ *
+ * @return 0 if successful \n
+ * FOSA_EINVAL The key is not initialised or is not in FOSA key range.
+ **/
+int fosa_key_destroy(int key)
+{
+ int ret_value;
+
+ // lock the mutex
+ CHK(pthread_mutex_lock(&key_lock));
+
+ // destroy the key and mark it as available
+ ret_value=pthread_key_delete(key_list[key]);
+ if (ret_value==0) {
+ key_in_use[key]=false;
+ }
+
+ // unlock the mutex before returning
+ CHK(pthread_mutex_unlock(&key_lock));
+ return ret_value;
+}
+
+
+/**
+ * fosa_thread_set_specific_data()
+ *
+ * Set thread-specific data
+ *
+ * For the thread identified by tid, the thread-specifid data field
+ * identified by key will be set to the value specified by value
+ *
+ * Returns 0 if successful; otherwise, an error code is returned
+ * EINVAL: the value of key is not between 0 and FOSA_MAX_KEYS-1
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+ int fosa_thread_set_specific_data
+ (int key, fosa_thread_id_t tid, const void * value)
+{
+ return pthread_setspecific_for(key_list[key],tid,value);
+}
+
+/**
+ * fosa_thread_get_specific_data()
+ *
+ * Get thread-specific data
+ *
+ * For the thread identified by tid, the thread-specifid data field
+ * identified by key will be copied to the variable pointed to by value
+ *
+ * Returns 0 if successful; otherwise, an error code is returned
+ * EINVAL: the value of key is not between 0 and FOSA_MAX_KEYS-1
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_get_specific_data(int key, fosa_thread_id_t tid,
+ void ** value)
+{
+ return pthread_getspecific_from(key_list[key],tid,value);
+}
+
+
+/******************************************************************
+ * Thread scheduling
+ *
+ * This implementation of FRSH assumes an underlying fixed priority
+ * scheduler with priorities in a range, with a minimum and a
+ * maximumm, a number of priority levels with at least 31
+ * priorities. A larger number implies a larger priority. In systems
+ * in which the underlying scheduler uses the opposite convention, a
+ * mapping is automatically provided by the OS adaptation layer.
+ *******************************************************************/
+
+/**
+ * fosa_get_priority_max()
+ *
+ * Return the maximum priority value used in this implementation
+ **/
+int fosa_get_priority_max()
+{
+ return sched_get_priority_max(SCHED_APP);
+}
+
+/**
+ * fosa_get_priority_min()
+ *
+ * Return the minimum priority value used in this implementation
+ **/
+int fosa_get_priority_min()
+{
+ return sched_get_priority_min(SCHED_APP);
+}
+
+/**
+ * fosa_thread_attr_set_prio()
+ *
+ * Change the priority of a thread attributes object
+ *
+ * The priority of the thread attriutes object specified by attr is
+ * set to the value specified by prio. This function has no runtime
+ * effect on the priority, except when the attributes object is used
+ * to create a thread, when it will be created with the specified
+ * priority
+ *
+ * Returns 0 if successful, or the following error code:
+ * EINVAL: the specified priority value is not between the
+ * minimum and the maximum priorities defined in this
+ * FRSH implementation
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_set_prio(fosa_thread_attr_t *attr, int prio)
+{
+ struct sched_param param;
+
+ param.sched_priority=prio;
+ return pthread_attr_setschedparam(attr,¶m);
+}
+
+/**
+ * fosa_thread_attr_get_prio()
+ *
+ * Get the priority from a thread attributes object
+ *
+ * This function sets the variable pointed to by prio to the
+ * priority stored in the thread attributes object attr.
+ *
+ * Returns 0
+ **/
+int fosa_thread_attr_get_prio
+ (const fosa_thread_attr_t *attr, int *prio)
+{
+ struct sched_param param;
+ int ret_value;
+
+ ret_value=pthread_attr_getschedparam(attr,¶m);
+ if (ret_value==0) {
+ *prio=param.sched_priority;
+ }
+ return ret_value;
+}
+
+/**
+ * fosa_thread_set_prio()
+ *
+ * Dynamically change the priority of a thread
+ *
+ * The priority of the thread identified by tid is
+ * set to the value specified by prio.
+ *
+ * Returns 0 if successful, or the following error code:
+ * EINVAL: the specified priority value is not between the
+ * minimum and the maximum priorities defined in this
+ * FRSH implementation
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_set_prio(fosa_thread_id_t tid, int prio)
+{
+ struct sched_param param;
+ int policy, ret_value;
+
+ ret_value=pthread_getschedparam(tid,&policy,¶m);
+ if (ret_value!=0) return ret_value;
+
+ param.sched_priority=prio;
+ return pthread_setschedparam(tid,policy,¶m);
+}
+
+/**
+ * fosa_thread_get_prio()
+ *
+ * Dynamically get the priority of a thread
+ *
+ * This function sets the variable pointed to by prio to the
+ * priority of the thread identified by tid
+ *
+ * Returns 0
+ **/
+int fosa_thread_get_prio (fosa_thread_id_t tid, int *prio)
+{
+ struct sched_param param;
+ int policy, ret_value;
+
+ ret_value=pthread_getschedparam(tid,&policy,¶m);
+ if (ret_value==0) {
+ *prio=param.sched_priority;
+ }
+ return ret_value;
+}
+
+
+
+/*******************************************************************
+ * Signals
+ *
+ * Signals represent events that may be notified by the system, or
+ * sent explicitly by the application, and for which a thread may
+ * synchronously wait. Signals carry an associated piece of
+ * information (an integer or a pointer) and are queued until they are
+ * accepted. Signals are identified by an integer signal number (of
+ * the type fosa_signal_t) in the range FOSA_SIGNAL_MIN,
+ * FOSA_SIGNAL_MAX. This range is required to have at least <tbd>
+ * values.
+ *******************************************************************/
+
+/**
+ * fosa_set_accepted_signals()
+ *
+ * Establish the set of signals that may be synchronously accepted
+ * by the calling thread
+ *
+ * The function uses the array of signal numbers specified by set,
+ * which must be of size equal to size
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the array contains one or more values which are not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size
+ * is less than 0
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_set_accepted_signals(fosa_signal_t set[], int size)
+{
+ sigset_t signalset;
+ int i;
+ struct sigaction act;
+
+ // empty the signal set
+ CHKE(sigemptyset(&signalset));
+
+ // configure the signal action to make the signal a real-time
+ // signal that can be queued
+ act.sa_handler=SIG_DFL;
+ act.sa_mask=signalset;
+ act.sa_flags=SA_SIGINFO;
+ act.sa_sigaction=NULL;
+
+ // loop for all signals in set
+ for(i=0;i<size;i++) {
+ CHKE(sigaddset(&signalset,set[i]));
+ // Configure the signal so that it can be queued with data
+ CHKE(sigaction(set[i],&act,NULL));
+ }
+ return pthread_sigmask(SIG_BLOCK,&signalset,NULL);
+}
+
+/**
+ * fosa_signal_queue()
+ *
+ * Queue a signal
+ *
+ * This function is used to explicitly send a signal with a specified
+ * value
+ *
+ * The signal number specified by signal is sent together with the
+ * information specified by info, to the thread identified by
+ * receiver. In those implementations that do not support queueing a
+ * signal with information to a thread (such as POSIX), the signal may
+ * be sent to any thread that is waiting for this signal via
+ * fosa_signal_wait(). Portability can be ensured by having the receiver
+ * thread be the one who is waiting for the signal.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the signal specified by signal is not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX
+ *
+ * EAGAIN: no resources are available to queue the signal; the
+ * maximum number of queued signals has been reached, or a
+ * systemwide resource limit has been exceeded
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_signal_queue
+ (fosa_signal_t signal, fosa_signal_info_t info,
+ fosa_thread_id_t receiver)
+{
+ // note: in MaRTE OS the signal is sent to any interested thread
+ pid_t pid=1; // dummy value; the pid is ignored in MaRTE OS
+ int err;
+ err=sigqueue(pid,signal,*((union sigval *)(&info)));
+ // the above casting construct is used to overcome the compiler
+ // restriction that does not allow casts between unions
+ if (err==0) {
+ return 0;
+ } else {
+ return errno;
+ }
+}
+
+
+/**
+ * fosa_signal_wait()
+ *
+ * Wait for a signal
+ *
+ * The function waits for the arrival of one of the signals in the
+ * array of signal numbers specified by set, which must be of size
+ * equal to size. If there is a signal already queued, the function
+ * returns immediately. If there is no signal of the specified set
+ * queued, the calling thread is suspended until a signal from that
+ * set arrives. Upon return, if signal_received is not NULL the number
+ * of the signal received is stored in the variable pointed to by
+ * signal_received; and if info is not NULL the associated information
+ * is stored in the variable pointed to by info.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the array contains one or more values which are not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size
+ * is less than 0
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_signal_wait
+ (fosa_signal_t set[], int size, fosa_signal_t *signal_received,
+ fosa_signal_info_t *info)
+{
+ int err,i;
+ sigset_t signalset;
+ siginfo_t siginfo;
+
+ CHKE(sigemptyset(&signalset));
+ for(i=0;i<size;i++) {
+ CHKE(sigaddset(&signalset,set[i]));
+ }
+
+ err=sigwaitinfo(&signalset,&siginfo);
+ if (err!=-1) {
+ *signal_received=siginfo.si_signo;
+ *info=*((fosa_signal_info_t *)(&siginfo.si_value));
+ return 0;
+ } else {
+ return errno;
+ }
+}
+
+/**
+ * fosa_signal_timedwait()
+ *
+ * Timed wait for a signal
+ *
+ * This function behaves the same as fosa_signal_wait(), except that
+ * the suspension time is limited to the time interval specified in
+ * the timespec structure referenced by timeout.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the array contains one or more values which are not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size
+ * is less than 0, or timeout is invalid
+ * EAGAIN: The timeout expired
+ *
+ * Alternatively, in case of the EINVAL error the implementation is
+ * allowed to notify it to the system console and then terminate the
+ * FRSH implementation and dependant applications
+ **/
+ int fosa_signal_timedwait
+ (fosa_signal_t set[], int size, fosa_signal_t *signal_received,
+ fosa_signal_info_t *info, const fosa_rel_time_t *timeout)
+{
+
+ // the implementation of sigtimedwait is not yet available in MaRTE OS
+ return ENOSYS;
+
+/* int err,i; */
+/* sigset_t signalset; */
+/* siginfo_t siginfo; */
+
+/* CHKE(sigemptyset(&signalset)); */
+/* for(i=0;i<size;i++) { */
+/* CHKE(sigaddset(&signalset,set[i])); */
+/* } */
+
+/* err=sigtimedwait(&signalset,&siginfo,timeout); */
+/* if (err==0) { */
+/* *signal_received=siginfo.si_signo; */
+/* *info=siginfo.si_value; */
+/* return 0; */
+/* } else { */
+/* return errno; */
+/* } */
+}
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+// fosa_time.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include "fosa.h"
+
+
+
+#ifdef VIRTUAL_TIME
+ #include <fosa_vt.h>
+#endif
+
+/**
+ * fosa_eat()
+ *
+ * Eat some time using system clock facilities
+ **/
+void fosa_eat(const fosa_rel_time_t *cpu_time)
+{
+#ifdef VIRTUAL_TIME
+ vt_time_t vt_clock;
+ timespec_2_vtime(cpu_time, vt_clock);
+ vt_use_time((unsigned long long)vt_clock);
+#else
+ fosa_clock_id_t clock_id;
+ fosa_abs_time_t current_time, time_to_go;
+
+ // NOTE: there should be a constant for the cpu_clock_id of the caller
+ // to avoid calling 'fosa_thread_get_cputime_clock'
+ fosa_thread_get_cputime_clock(fosa_thread_self(), &clock_id);
+ fosa_clock_get_time(clock_id, ¤t_time);
+
+ time_to_go = fosa_abs_time_incr(current_time, *cpu_time);
+
+ /* We also spread smaller_timespec */
+ while ( fosa_abs_time_smaller_or_equal(current_time, time_to_go) )
+ {
+ fosa_clock_get_time(clock_id, ¤t_time);
+ }
+#endif
+}
+
+
+
--- /dev/null
+SUBDIRS=$(ALL_OMK_SUBDIRS)
--- /dev/null
+include ../../../config.mk
+include ../../../rules.mk
+
+
+test_fosa_long_jump.exe: test_fosa_long_jump.o $(FOSA_PATH)/lib/libfosa_$(PLATFORM).a $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o
+ $(CC) -L$(FOSA_PATH)/lib $< -lfosa_$(PLATFORM) $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o -o $@
+
+
+simple_test_non_local_jump.exe: simple_test_non_local_jump.o $(FOSA_PATH)/lib/libfosa_$(PLATFORM).a $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o
+ $(CC) -L$(FOSA_PATH)/lib $< -lfosa_$(PLATFORM) $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o -o $@
+
+
--- /dev/null
+default_CONFIG = CONFIG_FOSA_MARTE_TEST_$(notdir $(SOURCES_DIR))=y
+
+ifeq ($(CONFIG_FRSH_TEST_$(notdir $(SOURCES_DIR))),y)
+test_PROGRAMS:=$(basename $(notdir $(wildcard $(SOURCES_DIR)/*.c)))
+
+$(foreach t,$(test_PROGRAMS),\
+$(eval $(t)_SOURCES = $(t).c)\
+$(eval $(t)_LIBS = fosa m)\
+)
+endif
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+#include <unistd.h>
+#include <stdio.h>
+#include <time.h> // for nanosleep
+
+#include "fosa.h"
+
+// TODO: use #include <assert.h> when it works for all architectures
+#include <stdlib.h> // for exit in assert
+
+
+static void inline asserto(expression)
+{
+ if (!expression) {
+ printe(__FILE__":%u: failed assertion.\n", __LINE__);
+ exit (-1);
+ }
+}
+
+int main () {
+ int err;
+ fosa_clock_id_t clockid = FOSA_CLOCK_REALTIME;
+ fosa_signal_t signal = FOSA_SIGNAL_MAX;
+ fosa_signal_t received;
+ fosa_signal_info_t info, info_received;
+ fosa_timer_id_t timerid;
+ fosa_rel_time_t timerval;
+ fosa_signal_t set[1];
+
+ info.sival_int=69;
+
+ err = fosa_timer_create (clockid, signal, info, &timerid);
+ printf("timer created, err=%d\n", err);
+ assert(err == 0);
+
+ timerval = fosa_msec_to_rel_time(1300);
+
+ err = fosa_rel_timer_arm (timerid, &timerval);
+ printf("timer armed for 1.3 secs, err=%d\n", err);
+
+ set[0] = signal;
+ err = fosa_signal_wait(set,1,&received, &info_received);
+ printf("signal received=%d value=%d (69?), err=%d\n",
+ received,info_received.sival_int,err);
+
+ err = fosa_signal_wait(set,1,&received, &info_received);
+ printf("signal received=%d value=%d (69?), err=%d\n",
+ received,info_received.sival_int,err);
+
+ return 0;
+}
--- /dev/null
+include ../../../config.mk
+include ../../../rules.mk
+
+
+test_fosa_long_jump.exe: test_fosa_long_jump.o $(FOSA_PATH)/lib/libfosa_$(PLATFORM).a $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o
+ $(CC) -L$(FOSA_PATH)/lib $< -lfosa_$(PLATFORM) $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o -o $@
+
+
+simple_test_non_local_jump.exe: simple_test_non_local_jump.o $(FOSA_PATH)/lib/libfosa_$(PLATFORM).a $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o
+ $(CC) -L$(FOSA_PATH)/lib $< -lfosa_$(PLATFORM) $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o -o $@
+
+
--- /dev/null
+../test_clock_and_timers/Makefile.omk
\ No newline at end of file
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+
+#include <unistd.h>
+#include <stdio.h>
+
+#include <assert.h>
+#include <stdlib.h> // for exit in assert
+#include <string.h> // for memset
+
+#include "fosa.h"
+
+/*****************************/
+/* D E F I N I T I O N S */
+/*****************************/
+#define RT_ERROR_SIGWAIT -2
+#define RT_ERROR_TIMER -3
+
+#define SIGNAL_TIMER FOSA_SIGNAL_MAX - 1
+
+/***************************/
+/* P R O T O T Y P E S */
+/***************************/
+static void * thread_body(void *thread_arg);
+
+
+static fosa_abs_time_t start_execution;
+static fosa_abs_time_t signal_reception;
+
+int main ()
+{
+ int err = -1;
+
+ fosa_thread_attr_t attr;
+ fosa_thread_id_t tid;
+
+ fosa_signal_t signal_received;
+ fosa_signal_info_t info_programmed, info_received;
+ fosa_rel_time_t work_interval = fosa_msec_to_rel_time(3200); // 3.2 seconds
+ fosa_clock_id_t clockid;
+ fosa_timer_id_t timerid;
+
+ fosa_rel_time_t budget;
+ fosa_rel_time_t elapsed_time;
+ fosa_signal_t signal_set[1];
+
+ /* Set the signal mask */
+ /***********************/
+ signal_set[0] = SIGNAL_TIMER;
+ if (fosa_set_accepted_signals(signal_set, 1) !=0)
+ {
+ printf ("Error while setting the signal mask\n");
+ exit (1);
+ }
+
+ /* Create the thread attributes and define its priority */
+ /********************************************************/
+ if (fosa_thread_attr_init (&attr) != 0) {
+ printf("Error while initializing the attributes\n");
+ exit(1);
+ }
+
+ if (fosa_thread_attr_set_prio (&attr,fosa_get_priority_min()+3) != 0) {
+ printf("Error while setting schedparam\n");
+ exit(1);
+ }
+
+ /* create the periodic thread. It won't execute yet */
+ /* because it has lower priority than main(). */
+ /*****************************************************/
+ err = fosa_thread_create(&tid, &attr, thread_body, NULL);
+ if (err) {
+ printf("pthread_create failed thread\n");
+ exit(1);
+ }
+
+ /* Get the thread's cputime clock */
+ /**********************************/
+ if (fosa_thread_get_cputime_clock(tid, &clockid) !=0)
+ {
+ exit(RT_ERROR_TIMER);
+ }
+
+ /* Create a timer and arm it with a given budget */
+ /*************************************************/
+ info_programmed.sival_int = 42;
+ err = fosa_timer_create(clockid, SIGNAL_TIMER, info_programmed, &timerid);
+ printf("timer created, err=%d\n", err);
+ assert(err == 0);
+
+ budget = fosa_msec_to_rel_time(2500);
+ err = fosa_rel_timer_arm(timerid, &budget);
+ printf("timer armed for 2.5 secs, err=%d\n", err);
+ assert(err == 0);
+
+ /* We execute a little bit to ensure that execution time */
+ /* and real time differ */
+ /*********************************************************/
+ printf("Main works for some time...\n");
+ fosa_eat(&work_interval);
+
+ /* Now we do the wait in order to allow the thread to run */
+ /**********************************************************/
+ printf("About to do the wait\n");
+ err = fosa_signal_wait(signal_set, 1 ,&signal_received, &info_received);
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, &signal_reception);
+ elapsed_time = fosa_abs_time_extract_interval(start_execution, signal_reception);
+
+ printf("signal received=%d value=%d (42?), err=%d\n",
+ signal_received, info_received.sival_int, err);
+
+ printf("Elapsed time between sigwait and timer expiration: %ld msecs\n",
+ fosa_rel_time_to_msec(elapsed_time) );
+
+ return 0;
+}
+
+
+// ----------------------------------------------------------------
+
+static void * thread_body(void *thread_arg)
+{
+ fosa_abs_time_t before_work_time;
+ fosa_abs_time_t after_work_time;
+ fosa_rel_time_t work_interval = fosa_msec_to_rel_time(1400);
+ fosa_rel_time_t elapsed_time;
+ int err;
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, &start_execution);
+
+ while(1)
+ {
+ err = fosa_clock_get_time(FOSA_CLOCK_REALTIME, &before_work_time);
+ assert(err == 0);
+ printf("Start periodic work at %ld msecs\n", fosa_abs_time_to_msec(before_work_time) );
+
+ fosa_eat(&work_interval);
+
+ err = fosa_clock_get_time(FOSA_CLOCK_REALTIME, &after_work_time);
+ assert(err == 0);
+
+ printf("End periodic work at %ld msecs\n", fosa_abs_time_to_msec(after_work_time) );
+ elapsed_time = fosa_abs_time_extract_interval(before_work_time, after_work_time);
+
+ printf("Elapsed time: %ld msecs\n", fosa_rel_time_to_msec(elapsed_time) );
+
+ } // while
+ return NULL;
+}
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+#include <unistd.h>
+#include <stdio.h>
+#include <time.h> // for nanosleep
+
+#include <assert.h>
+#include <stdlib.h> // for exit in assert
+#include <string.h> // for memset
+
+#include "fosa.h"
+
+/*****************************/
+/* D E F I N I T I O N S */
+/*****************************/
+#define RT_ERROR_SIGWAIT -2
+#define RT_ERROR_TIMER -3
+
+#define SIGNAL_TIMER FOSA_SIGNAL_MAX - 1
+
+/***************************/
+/* P R O T O T Y P E S */
+/***************************/
+static void * thread_body(void *thread_arg);
+
+/*************************************/
+/* S T A T I C V A R I A B L E S */
+/*************************************/
+static fosa_abs_time_t start_execution;
+static fosa_abs_time_t signal_reception;
+
+int main ()
+{
+ int err = -1;
+
+ fosa_thread_attr_t attr;
+ fosa_thread_id_t tid;
+
+ fosa_signal_t signal_received;
+ fosa_signal_info_t info_received;
+
+ fosa_rel_time_t work_interval = fosa_msec_to_rel_time(3200);
+ fosa_rel_time_t elapsed_time;
+
+ fosa_signal_t signal_set[1];
+
+ /* Set the signal mask */
+ /***********************/
+ signal_set[0] = SIGNAL_TIMER;
+ if (fosa_set_accepted_signals(signal_set, 1) !=0)
+ {
+ printf ("Error while setting the signal mask\n");
+ exit (1);
+ }
+
+ /* Create the thread attributes and define its priority */
+ /* */
+ /* At the same time ensure that the main priority is */
+ /* higher */
+ /********************************************************/
+ if (fosa_thread_attr_init (&attr) != 0) {
+ printf("Error while initializing the attributes\n");
+ exit(1);
+ }
+
+ if (fosa_thread_attr_set_prio (&attr,fosa_get_priority_min()+3) != 0) {
+ printf("Error while setting schedparam\n");
+ exit(1);
+ }
+
+ /* create the periodic thread. It won't execute yet */
+ /* because it has lower priority than main(). */
+ /*****************************************************/
+ err = fosa_thread_create(&tid, &attr, thread_body, NULL);
+ if (err) {
+ printf("pthread_create failed thread\n");
+ exit(1);
+ }
+
+
+ /* We execute a little bit to ensure that execution time */
+ /* and real time differ */
+ /*********************************************************/
+ printf("Main works for some time...\n");
+ fosa_eat(&work_interval);
+
+ /* Now we do the wait in order to allow the thread to run */
+ /**********************************************************/
+ printf("About to do the wait\n");
+ err = fosa_signal_wait(signal_set, 1 ,&signal_received, &info_received);
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, &signal_reception);
+ elapsed_time = fosa_abs_time_extract_interval(start_execution, signal_reception);
+
+ printf("signal received=%d value=%d (42?), err=%d\n",
+ signal_received, info_received.sival_int, err);
+
+ printf("Elapsed time between sigwait and timer expiration: %ld msecs\n",
+ fosa_rel_time_to_msec(elapsed_time) );
+
+ return 0;
+}
+
+
+// ----------------------------------------------------------------
+
+static void * thread_body(void *thread_arg)
+{
+ fosa_abs_time_t before_work_time;
+ fosa_abs_time_t after_work_time;
+ fosa_rel_time_t work_interval = fosa_msec_to_rel_time(1400);
+
+
+ fosa_clock_id_t clockid;
+ fosa_timer_id_t timerid;
+ fosa_rel_time_t budget;
+ fosa_rel_time_t elapsed_time;
+
+ fosa_signal_info_t info_programmed;
+ int err;
+
+
+ /* Get the thread's cputime clock */
+ /**********************************/
+ if (fosa_thread_get_cputime_clock(fosa_thread_self(), &clockid) !=0)
+ {
+ exit(RT_ERROR_TIMER);
+ }
+
+ /* Create a timer and arm it with a given budget */
+ /*************************************************/
+ info_programmed.sival_int = 42;
+ err = fosa_timer_create(clockid, SIGNAL_TIMER, info_programmed, &timerid);
+ printf("timer created, err=%d\n", err);
+ assert(err == 0);
+
+ budget = fosa_msec_to_rel_time(2500);
+ err = fosa_rel_timer_arm(timerid, &budget);
+ printf("timer armed for 2.5 secs, err=%d\n", err);
+ assert(err == 0);
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, &start_execution);
+
+ while(1)
+ {
+ err = fosa_clock_get_time(FOSA_CLOCK_REALTIME, &before_work_time);
+ assert(err == 0);
+ printf("Start periodic work at %ld msecs\n", fosa_abs_time_to_msec(before_work_time) );
+
+ fosa_eat(&work_interval);
+
+ err = fosa_clock_get_time(FOSA_CLOCK_REALTIME, &after_work_time);
+ assert(err == 0);
+
+ printf("End periodic work at %ld msecs\n", fosa_abs_time_to_msec(after_work_time) );
+
+ elapsed_time = fosa_abs_time_extract_interval(before_work_time, after_work_time);
+
+ printf("Elapsed time: %ld msec\n", fosa_rel_time_to_msec(elapsed_time) );
+
+ } // while
+
+ return NULL;
+}
+
--- /dev/null
+include ../../../config.mk
+include ../../../rules.mk
+
+
+test_fosa_long_jump.exe: test_fosa_long_jump.o $(FOSA_PATH)/lib/libfosa_$(PLATFORM).a $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o
+ $(CC) -L$(FOSA_PATH)/lib $< -lfosa_$(PLATFORM) $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o -o $@
+
+
+simple_test_non_local_jump.exe: simple_test_non_local_jump.o $(FOSA_PATH)/lib/libfosa_$(PLATFORM).a $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o
+ $(CC) -L$(FOSA_PATH)/lib $< -lfosa_$(PLATFORM) $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o -o $@
+
+
--- /dev/null
+../test_clock_and_timers/Makefile.omk
\ No newline at end of file
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+#include <stdio.h> // for printf
+#include <string.h> // for strlen, strncpy
+#include <unistd.h> // for sleep
+#include <time.h> // for nanosleep
+
+
+// TODO: use #include <assert.h> when it works for all architectures
+#include <stdlib.h> // for exit in assert
+
+#include "fosa.h"
+
+static void inline assert(expression)
+{
+ if (!expression) {
+ printe(__FILE__":%u: failed assertion.\n", __LINE__);
+ exit (-1);
+ }
+}
+
+///////////////////////////////////////////////////////
+// 0) Function prototypes
+///////////////////////////////////////////////////////
+
+static void *thread_code(void *arg);
+
+static void fosa_callback_init
+ (void *sched_data, void *arg);
+
+static void fosa_callback_new_thread
+ (void *sched_data,
+ fosa_thread_id_t thread,
+ fosa_ads_actions_t *actions,
+ fosa_abs_time_t *current_time);
+
+static void fosa_callback_thread_terminate
+ (void *sched_data,
+ fosa_thread_id_t thread,
+ fosa_ads_actions_t *actions,
+ fosa_abs_time_t *current_time);
+
+static void fosa_callback_thread_ready
+ (void *sched_data,
+ fosa_thread_id_t thread,
+ fosa_ads_actions_t *actions,
+ fosa_abs_time_t *current_time);
+
+static void fosa_callback_thread_block
+ (void *sched_data,
+ fosa_thread_id_t thread,
+ fosa_ads_actions_t *actions,
+ fosa_abs_time_t *current_time);
+
+static void fosa_callback_change_sched_param_thread
+ (void *sched_data,
+ fosa_thread_id_t thread,
+ fosa_ads_actions_t *actions,
+ fosa_abs_time_t *current_time);
+
+static void fosa_callback_explicit_call_with_data
+ (void *sched_data,
+ fosa_thread_id_t thread,
+ const void * msg,
+ size_t msg_size,
+ void *reply,
+ size_t *reply_size,
+ fosa_ads_actions_t *actions,
+ fosa_abs_time_t *current_time);
+
+static void fosa_callback_notification_for_thread
+ (void *sched_data,
+ fosa_thread_id_t thread,
+ fosa_clock_id_t clock,
+ fosa_ads_actions_t *actions,
+ fosa_abs_time_t *current_time);
+
+static void fosa_callback_timeout
+ (void *sched_data,
+ fosa_ads_actions_t *actions,
+ fosa_abs_time_t *current_time);
+
+static void fosa_callback_signal
+ (void *sched_data,
+ fosa_signal_t signal,
+ fosa_signal_info_t siginfo,
+ fosa_ads_actions_t *actions,
+ fosa_abs_time_t *current_time);
+
+static void fosa_callback_appsched_error
+ (void *sched_data,
+ fosa_thread_id_t thread,
+ fosa_ads_error_cause_t cause,
+ fosa_ads_actions_t *actions);
+
+///////////////////////////////////////////////////////
+// 1) Types, Module variables and Constants
+///////////////////////////////////////////////////////
+
+static fosa_ads_scheduler_ops_t scheduler_ops = {
+ .init = fosa_callback_init,
+ .new_thread = fosa_callback_new_thread,
+ .thread_terminate = fosa_callback_thread_terminate,
+ .thread_ready = fosa_callback_thread_ready,
+ .thread_block = fosa_callback_thread_block,
+ .change_sched_param_thread = fosa_callback_change_sched_param_thread,
+ .explicit_call_with_data = fosa_callback_explicit_call_with_data,
+ .notification_for_thread = fosa_callback_notification_for_thread,
+ .timeout = fosa_callback_timeout,
+ .signal = fosa_callback_signal,
+ .appsched_error = fosa_callback_appsched_error,
+};
+
+static fosa_mutex_t lock;
+
+const unsigned int MX_INIT_ARGS_STRING = 30;
+const unsigned int MX_PRIO = 20;
+#define MX_THREADS 2
+
+// general control structure for the scheduler
+typedef struct {
+ fosa_ads_urgency_t array_prio[MX_THREADS];
+ int array_status[MX_THREADS];
+} fosa_sched_data_t;
+
+typedef struct {
+ fosa_ads_urgency_t prio;
+} appsched_params_t;
+
+typedef enum {
+ ACTIVATE,
+ SUSPEND,
+ CAUSE_ERROR
+} command_t;
+
+typedef struct {
+ fosa_thread_id_t thread_id;
+ command_t command;
+} signal_action_t;
+
+///////////////////////////////////////////////////////
+// 2) Main program
+///////////////////////////////////////////////////////
+
+int main () {
+
+ int err;
+ char init_args_string[MX_INIT_ARGS_STRING + 1];
+ fosa_thread_id_t tid1, tid2, tid3;
+ fosa_thread_attr_t th_attr;
+ bool is_appsched;
+ appsched_params_t params;
+ fosa_signal_info_t timer_info;
+ fosa_timer_id_t timerid;
+ fosa_rel_time_t timerval;
+ signal_action_t signal_action;
+
+
+ err = fosa_thread_set_prio (fosa_thread_self(), MX_PRIO + 1);
+ printf("set main to highest priority, err=%d\n", err);
+ assert(err == 0);
+
+ err = fosa_mutex_init(&lock, MX_PRIO);
+ printf("mutex initialized with ceiling %d. err=%d\n", MX_PRIO, err);
+ assert(err == 0);
+
+ //////////////////////////////////
+ // 2a) Create the scheduler
+ //////////////////////////////////
+
+ printf("--------------------------------------------------\n");
+ printf("2a) Create the scheduler\n");
+
+ strncpy(init_args_string, "Hello Scheduler!!", MX_INIT_ARGS_STRING);
+ init_args_string[MX_INIT_ARGS_STRING] = '\0';
+
+ err = fosa_ads_scheduler_create
+ (&scheduler_ops,
+ sizeof(fosa_sched_data_t),
+ init_args_string, // INIT IS CALLED INMEDIATELY??!!!
+ strlen(init_args_string) + 1);
+ printf("scheduler created, err=%d\n", err);
+ assert(err == 0);
+
+ //////////////////////////////////////////////////////////////
+ // 2b) Create two application scheduled threads
+ //////////////////////////////////////////////////////////////
+
+ printf("--------------------------------------------------\n");
+ printf("2b) Create two application scheduled threads\n");
+
+ err = fosa_thread_attr_init(&th_attr);
+ printf("thread attributes object initialized, err=%d\n", err);
+ assert(err == 0);
+
+ err = fosa_thread_attr_set_stacksize(&th_attr,40000);
+ printf("thread attr set stack size to 40000, err=%d\n", err);
+ assert(err == 0);
+
+ err = fosa_thread_attr_set_prio(&th_attr, MX_PRIO - 1);
+ printf("thread attr set prio to 10, err=%d\n",err);
+ assert(err == 0);
+
+ err = fosa_thread_attr_set_appscheduled(&th_attr, true);
+ printf("thread attr set appscheduled, err=%d\n", err);
+ assert(err == 0);
+
+ err = fosa_thread_attr_get_appscheduled(&th_attr, &is_appsched);
+ printf("thread attr get appscheduled=%d, err=%d\n",is_appsched, err);
+ assert(err == 0);
+
+ params.prio = 10;
+ err = fosa_thread_attr_set_appsched_params
+ (&th_attr, (void *)¶ms, sizeof(params));
+ printf("thread attr set params prio=%d, err=%d\n", params.prio, err);
+ assert(err == 0);
+
+ // create thread 1
+ err = fosa_thread_create (&tid1, &th_attr, thread_code, (void *)1);
+ printf("created thread 1 with prio=%d, err=%d\n", params.prio, err);
+ assert(err == 0);
+
+ params.prio = 15;
+ err = fosa_thread_attr_set_appsched_params
+ (&th_attr, (void *)¶ms, sizeof(params));
+ printf("thread attr set params prio=%d, err=%d\n", params.prio, err);
+ assert(err == 0);
+
+ // create thread 2
+ err = fosa_thread_create (&tid2, &th_attr, thread_code, (void *)2);
+ printf("created thread 2 with prio=%d, err=%d\n",params.prio, err);
+ assert(err == 0);
+
+ // create thread 3 - should be rejected
+ err = fosa_thread_create (&tid3, &th_attr, thread_code, (void *)3);
+ printf("created thread 3 (rejected=%d), err=%d\n",
+ (err == FOSA_EREJECT), err);
+
+ err = fosa_thread_attr_destroy(&th_attr);
+ printf("thread attributes object destroyed, err=%d\n",err);
+ assert(err == 0);
+
+ sleep (5);
+
+ //////////////////////////////////////////////////////////////
+ // 2c) Change appsched params
+ //////////////////////////////////////////////////////////////
+ printf("--------------------------------------------------\n");
+ printf("2c) Change appsched params\n");
+
+ err = fosa_thread_set_prio(tid1,14);
+ printf("priority of thread 1 set to 14, err=%d\n", err);
+ assert(err == 0);
+
+ sleep (1);
+
+ params.prio = MX_PRIO - 5;
+ err = fosa_ads_set_appsched_params(tid2, (void *)¶ms, sizeof(params));
+ printf("urgency of thread 2 set to %d, err=%d\n", params.prio, err);
+ assert(err == 0);
+
+ sleep (3);
+
+ //////////////////////////////////////////////////////////////
+ // 2d) Signals
+ //////////////////////////////////////////////////////////////
+ printf("--------------------------------------------------\n");
+ printf("2d) Signals\n");
+
+ signal_action.command = SUSPEND;
+ signal_action.thread_id = tid1;
+ timer_info.sival_ptr = (void *)&signal_action;
+
+ err = fosa_timer_create
+ (FOSA_CLOCK_REALTIME, FOSA_SIGNAL_MAX, timer_info, &timerid);
+ printf("timer created, err=%d\n", err);
+ assert(err == 0);
+
+ timerval = fosa_msec_to_rel_time(500);
+
+ err=fosa_rel_timer_arm(timerid, &timerval);
+ printf("suspend thread 1 in 0.5 secs, err=%d\n", err);
+ assert(err == 0);
+
+ sleep (5);
+
+ signal_action.command = ACTIVATE;
+ err=fosa_rel_timer_arm(timerid, &timerval);
+ printf("activate thread 1 in 0.5 secs, err=%d\n", err);
+ assert(err == 0);
+
+ sleep (3);
+
+ //////////////////////////////////////////////////////////////
+ // 2e) Cause error
+ //////////////////////////////////////////////////////////////
+ printf("--------------------------------------------------\n");
+ printf("2e) Cause error\n");
+
+ signal_action.command = CAUSE_ERROR;
+ err=fosa_rel_timer_arm(timerid, &timerval);
+ printf("causing an ERROR callback in 0.5 secs, err=%d\n", err);
+ assert(err == 0);
+
+ sleep (3);
+
+ //////////////////////////////////////////////////////////////
+ // 2f) Dettach from application scheduler
+ //////////////////////////////////////////////////////////////
+ printf("--------------------------------------------------\n");
+ printf("2f) Dettach from application scheduler\n");
+
+ err = fosa_ads_set_appscheduled (tid1, false);
+ printf("dettach thread 1, err=%d\n", err);
+ assert(err == 0);
+
+ err = fosa_ads_get_appscheduled (tid1, &is_appsched);
+ printf("thread 1 is dettached? %d, err=%d\n", !is_appsched, err);
+ assert(err == 0);
+
+ err = fosa_ads_get_appscheduled (tid2, &is_appsched);
+ printf("thread 2 is dettached? %d, err=%d\n", !is_appsched, err);
+ assert(err == 0);
+
+ fosa_timer_delete(timerid);
+
+ sleep(1000);
+ return 0;
+}
+
+///////////////////////////////////////////////////////
+// 3) Threads Code
+///////////////////////////////////////////////////////
+
+static void *thread_code (void * arg)
+{
+ struct timespec ts = {2, 0};
+ int err, i;
+ char whoami[] = "who am i?";
+ int reply;
+ size_t reply_size;
+ fosa_rel_time_t one_second = fosa_msec_to_rel_time(1000);
+
+ printf("THREAD %d - starts\n", (int)arg);
+ for (i=1;i<50;i++) {
+ nanosleep (&ts, NULL);
+
+ printf("THREAD %d - locking mutex\n", (int)arg);
+ err=fosa_mutex_lock(&lock);
+ assert(err == 0);
+
+ fosa_eat (&one_second);
+
+ printf("THREAD %d - unlocking mutex\n", (int)arg);
+ err=fosa_mutex_unlock(&lock);
+ assert(err == 0);
+
+ printf("THREAD %d - asking with invoke_withdata\n", (int)arg);
+ err = fosa_ads_invoke_withdata
+ (whoami, sizeof(whoami), (void *)&reply, &reply_size);
+ printf("THREAD %d - received reply, correct?: %d, err=%d\n", (int)arg,
+ reply == (int)fosa_thread_self(), err);
+ if (err != 0) {
+ printf("THREAD %d - bye bye!!\n", (int)arg);
+ pthread_exit (NULL);
+ }
+
+ }
+ return NULL;
+}
+
+///////////////////////////////////////////////////////
+// 4) Implementation of Application Defined Callbacks
+///////////////////////////////////////////////////////
+static void fosa_callback_init
+ (void *sched_data, void *arg)
+{
+ fosa_sched_data_t *frsh = (fosa_sched_data_t *)sched_data;
+ int i, err;
+ fosa_signal_t sched_signal = FOSA_SIGNAL_MAX; // HOW TO PUT SIGNALS IF IS OPAQUE??
+
+ printf ("BEGIN CALLBACK: %s \n", __func__);
+ printf ("init args string received: %s \n", (char *)arg);
+
+ err = fosa_ads_set_handled_signal_set(&sched_signal, 1);
+ printf("set signal set, err=%d\n", err);
+ assert(err == 0);
+
+ for (i=0; i<MX_THREADS; i++) {
+ frsh->array_prio[i] = 0;
+ frsh->array_status[i] = 0;
+ }
+ printf ("END CALLBACK: %s \n", __func__);
+}
+
+static void fosa_callback_new_thread
+ (void *sched_data,
+ fosa_thread_id_t thread,
+ fosa_ads_actions_t *actions,
+ fosa_abs_time_t *current_time)
+{
+ int err;
+ unsigned int i, index;
+ fosa_sched_data_t *frsh = (fosa_sched_data_t *)sched_data;
+ appsched_params_t params;
+ size_t size;
+
+ printf ("BEGIN CALLBACK: %s \n", __func__);
+
+ index = MX_THREADS;
+ for (i=0; i<MX_THREADS; i++) {
+ if (frsh->array_status[i] == 0) {
+ index = i;
+ break;
+ }
+ }
+
+ if (index == MX_THREADS) {
+ err = fosa_adsactions_add_reject(actions, thread);
+ assert(err == 0);
+ } else {
+ // Get the priority for the new thread
+ size = sizeof(params);
+ err = fosa_ads_get_appsched_params(thread, (void *)¶ms, &size);
+ assert(err == 0);
+
+ frsh->array_prio[index] = params.prio;
+ frsh->array_status[index] = 1;
+ }
+ printf ("END CALLBACK: %s \n", __func__);
+}
+
+static void fosa_callback_thread_terminate
+ (void *sched_data,
+ fosa_thread_id_t thread,
+ fosa_ads_actions_t *actions,
+ fosa_abs_time_t *current_time)
+{
+ fosa_abs_time_t at_time;
+ int err;
+
+ printf ("BEGIN CALLBACK: %s \n", __func__);
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, &at_time);
+ printf("current time %ld msec\n", fosa_abs_time_to_msec(at_time) );
+ at_time = fosa_abs_time_incr(at_time, fosa_msec_to_rel_time(1000) );
+
+
+ err = fosa_adsactions_add_timeout(actions, FOSA_CLOCK_REALTIME, &at_time);
+ printf("put a timeout of one second, err=%d\n", err);
+ assert(err == 0);
+ printf ("END CALLBACK: %s \n", __func__);
+}
+
+static void fosa_callback_thread_ready
+ (void *sched_data,
+ fosa_thread_id_t thread,
+ fosa_ads_actions_t *actions,
+ fosa_abs_time_t *current_time)
+{
+ printf ("BEGIN CALLBACK: %s \n", __func__);
+ printf ("END CALLBACK: %s \n", __func__);
+}
+
+static void fosa_callback_thread_block
+ (void *sched_data,
+ fosa_thread_id_t thread,
+ fosa_ads_actions_t *actions,
+ fosa_abs_time_t *current_time)
+{
+ int err;
+ fosa_abs_time_t at_time;
+
+ printf ("BEGIN CALLBACK: %s \n", __func__);
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, &at_time);
+ printf("current time %ld msec\n", fosa_abs_time_to_msec(at_time) );
+ at_time = fosa_abs_time_incr(at_time, fosa_msec_to_rel_time(1000) );
+
+ err = fosa_adsactions_add_timeout(actions, FOSA_CLOCK_REALTIME, &at_time);
+ printf("put a timeout of one second, err=%d\n", err);
+ assert(err == 0);
+ printf ("END CALLBACK: %s \n", __func__);
+}
+
+static void fosa_callback_change_sched_param_thread
+ (void *sched_data,
+ fosa_thread_id_t thread,
+ fosa_ads_actions_t *actions,
+ fosa_abs_time_t *current_time)
+{
+ printf ("BEGIN CALLBACK: %s \n", __func__);
+ // HOW DO I KNOW THE REASON IS SETPRIO OR SETSCHEDPARAMS????
+ printf ("END CALLBACK: %s \n", __func__);
+}
+
+static void fosa_callback_explicit_call_with_data
+ (void *sched_data,
+ fosa_thread_id_t thread,
+ const void * msg,
+ size_t msg_size,
+ void *reply,
+ size_t *reply_size,
+ fosa_ads_actions_t *actions,
+ fosa_abs_time_t *current_time)
+{
+ printf ("BEGIN CALLBACK: %s \n", __func__);
+ *((int *)reply) = (int)thread;
+ printf ("received command: %s , answer %d \n", (char *)msg,
+ *((int *)reply));
+ printf ("END CALLBACK: %s \n", __func__);
+}
+
+static void fosa_callback_notification_for_thread
+ (void *sched_data,
+ fosa_thread_id_t thread,
+ fosa_clock_id_t clock,
+ fosa_ads_actions_t *actions,
+ fosa_abs_time_t *current_time)
+{
+ printf ("BEGIN CALLBACK: %s \n", __func__);
+ printf ("END CALLBACK: %s \n", __func__);
+}
+
+static void fosa_callback_timeout // WHY NOT WATCHDOG????
+ (void *sched_data,
+ fosa_ads_actions_t *actions,
+ fosa_abs_time_t *current_time) // WHY IS IN OUT and not IN???
+{
+ printf ("BEGIN CALLBACK: %s \n", __func__);
+ printf("current time %ld msec", fosa_abs_time_to_msec(*current_time) );
+ printf ("END CALLBACK: %s \n", __func__);
+}
+
+static void fosa_callback_signal
+ (void *sched_data,
+ fosa_signal_t signal,
+ fosa_signal_info_t siginfo, // HOW DO I KNOW THE ORIGIN (see signal_info type)
+ fosa_ads_actions_t *actions,
+ fosa_abs_time_t *current_time)
+{
+ int err;
+ signal_action_t *signal_action = (signal_action_t *)siginfo.sival_ptr;
+ fosa_sched_data_t *frsh = (fosa_sched_data_t *)sched_data;
+
+ printf ("BEGIN CALLBACK: %s \n", __func__);
+
+ switch (signal_action->command) {
+ case SUSPEND:
+ err=fosa_adsactions_add_suspend(actions, signal_action->thread_id);
+ printf("suspending thread 1 , err=%d\n", err);
+ assert(err == 0);
+ break;
+ case ACTIVATE:
+ err = fosa_adsactions_add_activate
+ (actions, signal_action->thread_id, frsh->array_prio[0]);
+ printf("activating thread 1, err=%d\n", err);
+ assert(err == 0);
+ break;
+ case CAUSE_ERROR:
+ // cause an error by overwriting actions with 666 ;D
+ *(int *)actions = 666;
+ err = 666;
+ printf("causing an error, err=%d\n", err);
+ break;
+ }
+ printf ("END CALLBACK: %s \n", __func__);
+}
+
+static void fosa_callback_appsched_error
+ (void *sched_data,
+ fosa_thread_id_t thread,
+ fosa_ads_error_cause_t cause,
+ fosa_ads_actions_t *actions)
+{
+ printf ("BEGIN CALLBACK: %s \n", __func__);
+ printf ("END CALLBACK: %s \n", __func__);
+}
--- /dev/null
+include ../../../config.mk
+include ../../../rules.mk
+
+
--- /dev/null
+../test_clock_and_timers/Makefile.omk
\ No newline at end of file
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+#include <unistd.h>
+#include <stdio.h>
+#include <time.h> // for nanosleep
+
+#include "fosa.h"
+
+void * thread_code(void *arg) {
+ printf("Thread executing\n");
+ sleep(1);
+ printf("Thread terminating\n");
+ return NULL;
+}
+
+/////////////////////////////////////////////////////////////
+// Simple test program for FOSA
+//
+// It just checks that the different functions can be called
+// and that they return appropriate values
+/////////////////////////////////////////////////////////////
+
+int main () {
+
+ //////////////////////////////////
+ // Test clock functions
+ //////////////////////////////////
+
+ printf("--------------------------------------------------\n");
+ printf("test get_time\n");
+
+ fosa_abs_time_t current_time;
+ int err;
+ void * obtained;
+ fosa_clock_id_t cpu_clock;
+
+ err=fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time);
+ printf("fosa_clock_get_time for CLOCK_REALTIME %ld msec err=%d\n",
+ fosa_rel_time_to_msec(current_time), err);
+
+ fosa_thread_get_cputime_clock(fosa_thread_self(), &cpu_clock);
+ err=fosa_clock_get_time(cpu_clock, ¤t_time);
+ printf("fosa_clock_get_time for CPU-time clock %ld msec err=%d\n",
+ fosa_rel_time_to_msec(current_time), err);
+
+ /////////////////////////////////////////////
+ // Test thread ids, attributes and creation
+ ////////////////////////////////////////////
+
+ printf("--------------------------------------------------\n");
+ printf("test thread ids and thread creation\n");
+
+ int stsize, prio;
+
+ fosa_thread_id_t tid1=fosa_thread_self();
+ fosa_thread_id_t tid2=fosa_thread_self();
+ printf("equal thread comparison=%d\n",fosa_thread_equal(tid1,tid2));
+
+ fosa_thread_attr_t th_attr;
+
+ err=fosa_thread_attr_init(&th_attr);
+ printf("thread attributes object initialized, err=%d\n",err);
+
+ err=fosa_thread_attr_set_stacksize(&th_attr,40000);
+ printf("thread attr set stack size to 40000, err=%d\n",err);
+
+ err=fosa_thread_attr_get_stacksize(&th_attr,&stsize);
+ printf("thread attr get stack size=%d, err=%d\n",stsize,err);
+
+ err=fosa_thread_attr_set_prio(&th_attr,27);
+ printf("thread attr set prio to 27, err=%d\n",err);
+
+ err=fosa_thread_attr_get_prio(&th_attr,&prio);
+ printf("thread attr get prio=%d, err=%d\n",prio,err);
+
+ err=fosa_thread_create (&tid2, &th_attr, thread_code, NULL);
+ printf("creating thread with default attributes err=%d\n",err);
+
+ sleep(2);
+
+ err=fosa_thread_attr_destroy(&th_attr);
+ printf("thread attributes object destroyed, err=%d\n",err);
+
+ //////////////////////////////////
+ // Test signals
+ //////////////////////////////////
+
+ printf("--------------------------------------------------\n");
+ printf("test signals\n");
+
+ fosa_signal_t received;
+ fosa_signal_info_t sigvalue, value_received;
+ fosa_rel_time_t timeout;
+ fosa_signal_t sig=FOSA_SIGNAL_MIN+1;
+ fosa_signal_t timer_sig=FOSA_SIGNAL_MIN+3;
+ fosa_signal_t siglist[2];
+
+ siglist[0]=sig;
+ siglist[1]=timer_sig;
+
+ timeout = fosa_msec_to_rel_time(1000);
+
+ sigvalue.sival_int=55;
+
+ err=fosa_set_accepted_signals(siglist,2);
+ printf("two signals in set of accepted signals, err=%d\n",err);
+
+ err=fosa_signal_timedwait(siglist,1,&received,&value_received,&timeout);
+ printf("timed wait not implemented; timeoutcode=%d\n",err);
+
+ err=fosa_signal_queue(sig, sigvalue,fosa_thread_self());
+ printf("signal queued with value 55, err=%d\n",err);
+
+ err=fosa_signal_wait(siglist,1,&received, &value_received);
+ printf("timeoutcode=%d signal received=%d value=%d\n",
+ err,received,value_received.sival_int);
+
+ //////////////////////////////////
+ // Test timers and signals
+ //////////////////////////////////
+
+ printf("--------------------------------------------------\n");
+ printf("test timers and signals\n");
+
+ fosa_signal_info_t timer_info;
+ fosa_timer_id_t timerid;
+ fosa_rel_time_t timerval, remaining_time;
+
+ timer_info.sival_int=88;
+ timerval = fosa_msec_to_rel_time(1300);
+
+ err=fosa_timer_create
+ (FOSA_CLOCK_REALTIME, timer_sig, timer_info,&timerid);
+ printf("timer created, err=%d\n",err);
+
+ err=fosa_rel_timer_arm(timerid, &timerval);
+ printf("timer armed for 1.3 secs, err=%d\n",err);
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time);
+ printf("current time %ld msec\n", fosa_rel_time_to_msec(current_time) );
+ printf("wait for timer to expire...\n");
+
+ siglist[0]=timer_sig;
+ err=fosa_signal_wait(siglist,1,&received, &value_received);
+ printf("timeoutcode=%d signal received=%d value=%d\n",
+ err,received,value_received.sival_int);
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time);
+ printf("current time: %ld msec\n", fosa_rel_time_to_msec(current_time) );
+
+ timerval = fosa_msec_to_rel_time(6000);
+ err=fosa_rel_timer_arm(timerid, &timerval);
+ printf("timer armed for 6 secs, err=%d\n",err);
+
+ struct timespec timerval_tspec = {1, 0};
+ printf("sleeping 1 second\n");
+ nanosleep(&timerval_tspec, NULL);
+
+ err=fosa_timer_get_remaining_time(timerid, &remaining_time);
+ printf("timer remaining time: %ld msec\n", fosa_rel_time_to_msec(remaining_time) );
+
+ printf("sleeping 1 second\n");
+ nanosleep(&timerval_tspec, NULL);
+
+ err=fosa_timer_disarm(timerid,&remaining_time);
+ printf("timer disarmed, remaining time: %ld msec, err=%d\n",
+ fosa_rel_time_to_msec(remaining_time), err);
+
+ err=fosa_timer_get_remaining_time(timerid, &remaining_time);
+ printf("timer remaining time after disarm (0?) %ld msec, err=%d\n",
+ fosa_rel_time_to_msec(remaining_time), err);
+
+ fosa_timer_delete(timerid);
+
+
+ //////////////////////////////////
+ // Test thread-specific data
+ //////////////////////////////////
+
+ printf("--------------------------------------------------\n");
+ printf("test thread-specific data\n");
+
+ int value=333;
+ int key;
+ fosa_thread_id_t tid=fosa_thread_self();
+
+ err=fosa_key_create(&key);
+ printf("key created=%d. err=%d\n",key,err);
+
+ fosa_thread_set_specific_data (key, tid, (void *) (&value));
+ printf("specific data set to 333. err=%d\n",err);
+
+ fosa_thread_get_specific_data (key, tid, &obtained);
+ printf("obtained thread specific data=%d\n",*((int *)obtained));
+
+
+ //////////////////////////////////
+ // Test Priorities
+ //////////////////////////////////
+
+ printf("--------------------------------------------------\n");
+ printf("test priorities\n");
+
+
+ err=fosa_thread_set_prio(fosa_thread_self(),14);
+ printf("priority set to 14. err=%d\n",err);
+
+ err=fosa_thread_get_prio(fosa_thread_self(),&prio);
+ printf("prio=%d. err=%d\n",prio,err);
+
+
+ //////////////////////////////////
+ // Test Mutexes
+ //////////////////////////////////
+
+ printf("--------------------------------------------------\n");
+ printf("test mutexes\n");
+
+ fosa_mutex_t lock;
+ int old;
+
+ err=fosa_mutex_init(&lock,24);
+ printf("mutex initialized with ceiling 24. err=%d\n",err);
+
+ err=fosa_mutex_set_prioceiling(&lock,24,&old);
+ printf("mutex priority ceiling changed to 24. old=%d. err=%d\n",old,err);
+
+ err=fosa_mutex_get_prioceiling(&lock,&old);
+ printf("mutex priority ceiling is=%d. err=%d\n",old,err);
+
+ err=fosa_mutex_lock(&lock);
+ printf("mutex locked. err=%d\n",err);
+
+ err=fosa_mutex_unlock(&lock);
+ printf("mutex unlocked. err=%d\n",err);
+
+ err=fosa_mutex_trylock(&lock);
+ printf("mutex try locked. err=%d\n",err);
+
+ err=fosa_mutex_unlock(&lock);
+ printf("mutex unlocked. err=%d\n",err);
+
+ //////////////////////////////////
+ // Test Condition variables
+ //////////////////////////////////
+
+ printf("--------------------------------------------------\n");
+ printf("test condition variables\n");
+
+ fosa_cond_t cond;
+
+ err=fosa_cond_init(&cond);
+ printf("condvar initialized. err=%d\n",err);
+
+ err=fosa_cond_signal(&cond);
+ printf("cond signalled. err=%d\n",err);
+
+ err=fosa_cond_broadcast(&cond);
+ printf("cond broadcast. err=%d\n",err);
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time);
+ printf("current time %ld msec\n", fosa_abs_time_to_msec(current_time) );
+
+ current_time = fosa_abs_time_incr(current_time, fosa_msec_to_rel_time(2000) );
+
+ fosa_mutex_lock(&lock);
+ err=fosa_cond_timedwait(&cond,&lock,¤t_time);
+ fosa_mutex_unlock(&lock);
+ printf("cond timedwait with timeout=2 sec. err=%d\n",err);
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time);
+ printf("current time %ld msec\n", fosa_abs_time_to_msec(current_time) );
+
+ err=fosa_mutex_destroy(&lock);
+ printf("mutex destroyed. err=%d\n",err);
+
+ err=fosa_cond_destroy(&cond);
+ printf("cond destroyed. err=%d\n",err);
+
+ ////////////////////////////////////////
+ // Test Application-defined scheduling
+ ///////////////////////////////////////
+
+ printf("--------------------------------------------------\n");
+ printf("test application-defined scheduling\n");
+
+ fosa_thread_attr_t th1_attr;
+ bool is_appsched;
+
+ err=fosa_thread_attr_init(&th1_attr);
+ printf("thread attributes object initialized, err=%d\n",err);
+
+ err=fosa_thread_attr_set_appscheduled(&th1_attr,true);
+ printf("thread attr set appsched, err=%d\n",err);
+
+ err=fosa_thread_attr_get_appscheduled(&th1_attr,&is_appsched);
+ printf("thread attr get appsched=%d, err=%d\n",is_appsched,err);
+
+ return 0;
+}
--- /dev/null
+include ../../../config.mk
+include ../../../rules.mk
+
+
+test_fosa_long_jump.exe: test_fosa_long_jump.o $(FOSA_PATH)/lib/libfosa_$(PLATFORM).a $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o
+ $(CC) -L$(FOSA_PATH)/lib $< -lfosa_$(PLATFORM) $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o -o $@
+
+
+simple_test_non_local_jump.exe: simple_test_non_local_jump.o $(FOSA_PATH)/lib/libfosa_$(PLATFORM).a $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o
+ $(CC) -L$(FOSA_PATH)/lib $< -lfosa_$(PLATFORM) $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o -o $@
+
+
--- /dev/null
+../test_clock_and_timers/Makefile.omk
\ No newline at end of file
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+
+#include <unistd.h>
+#include <stdio.h>
+
+#include <assert.h>
+#include <stdlib.h> // for exit in assert
+#include <string.h> // for memset
+
+#include "fosa.h"
+
+/*****************************/
+/* D E F I N I T I O N S */
+/*****************************/
+#define RT_ERROR_SIGWAIT -2
+#define RT_ERROR_TIMER -3
+
+#define SIGNAL_TIMER (FOSA_SIGNAL_MAX - 1)
+
+#define SIGNAL_A (FOSA_SIGNAL_MAX - 2)
+#define SIGNAL_KILL_A (FOSA_SIGNAL_MAX - 3)
+
+#define SIGNAL_B (FOSA_SIGNAL_MAX - 4)
+#define SIGNAL_KILL_B (FOSA_SIGNAL_MAX - 5)
+#define SIGNAL_C (FOSA_SIGNAL_MAX - 6)
+#define SIGNAL_KILL_C (FOSA_SIGNAL_MAX - 7)
+
+
+#define PRIO_MAIN 4
+#define PRIO_A 5
+#define PRIO_B 6
+#define PRIO_C 7
+#define PRIO_CATCHER 8
+
+
+typedef struct _my_signal_info_t
+{
+ fosa_rel_time_t eat_time;
+} my_signal_info_t;
+
+typedef struct _my_thread_arg_t
+{
+ char identifier[100];
+ fosa_signal_t signum;
+ fosa_signal_t sigkill;
+} my_thread_arg_t;
+
+
+
+
+/***************************/
+/* P R O T O T Y P E S */
+/***************************/
+static void *controlled_thread(void *thread_arg);
+static void *catcher_thread(void *arg);
+
+static void create_thread(fosa_thread_code_t thread_code,
+ void *arg,
+ int priority,
+ fosa_thread_id_t *tid);
+
+static void time_printf(const char *format, ...);
+
+
+/***************************/
+/* S T A T I C D A T A */
+/***************************/
+static fosa_abs_time_t start_time;
+static bool timer_expired;
+
+
+int main ()
+{
+ int err = -1;
+
+ fosa_thread_id_t tid_A, tid_B, tid_C, tid_catcher;
+ my_thread_arg_t thread_arg_A, thread_arg_B, thread_arg_C;
+ fosa_rel_time_t eat_time_A, eat_time_B, eat_time_C, group_time;
+ fosa_signal_info_t siginfo_A, siginfo_B, siginfo_C, siginfo_timer;
+
+ fosa_thread_set_id_t thread_set_id;
+ fosa_clock_id_t group_clock_id;
+ fosa_timer_id_t group_timer;
+
+ /* Initialize base time and thread arguments */
+ /*********************************************/
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, &start_time);
+
+ strcpy(thread_arg_A.identifier, "THREAD A");
+ thread_arg_A.signum = SIGNAL_A;
+ thread_arg_A.sigkill = SIGNAL_KILL_A;
+ siginfo_A.sival_ptr = &eat_time_A;
+
+ strcpy(thread_arg_B.identifier, "THREAD B");
+ thread_arg_B.signum = SIGNAL_B;
+ thread_arg_B.sigkill = SIGNAL_KILL_B;
+ siginfo_B.sival_ptr = &eat_time_B;
+
+ strcpy(thread_arg_C.identifier, "THREAD C");
+ thread_arg_C.signum = SIGNAL_C;
+ thread_arg_C.sigkill = SIGNAL_KILL_C;
+ siginfo_C.sival_ptr = &eat_time_C;
+
+
+ /* We set our priority and create the threads. The threads */
+ /* will be blocked waiting for the signal. */
+ /************************************************************/
+ err = fosa_thread_set_prio(fosa_thread_self(), fosa_get_priority_min() + PRIO_MAIN);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d with setting main priority\n", err);
+ exit(1);
+ }
+
+ create_thread(controlled_thread, &thread_arg_A, PRIO_A, &tid_A);
+ create_thread(controlled_thread, &thread_arg_B, PRIO_B, &tid_B);
+ create_thread(controlled_thread, &thread_arg_C, PRIO_C, &tid_C);
+
+ create_thread(catcher_thread, NULL, PRIO_CATCHER, &tid_catcher);
+
+
+ /* We create the thread set, get its clock and create a timer */
+ /****************************************************************/
+ err = fosa_thread_set_create(&thread_set_id);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d creating thread_set\n", err);
+ exit(1);
+ }
+
+ err = fosa_get_groupcpu_clock(thread_set_id, &group_clock_id);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d obtaining group clock\n", err);
+ exit(1);
+ }
+
+ err = fosa_timer_create(group_clock_id, SIGNAL_TIMER, siginfo_timer, &group_timer);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d obtaining group CPU timer\n", err);
+ exit(1);
+ }
+
+ /* We add the 3 threads to the set */
+ /*************************************/
+ err = fosa_thread_set_add(thread_set_id, tid_A);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d adding thread to thread set\n", err);
+ exit(1);
+ }
+
+ err = fosa_thread_set_add(thread_set_id, tid_B);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d adding thread to thread set\n", err);
+ exit(1);
+ }
+
+ err = fosa_thread_set_add(thread_set_id, tid_C);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d adding thread to thread set\n", err);
+ exit(1);
+ }
+
+
+ /* First experiment: We arm the group CPU timer with 5 sec and */
+ /* make each thread execute two seconds each. */
+ /****************************************************************/
+ eat_time_A = fosa_msec_to_rel_time(2000);
+ eat_time_B = fosa_msec_to_rel_time(2000);
+ eat_time_C = fosa_msec_to_rel_time(2000);
+
+ group_time = fosa_msec_to_rel_time(5000);
+
+ timer_expired = false;
+ time_printf("MAIN: Arming group timer for 5 seconds\n");
+ err = fosa_rel_timer_arm(group_timer, &group_time);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d queueing signal\n", err);
+ exit(1);
+ }
+
+ err = fosa_signal_queue(SIGNAL_A, siginfo_A, (fosa_thread_id_t) 0);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d queueing signal\n", err);
+ exit(1);
+ }
+
+ err = fosa_signal_queue(SIGNAL_B, siginfo_B, (fosa_thread_id_t) 0);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d queueing signal\n", err);
+ exit(1);
+ }
+
+ err = fosa_signal_queue(SIGNAL_C, siginfo_C, (fosa_thread_id_t) 0);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d queueing signal\n", err);
+ exit(1);
+ }
+
+ time_printf("MAIN: Back after all threads\n");
+
+ assert(timer_expired);
+
+
+ return 0;
+}
+
+
+// ----------------------------------------------------------------
+
+/**
+ * This is a controlled thread. It stays waiting for a signal and
+ * then eats the requested time sent in the signal info.
+ **/
+static void *controlled_thread(void *arg)
+{
+
+ fosa_signal_t signal_set[2];
+ int err;
+
+ my_thread_arg_t *thread_arg = (my_thread_arg_t *) arg;
+
+ time_printf("%s: Initializing\n", thread_arg->identifier);
+
+ signal_set[0] = thread_arg->signum;
+ signal_set[1] = thread_arg->sigkill;
+ err = fosa_set_accepted_signals(signal_set, 2);
+ if (err !=0)
+ {
+ printf ("%s: Error %d while setting the signal mask\n", thread_arg->identifier, err);
+ exit (1);
+ }
+
+
+ while(1)
+ {
+ fosa_signal_t signal_received;
+ fosa_signal_info_t info_received;
+ my_signal_info_t *signal_info;
+
+ err = fosa_signal_wait(signal_set, 2, &signal_received, &info_received);
+ if ( err != 0)
+ {
+ printf("%s: Error %d while waiting for signal\n", thread_arg->identifier, err);
+ exit(1);
+ }
+
+ if (signal_received == thread_arg->sigkill)
+ {
+ time_printf("%s: Terminating\n", thread_arg->identifier);
+ break;
+ }
+
+ signal_info = (my_signal_info_t *) info_received.sival_ptr;
+
+ time_printf("%s: about to eat %ld msec\n", thread_arg->identifier, fosa_rel_time_to_msec(signal_info->eat_time) );
+
+ fosa_eat(&signal_info->eat_time);
+ }
+
+ return NULL;
+}
+
+// ------------------------------------------------------------------
+
+static void *catcher_thread(void *arg)
+{
+ int err = -1;
+ fosa_signal_t signal_set[1];
+
+ time_printf("CATCHER: Initializing\n");
+
+ signal_set[0] = SIGNAL_TIMER;
+ err = fosa_set_accepted_signals(signal_set, 1);
+ if (err !=0)
+ {
+ printf ("CATCHER: Error %d while setting the signal mask\n", err);
+ exit (1);
+ }
+
+ while(1)
+ {
+ fosa_signal_t signal_received;
+ fosa_signal_info_t info_received;
+
+ err = fosa_signal_wait(signal_set, 1, &signal_received, &info_received);
+ if ( err != 0)
+ {
+ printf("CATCHER: Error %d while waiting for signal\n", err);
+ exit(1);
+ }
+
+ time_printf("CATCHER: Group timer expired!!!\n");
+ timer_expired = true;
+ }
+
+ return NULL;
+}
+
+
+// ------------------------------------------------------------------------
+
+static void create_thread(fosa_thread_code_t thread_code,
+ void *arg,
+ int priority,
+ fosa_thread_id_t *tid)
+{
+ fosa_thread_attr_t attr;
+ int err;
+
+ err = fosa_thread_attr_init(&attr);
+ if (err != 0) {
+ printf("Error %d while initializing the attr\n", err);
+ exit(1);
+ }
+
+ err = fosa_thread_attr_set_prio(&attr, fosa_get_priority_min() + priority);
+ if (err != 0) {
+ printf("Error %d while setting priority\n", err);
+ exit(1);
+ }
+
+ err = fosa_thread_create(tid, &attr, thread_code, arg);
+ if (err) {
+ printf("Error %d in fosa_thread_create\n", err);
+ exit(1);
+ }
+}
+
+
+
+// ------------------------------------------------------------------------
+
+
+static void time_printf(const char *format, ...)
+{
+ va_list args;
+
+ fosa_abs_time_t current_time;
+ fosa_rel_time_t interval;
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time);
+ interval = fosa_abs_time_extract_interval(start_time, current_time);
+
+ printf("%ld:", fosa_rel_time_to_msec(interval));
+
+ va_start(args, format);
+ vprintf(format, args);
+ va_end(args);
+}
--- /dev/null
+include ../../../config.mk
+include ../../../rules.mk
+
+
+
+
--- /dev/null
+test_PROGRAMS:=$(basename $(notdir $(wildcard $(SOURCES_DIR)/*.c)))
+
+$(foreach t,$(test_PROGRAMS),\
+$(eval $(t)_SOURCES = $(t).c)\
+$(eval $(t)_LIBS = fosa m)\
+)
+
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+/*
+ Idea of the test:
+
+ This test verifies that the remaining budget of an execution-time
+ clock decreases in a monotonic way with execution time.
+
+ Some traces in a FRSH demo with Thales made us believe that
+ sometimes this does not happen.
+
+ The test consists in creating a monitored thread that execute very
+ small time slots and remain blocked for most of the time. In each
+ block-unblock period the cpu clock is read, the timer is disarmed
+ and armed again.
+
+ We verify that the remaining time obtained when disarming the
+ timer is equal or less than the time used to arm the timer
+ initially.
+
+*/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <time.h> // for nanosleep
+
+#include <assert.h>
+#include <stdlib.h> // for exit in assert
+#include <string.h> // for memset
+
+#include "fosa.h"
+#include <misc/error_checks.h>
+#include <drivers/console_switcher.h>
+
+/*****************************/
+/* D E F I N I T I O N S */
+/*****************************/
+#define NUMBER_OF_TRIES 25
+#define SLEEP_TIME_MSECS 5
+#define ARMED_BUDGET_MSECS 2000
+
+#define MAIN_PRIO 5
+#define MUTEX_CEILING 5
+#define MONITORED_THREAD_PRIO 5
+
+#define TIMER_SIGNAL (FOSA_SIGNAL_MAX - 1)
+
+
+typedef struct _thread_arg_t
+{
+ fosa_cond_t *conditional_variable;
+ fosa_mutex_t *sync_mutex;
+ int *slave_can_run;
+} thread_arg_t;
+
+
+/***************************/
+/* P R O T O T Y P E S */
+/***************************/
+static void *monitored_thread_body(void *arg);
+
+
+int main ()
+{
+ SERIAL_CONSOLE_INIT();
+
+
+ fosa_thread_attr_t monitored_attr;
+ fosa_thread_id_t monitored_tid;
+
+ fosa_cond_t conditional_variable;
+ fosa_mutex_t sync_mutex;
+ int slave_can_run;
+
+ fosa_clock_id_t monitored_clock;
+ fosa_timer_id_t monitored_timer;
+
+ fosa_signal_t signal_set[1];
+ fosa_signal_info_t signal_info_to_send;
+
+ fosa_rel_time_t remaining_time = fosa_msec_to_rel_time(ARMED_BUDGET_MSECS);
+ fosa_rel_time_t interval_to_sleep = fosa_msec_to_rel_time(SLEEP_TIME_MSECS);
+ int i;
+
+
+ thread_arg_t thread_arg;
+
+ /* Set the process-wide signal mask */
+ /************************************/
+ signal_set[0] = TIMER_SIGNAL;
+ CHK( fosa_set_accepted_signals(signal_set, 1) );
+ CHK( fosa_thread_set_prio(fosa_thread_self(), fosa_get_priority_min() + MAIN_PRIO) );
+
+
+ /* We initializa the condvar the mutex and */
+ /* set the predicate to false */
+ /*******************************************/
+ CHK( fosa_cond_init(&conditional_variable) );
+ CHK( fosa_mutex_init(&sync_mutex, fosa_get_priority_min() + MUTEX_CEILING) );
+ slave_can_run = 0;
+
+
+ thread_arg.conditional_variable = &conditional_variable;
+ thread_arg.sync_mutex = &sync_mutex;
+ thread_arg.slave_can_run = &slave_can_run;
+
+ /* We create the monitored thread that will stop in the */
+ /* conditional variable wait. */
+ /********************************************************/
+ thread_arg.conditional_variable = &conditional_variable;
+ thread_arg.sync_mutex = &sync_mutex;
+
+ CHK( fosa_thread_attr_init(&monitored_attr) );
+ CHK( fosa_thread_attr_set_prio(&monitored_attr, fosa_get_priority_min() + MONITORED_THREAD_PRIO) );
+
+ CHK( fosa_thread_create(&monitored_tid, &monitored_attr, monitored_thread_body, &thread_arg) );
+
+ /* We create the CPU timer for the monitored thread */
+ /* and program it for a long expiration period. */
+ /****************************************************/
+ signal_info_to_send.sival_int = 42;
+ CHK( fosa_thread_get_cputime_clock(monitored_tid, &monitored_clock) );
+ CHK( fosa_timer_create(monitored_clock, TIMER_SIGNAL, signal_info_to_send, &monitored_timer) );
+
+
+ for (i = 0; i < NUMBER_OF_TRIES; i++)
+ {
+ long int msecs_armed_after_activation;
+ long int msecs_disarmed_after_blocking;
+ fosa_abs_time_t current_time;
+ fosa_abs_time_t awakening_time;
+ struct timespec awakening_time_tspec;
+
+ /* We first unblock the thread by signalling the condition var */
+ CHK( fosa_mutex_lock(&sync_mutex) );
+ assert(slave_can_run == 0);
+ slave_can_run = 1;
+ CHK( fosa_cond_signal(&conditional_variable) );
+ CHK( fosa_mutex_unlock(&sync_mutex) );
+
+ printf("MAIN: Slave activation # %d\n", i);
+ /* Since we have the lock, we have a higher priority */
+ /* due to the priority ceiling of the mutex. */
+ /****************************************************/
+
+ // We arm the timer
+ msecs_armed_after_activation = fosa_rel_time_to_msec(remaining_time);
+ printf("MAIN: Timer armed with: %ld msec\n", msecs_armed_after_activation);
+ CHK( fosa_rel_timer_arm(monitored_timer, &remaining_time) );
+
+
+ // We let the thread execute something (short) and then block
+ // itself again
+ CHK( fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time) );
+ printf("MAIN: SLEEPING\n");
+ awakening_time = fosa_abs_time_incr(current_time, interval_to_sleep);
+ awakening_time_tspec = fosa_abs_time_to_timespec(awakening_time);
+
+
+ CHK( clock_nanosleep(FOSA_CLOCK_REALTIME, TIMER_ABSTIME, &awakening_time_tspec, NULL) );
+
+
+ // We disarm the timer and release the mutex
+ CHK( fosa_timer_disarm(monitored_timer, &remaining_time) );
+ msecs_disarmed_after_blocking = fosa_rel_time_to_msec(remaining_time);
+
+ printf("MAIN: Timer disarmed with %ld msec\n", msecs_disarmed_after_blocking);
+
+ if (msecs_disarmed_after_blocking > msecs_armed_after_activation)
+ {
+ printf("MAIN: BINGOO Bug reproduced!!!\n");
+ exit(1);
+ }
+
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------
+
+static void *monitored_thread_body(void *arg)
+{
+ thread_arg_t *thread_args = (thread_arg_t *) arg;
+
+ int nr_activation = 0;
+
+ while(1)
+ {
+ printf("SLAVE about to block\n");
+ CHK( fosa_mutex_lock(thread_args->sync_mutex) );
+
+ while (!*(thread_args->slave_can_run))
+ {
+ CHK( fosa_cond_wait(thread_args->conditional_variable,
+ thread_args->sync_mutex) );
+ }
+
+ printf("This comes second\n");
+
+ printf("SLAVE: Activation nr: %d\n", nr_activation);
+ nr_activation++;
+
+ *(thread_args->slave_can_run) = 0;
+ CHK( fosa_mutex_unlock(thread_args->sync_mutex) );
+
+ }
+}
+
+
--- /dev/null
+include ../../../config.mk
+include ../../../rules.mk
+
+testbench_long_jump.exe: testbench_long_jump.c libfosa
+
+test_fosa_long_jump.exe: test_fosa_long_jump.c libfosa
+
+
+
--- /dev/null
+../test_clock_and_timers/Makefile.omk
\ No newline at end of file
--- /dev/null
+ Tests in fosa/src_marte_os/tests/test_non_local_jump
+ ----------------------------------------------------
+simple_test_non_local_jump.c
+ This test checks the ability to make long jumps in MaRTE OS
+ A periodic workload consumes 1ms or 2ms (every 5 iterations)
+ The budget is set to 1.4ms; when exceeded, the operation is aborted
+
+test_fosa_long_jump.c
+ This test checks the ability to make long jumps in FOSA
+ A periodic workload consumes 1ms or 7ms (every 5 iterations)
+ The budget is set to 1.4ms; when exceeded, the operation is aborted
+
+testbench_long_jump.c
+ This test measures the time of a long jump
+ It displays elapsed time for execution of an operation with a budget of 20ms
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+// 11-Jul-2007 SANGORRIN change calibrate and eat because it didn't work for
+// MaRTE OS linux_arch
+// 13-Jul-2007 SANGORRIN substitute calibrate for a new eat that I have added
+// -----------------------------------------------------------------------
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+
+//#include <string.h>
+//#include <errno.h>
+//#include <pthread.h>
+//#include <sched.h>
+//#include <signal.h>
+//#include <frsh.h>
+
+#include "fosa.h"
+
+#include "misc/marte_non_local_jmp.h"
+
+/************************/
+/** Constants and types */
+/************************/
+
+#define BUDGET_OVERRUN_SIGNAL SIGRTMIN+3
+#define RT_ERROR_SIGWAIT -2
+#define RT_ERROR_TIMER -3
+
+typedef struct {
+ fosa_thread_id_t tid;
+ marte_nonlocaljmp_context_t *context_ptr;
+ int dummy;
+} budget_timer_info_t;
+
+
+/************************/
+/** Global Variables */
+/************************/
+
+static marte_nonlocaljmp_context_t context;
+static int error_status;
+
+
+/************************/
+/** Prototypes */
+/************************/
+
+static void * thread_body(void *arg);
+static void * signal_handler_thread (void * arg);
+
+
+/************************************************************************/
+/* Main program */
+/************************************************************************/
+
+int main()
+{
+ fosa_signal_t set[1];
+ fosa_thread_attr_t attr;
+
+ fosa_thread_id_t tid1, tid2;
+ int terror = 0;
+
+ // Print test header
+ printf("\n");
+ printf("This test checks the ability to make long jumps in MaRTE OS\n");
+ printf("A periodic workload consumes 1ms or 2ms (every 5 iterations)\n");
+ printf("The budget is set to 1.4ms; when exceeded, the operation is aborted\n");
+ printf("\n");
+
+ // set signal mask
+ set[0]=BUDGET_OVERRUN_SIGNAL;
+ if (fosa_set_accepted_signals(set, 1) !=0) {
+ printf ("Error while setting the signal mask\n");
+ exit (1);
+ }
+
+ // Create the thread attributes object
+ if (fosa_thread_attr_init (&attr) != 0) {
+ printf("Error while initializing the attributes\n");
+ exit(1);
+ }
+
+ if (fosa_thread_attr_set_prio (&attr,fosa_get_priority_max()-2) != 0) {
+ printf("Error while setting schedparam\n");
+ exit(1);
+ }
+
+
+ /* create the signal handler thread */
+ terror = fosa_thread_create(&tid1, &attr, signal_handler_thread, NULL);
+ if (terror) {
+ printf("Error in pthread_create signal handler\n");
+ exit(1);
+ }
+
+ // set priority of periodic thread
+ if (fosa_thread_attr_set_prio (&attr,fosa_get_priority_min()+3) != 0) {
+ printf("Error while setting schedparam\n");
+ exit(1);
+ }
+
+ /* create the periodic thread */
+ terror = fosa_thread_create(&tid2, &attr, thread_body, NULL);
+ if (terror) {
+ printf("Error in pthread_create periodic thread\n");
+ exit(1);
+ }
+
+ printf("Main goes to sleep...\n");
+ sleep(20000);
+
+ return 0;
+}
+
+// work to be aborted if too long
+void work() {
+ static int i=0;
+ fosa_rel_time_t exec_time = fosa_msec_to_rel_time(1000); // 1 second
+
+ i++;
+ printf("start work (eat 1s) %d\n",i);
+ // regular code
+ // eat one second of budget
+ fosa_eat(&exec_time);
+ // every five cycles eat an additional one second of budget */
+ if (i%5==0) {
+ printf("start eating 1s more\n");
+ fosa_eat(&exec_time);
+ }
+ printf("finish work\n");
+}
+
+
+
+/* ------------------------------------------------------------ */
+/** Body of periodic thread that consumes budget */
+
+static void * thread_body(void *thread_arg)
+{
+ fosa_rel_time_t period = fosa_msec_to_rel_time(2500);
+ fosa_rel_time_t budget = fosa_msec_to_rel_time(1400);
+ fosa_abs_time_t activation_time, after_activation_time;
+ fosa_rel_time_t elapsed_time;
+ struct timespec activation_time_tspec;
+
+ fosa_timer_id_t timerid;
+ fosa_clock_id_t clockid;
+ budget_timer_info_t timerinfo;
+ fosa_signal_info_t siginfo;
+ int i=0;
+
+ timerinfo.tid=pthread_self();
+ timerinfo.context_ptr=&context;
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME,&activation_time);
+
+ if (fosa_thread_get_cputime_clock(timerinfo.tid,&clockid) !=0) {
+ error_status=RT_ERROR_TIMER;
+ pthread_exit ( (void*)&error_status);
+ }
+
+ // create budget timer
+ siginfo.sival_ptr=(void *)(&timerinfo);
+ if (fosa_timer_create (clockid,BUDGET_OVERRUN_SIGNAL,siginfo,&timerid)
+ != 0)
+ {
+ error_status=RT_ERROR_TIMER;
+ pthread_exit ( (void*)&error_status);
+ }
+
+ printf("Start periodic thread body with 1400ms budget\n");
+
+ // main loop
+ while(1) {
+
+ // set the budget timer
+ if (fosa_rel_timer_arm(timerid, &budget) != 0) {
+ error_status=RT_ERROR_TIMER;
+ pthread_exit ( (void*)&error_status);
+ }
+
+ printf("Begin thread at: %ld msec\n",
+ fosa_abs_time_to_msec(activation_time) );
+ i++;
+ timerinfo.dummy=i;
+
+ // save context
+
+ marte_nonlocaljmp_savecontext(&context);
+ printf ("context saved\n");
+
+ if (marte_nonlocaljmp_afterjmp(&context)==0) {
+ work();
+ } else {
+ // code executed if asynchronous jump instruction invoked */
+ printf("Work was aborted\n");
+ }
+
+ //printf("after block %d\n",marte_nonlocaljmp_afterjmp(&context));
+ printf("Work block was finished\n");
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, &after_activation_time);
+ elapsed_time = fosa_abs_time_extract_interval
+ (activation_time, after_activation_time);
+ printf("End thread. Elapsed: %ld msec\n",
+ fosa_rel_time_to_msec(elapsed_time) );
+
+ // sleep for a while
+ activation_time = fosa_abs_time_incr(activation_time, period);
+ activation_time_tspec = fosa_abs_time_to_timespec(activation_time);
+
+ clock_nanosleep(FOSA_CLOCK_REALTIME,TIMER_ABSTIME,
+ &activation_time_tspec, NULL);
+ } // while
+}
+
+
+/*----------------------------------------------------------------------*/
+
+/** Body of signal handler thread
+ * The signal mask is assumed to be inherited from the parent
+ */
+
+void * signal_handler_thread (void * arg) {
+
+ fosa_signal_t set[1];
+ fosa_signal_t sig;
+ fosa_signal_info_t siginfo;
+
+ budget_timer_info_t *info;
+
+ // Wait for a budget overrun signal
+ set[0]=BUDGET_OVERRUN_SIGNAL;
+ while (1) {
+ if ((fosa_signal_wait(set, 1, &sig, &siginfo)) == -1) {
+ error_status=RT_ERROR_SIGWAIT;
+ pthread_exit ( (void*)&error_status);
+ }
+ // Restore periodic thread's context
+ printf("About to restore context\n");
+ info=((budget_timer_info_t*) (siginfo.sival_ptr));
+ marte_nonlocaljmp_restorecontext(info->tid,info->context_ptr);
+ printf("Restored thread %d\n",info->dummy);
+ }
+}
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h> // For clock_nanosleep
+
+#include "fosa.h"
+
+#include <misc/error_checks.h>
+
+
+
+/*************************/
+/* D E F I N I T I O N S */
+/*************************/
+#define PERIODIC_THREAD_PRIORITY (fosa_get_priority_min() + 3)
+#define MAIN_THREAD_PRIORITY (fosa_get_priority_min() + 5)
+
+
+/*************************/
+/* P R O T O T Y P E S */
+/*************************/
+static void *periodic_code(void *thread_arg);
+
+/**********************************/
+/* S T A T I C V A R I A B L E S */
+/**********************************/
+static fosa_long_jump_context_t context;
+static void work_under_an_interruptible_budget();
+
+
+int main()
+{
+ fosa_thread_attr_t periodic_attr;
+ fosa_signal_t signal_set[1];
+ fosa_thread_id_t periodic_tid;
+
+ // Print test header
+ printf("\n");
+ printf("This test checks the ability to make long jumps in FOSA\n");
+ printf("A periodic workload consumes 1ms or 7ms (every 5 iterations)\n");
+ printf("The budget is set to 1.4ms; when exceeded, the operation is aborted\n");
+ printf("\n");
+
+ memset(&context, 0, sizeof(context) );
+
+ memset(&periodic_attr, 0, sizeof(periodic_attr) );
+ memset(&signal_set, 0, sizeof(signal_set) );
+ memset(&periodic_tid, 0, sizeof(periodic_tid) );
+
+
+ /* We set the signal mask */
+ signal_set[0] = FOSA_LONG_JUMP_SIGNAL;
+
+ CHK( fosa_set_accepted_signals(signal_set, 1) );
+
+ /* We create a new thread with a given priority */
+ CHK( fosa_thread_attr_init(&periodic_attr) );
+ CHK( fosa_thread_attr_set_prio
+ (&periodic_attr, PERIODIC_THREAD_PRIORITY) );
+ CHK( fosa_thread_create
+ (&periodic_tid, &periodic_attr, periodic_code, NULL) );
+
+ printf("Main goes to sleep...\n");
+
+ sleep(2000);
+
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+
+
+static void *periodic_code(void *thread_arg)
+{
+ fosa_rel_time_t period = fosa_msec_to_rel_time(2500);
+
+ fosa_thread_id_t jump_handler_thread;
+
+ fosa_signal_t jump_signal;
+ fosa_signal_info_t jump_signal_info;
+
+ fosa_clock_id_t clock_id;
+ fosa_timer_id_t jump_timer;
+
+ memset(&jump_signal, 0, sizeof(jump_signal) );
+ memset(&jump_signal_info, 0, sizeof(jump_signal_info) );
+ memset(&jump_handler_thread, 0, sizeof(jump_handler_thread) );
+ memset(&clock_id, 0, sizeof(clock_id) );
+ memset(&jump_timer, 0, sizeof(jump_timer) );
+
+
+ /* We install a long jump handler */
+ /* - This creates the thread that will wait for */
+ /* FOSA_JUMP_SIGNAL */
+ /************************************************/
+ CHK( fosa_long_jump_install_handler(&jump_signal, &jump_handler_thread) );
+
+ /* We create a budget timer using the thread's CPU clock */
+ /* */
+ /* When the timer expires: */
+ /* - Triggers the signal corresponding to signal jump */
+ /* - Provides a pointer to the context in siginfo. */
+ /* */
+ /* This signal is delivered to the handler thread. */
+ /*********************************************************/
+ CHK( fosa_thread_get_cputime_clock( fosa_thread_self(), &clock_id) );
+ jump_signal_info.sival_ptr = &context;
+ CHK( fosa_timer_create_with_receiver
+ (clock_id, jump_signal, jump_signal_info,
+ &jump_timer, jump_handler_thread) );
+
+
+ printf("Start periodic work with budget=1400ms\n");
+
+ /* Periodic loop */
+ /*****************/
+ while (1)
+ {
+ int jumped = -1;
+ fosa_rel_time_t budget = fosa_msec_to_rel_time(1400);
+ fosa_abs_time_t activation_time;
+ struct timespec activation_time_tspec;
+ fosa_abs_time_t after_activation_time;
+ fosa_rel_time_t elapsed_time;
+
+ jumped = 0;
+
+ /* For statistical purposes we read the activation time */
+ CHK( fosa_clock_get_time(FOSA_CLOCK_REALTIME, &activation_time) );
+
+
+
+ /* Start of the interruptible block */
+ /************************************/
+
+ /* We arm the jump_timer */
+ CHK( fosa_rel_timer_arm(jump_timer, &budget) );
+
+ /* This is the point where the jump returns */
+ CHK( fosa_long_jump_save_context(&context) );
+
+ /* Query if we come from a jump */
+ CHK( fosa_long_jump_was_performed(&context, &jumped) );
+ if (!jumped)
+ {
+ /* HERE COMES THE WORK THAT CAN BE INTERRUPTED */
+ work_under_an_interruptible_budget();
+ CHK( fosa_timer_disarm(jump_timer, NULL) );
+ printf("NOT JUMPPED\n");
+ }
+ else
+ {
+ printf("JUMPPPPPEEED\n");
+ }
+
+
+ /* End of interruptible work */
+ /*****************************/
+
+ printf("After interruptible block\n");
+
+ /* Now we measure the time duration of the block */
+ /*************************************************/
+ CHK( fosa_clock_get_time(FOSA_CLOCK_REALTIME, &after_activation_time) );
+ elapsed_time = fosa_abs_time_extract_interval
+ (activation_time, after_activation_time);
+ printf("Execution time: %ld msec\n",
+ fosa_rel_time_to_msec(elapsed_time) );
+
+ /* And we program the next loop */
+ activation_time = fosa_abs_time_incr(activation_time, period);
+ activation_time_tspec = fosa_abs_time_to_timespec(activation_time);
+ clock_nanosleep(FOSA_CLOCK_REALTIME, TIMER_ABSTIME,
+ &activation_time_tspec,NULL);
+ }
+
+ return NULL;
+}
+
+
+// ------------------------------------------------------------------------------
+
+static void work_under_an_interruptible_budget()
+{
+ static int i = 0;
+ fosa_rel_time_t exec_time = fosa_msec_to_rel_time(1000); // 1 sec
+
+ i++;
+ printf("Start regular work (eat 1s)\n");
+
+ fosa_eat(&exec_time);
+
+ /* Once in every 5 executions we work over the budget */
+ if (i % 5 == 0)
+ {
+ printf("Eat additional time (6s more) \n");
+ fosa_eat(&exec_time);
+ fosa_eat(&exec_time);
+ fosa_eat(&exec_time);
+ fosa_eat(&exec_time);
+ fosa_eat(&exec_time);
+ fosa_eat(&exec_time);
+ }
+
+ printf("End regular work\n");
+
+}
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+/*
+ TO DO:
+
+ - Define a pthread_join equivalent in FOSA (and also the detachable
+ argument).
+ - Define a clock_nanosleep equivalent in FOSA.
+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h> // For clock_nanosleep
+
+#include "fosa.h"
+
+#include <misc/error_checks.h>
+
+
+/*************************/
+/* D E F I N I T I O N S */
+/*************************/
+#define PERIODIC_THREAD_PRIORITY (fosa_get_priority_min() + 5)
+#define MAIN_THREAD_PRIORITY (fosa_get_priority_min() + 3)
+
+#define NUMBER_OF_JUMPS 100
+
+typedef struct _results_t
+{
+ double first_jump_interval_ms;
+ double average_jump_interval_ms;
+ double min_jump_interval_ms;
+ int iteration_min_jump_interval;
+ double max_jump_interval_ms;
+ int iteration_max_jump_interval;
+ double total_jump_interval_ms;
+ int number_of_jumps;
+} results_t;
+
+/*************************/
+/* P R O T O T Y P E S */
+/*************************/
+static void *periodic_code(void *thread_arg);
+
+/**********************************/
+/* S T A T I C V A R I A B L E S */
+/**********************************/
+static fosa_long_jump_context_t context;
+static void work_under_an_interruptible_budget();
+
+fosa_abs_time_t before_jump_timestamp;
+
+
+int main()
+{
+ fosa_thread_attr_t periodic_attr;
+ fosa_signal_t signal_set[1];
+ fosa_thread_id_t periodic_tid;
+ results_t results;
+
+ // Display a header text
+ printf("\n");
+ printf("This test measures the time of a long jump\n");
+ printf("It displays elapsed time for execution of an operation with a budget of 20ms\n");
+ printf("\n");
+
+ memset(&context, 0, sizeof(context) );
+
+
+ /* We set the signal mask */
+ signal_set[0] = FOSA_LONG_JUMP_SIGNAL;
+ CHK( fosa_set_accepted_signals(signal_set, 1) );
+
+ /* We create a new thread with a given priority */
+ CHK( fosa_thread_set_prio(fosa_thread_self(), MAIN_THREAD_PRIORITY) );
+
+ CHK( fosa_thread_attr_init(&periodic_attr) );
+ CHK( fosa_thread_attr_set_prio
+ (&periodic_attr, PERIODIC_THREAD_PRIORITY) );
+ CHK( fosa_thread_create
+ (&periodic_tid, &periodic_attr, periodic_code, &results) );
+
+ printf("Main waits for the periodic code to finish...\n");
+ pthread_join(periodic_tid, NULL);
+
+ results.average_jump_interval_ms =
+ results.total_jump_interval_ms/results.number_of_jumps;
+
+ printf("------------ RESULTS -------------\n");
+ printf("First Time: %6.3f ms\n Max Time: %6.3f ms Iteration %d Min Time: %6.3f ms Iteration %d\n",
+ results.first_jump_interval_ms, results.max_jump_interval_ms,
+ results.iteration_max_jump_interval,
+ results.min_jump_interval_ms, results.iteration_min_jump_interval);
+ printf("Average_time: %6.3f ms Total jumps: %d\n",
+ results.average_jump_interval_ms, results.number_of_jumps);
+
+ printf("End of test\n");
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+
+
+static void *periodic_code(void *thread_arg)
+{
+ fosa_thread_id_t jump_handler_thread;
+
+ fosa_signal_t jump_signal;
+ fosa_signal_info_t jump_signal_info;
+
+ fosa_clock_id_t clock_id;
+ fosa_timer_id_t jump_timer;
+
+ /* testbench data */
+ results_t *results;
+ int first_time = 1;
+
+
+ results = (results_t *) thread_arg;
+
+ /* We install a long jump handler */
+ /* - This creates the thread that will wait for */
+ /* FOSA_JUMP_SIGNAL */
+ /************************************************/
+ CHK( fosa_long_jump_install_handler(&jump_signal, &jump_handler_thread) );
+
+ /* We create a budget timer using the thread's CPU clock */
+ /* */
+ /* When the timer expires: */
+ /* - Triggers the signal corresponding to signal jump */
+ /* - Provides a pointer to the context in siginfo. */
+ /* */
+ /* This signal is delivered to the handler thread. */
+ /*********************************************************/
+ CHK( fosa_thread_get_cputime_clock( fosa_thread_self(), &clock_id) );
+ jump_signal_info.sival_ptr = &context;
+ CHK( fosa_timer_create_with_receiver
+ (clock_id, jump_signal, jump_signal_info,
+ &jump_timer, jump_handler_thread) );
+
+ results->number_of_jumps = 0;
+
+ /* Periodic loop */
+ /*****************/
+ while (results->number_of_jumps < NUMBER_OF_JUMPS)
+ {
+ int jumped = -1;
+ fosa_rel_time_t budget = fosa_msec_to_rel_time(20); // 20 ms
+
+ fosa_abs_time_t after_jump_timestamp;
+ fosa_rel_time_t jump_interval;
+ double jump_interval_ms = 0.0;
+
+
+
+ /* We initialise variables */
+ jumped = 0;
+ memset(&before_jump_timestamp, 0, sizeof(before_jump_timestamp) );
+
+
+ /* Start of the interruptible block */
+ /************************************/
+
+ /* We arm the jump_timer */
+ fosa_rel_timer_arm(jump_timer, &budget);
+
+
+ /* This is the point where the jump returns */
+ fosa_long_jump_save_context(&context);
+
+ /* Query if we come from a jump */
+ fosa_long_jump_was_performed(&context, &jumped);
+ if (!jumped)
+ {
+ /* HERE COMES THE WORK THAT CAN BE INTERRUPTED */
+ work_under_an_interruptible_budget();
+ printf("We should not arrive here \n");
+ exit(1);
+ }
+ else
+ {
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, &after_jump_timestamp);
+
+ results->number_of_jumps++;
+ jump_interval = fosa_abs_time_extract_interval
+ (before_jump_timestamp, after_jump_timestamp);
+ jump_interval_ms = fosa_rel_time_to_double(jump_interval)*1.0e6;
+
+ if (first_time)
+ {
+ results->first_jump_interval_ms = jump_interval_ms;
+
+ results->max_jump_interval_ms = jump_interval_ms;
+ results->iteration_max_jump_interval = results->number_of_jumps;
+
+ results->min_jump_interval_ms = jump_interval_ms;
+ results->iteration_min_jump_interval = results->number_of_jumps;
+
+ first_time = 0;
+ }
+ results->total_jump_interval_ms += jump_interval_ms;
+
+ if (jump_interval_ms > results->max_jump_interval_ms)
+ {
+ results->max_jump_interval_ms = jump_interval_ms;
+ results->iteration_max_jump_interval = results->number_of_jumps;
+ }
+
+ if (jump_interval_ms < results->min_jump_interval_ms)
+ {
+ results->min_jump_interval_ms = jump_interval_ms;
+ results->iteration_min_jump_interval = results->number_of_jumps;
+ }
+
+ printf("Jump Iteration: %d\r", results->number_of_jumps);
+ }
+
+ /* End of interruptible work */
+ /*****************************/
+ }
+
+
+
+ return NULL;
+}
+
+
+// ----------------------------------------------------------------------------
+
+static void work_under_an_interruptible_budget()
+{
+ /* This must be measured */
+ while(1)
+ {
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, &before_jump_timestamp);
+ }
+
+}
--- /dev/null
+include ../../../config.mk
+include ../../../rules.mk
+
+
--- /dev/null
+../test_clock_and_timers/Makefile.omk
\ No newline at end of file
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include <assert.h>
+#include <stdio.h>
+#include "fosa.h"
+
+int main () {
+
+ int ret;
+ fosa_resource_id_t cpu_id;
+
+ ret = fosa_get_cpu_resource_id(&cpu_id);
+ assert (ret == 0);
+
+ printf("CPU ID: %u\n", cpu_id);
+
+ return 0;
+}
--- /dev/null
+include ../../../config.mk
+include ../../../rules.mk
+
+
+test_fosa_long_jump.exe: test_fosa_long_jump.o $(FOSA_PATH)/lib/libfosa_$(PLATFORM).a $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o
+ $(CC) -L$(FOSA_PATH)/lib $< -lfosa_$(PLATFORM) $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o -o $@
+
+
+simple_test_non_local_jump.exe: simple_test_non_local_jump.o $(FOSA_PATH)/lib/libfosa_$(PLATFORM).a $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o
+ $(CC) -L$(FOSA_PATH)/lib $< -lfosa_$(PLATFORM) $(FOSA_PATH)/marte_non_local_jump/non_local_jump.o -o $@
+
+
--- /dev/null
+../test_clock_and_timers/Makefile.omk
\ No newline at end of file
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "fosa.h"
+
+#define TEST_SIGNAL (SIGRTMIN + 6)
+
+int main()
+{
+ int terror = -1;
+
+ fosa_abs_time_t past_time;
+ fosa_abs_time_t current_time;
+ fosa_timer_id_t timer;
+
+ fosa_signal_t signal_set[1];
+ fosa_signal_info_t signal_info;
+ fosa_signal_t signal_received;
+
+ int my_test_value = 42;
+ fosa_rel_time_t eat_time = fosa_msec_to_rel_time(2000);
+
+
+
+ /* We block the signals that we are going to process */
+ /*****************************************************/
+ signal_set[0] = TEST_SIGNAL;
+ terror = fosa_set_accepted_signals(signal_set, 1);
+ if (terror != 0) exit(1);
+
+
+
+ /* We create a timer based on the FOSA_CLOCK_REALTIME */
+ /******************************************************/
+ signal_info.sival_int = my_test_value;
+ terror = fosa_timer_create(FOSA_CLOCK_REALTIME, TEST_SIGNAL, signal_info, &timer);
+ if (terror != 0) exit(1);
+
+ /* I get the time BEFORE doing the eat */
+ /***************************************/
+ terror = fosa_clock_get_time(FOSA_CLOCK_REALTIME, &past_time);
+ if (terror != 0) exit(1);
+ printf("Current time: %ld msec\n", fosa_abs_time_to_msec(past_time) );
+
+ /* Now I do some work for some secs */
+ /************************************/
+ fosa_eat(&eat_time);
+
+ /* I read the time again */
+ /*************************/
+ terror = fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time);
+ if (terror != 0) exit(1);
+ printf("Current time: %ld msec\n", fosa_abs_time_to_msec(current_time) );
+
+ /* I arm the timer to the past */
+ /* Since we have blocked this signal, the signal should be stored */
+ /******************************************************************/
+ printf("Arming the timer\n");
+ terror = fosa_abs_timer_arm(timer, &past_time);
+
+
+ /* Now I do the sigwait */
+ /************************/
+ printf("Waiting for the signal\n");
+ terror = fosa_signal_wait(signal_set, 1, &signal_received, &signal_info);
+ if (terror != 0) exit(1);
+
+ printf("Signal accepted!!!\n");
+
+ return 0;
+}
--- /dev/null
+include ../../../config.mk
+include ../../../rules.mk
--- /dev/null
+../test_clock_and_timers/Makefile.omk
\ No newline at end of file
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+#include "fosa.h"
+#include <assert.h>
+#include <time.h> /* for timespec */
+#include <stdio.h> /* for printf */
+#include <string.h> /* for memcmp */
+
+static int check_exact_abs_msec(fosa_abs_time_t abs_time, long msec);
+static int check_exact_rel_msec(fosa_rel_time_t rel_time, long msec);
+
+int main()
+{
+
+ struct timespec tspec1 = {1, 500000000};
+ struct timespec tspec2 = {0, 400000000};
+ struct timespec tspec_result;
+
+ fosa_rel_time_t rel_time1 = fosa_msec_to_rel_time(1500);
+ fosa_rel_time_t rel_time2 = fosa_msec_to_rel_time(400);
+ fosa_rel_time_t rel_time_aux = fosa_msec_to_rel_time(1500);
+ fosa_rel_time_t rel_time_result;
+
+ fosa_abs_time_t abs_time1 = fosa_msec_to_abs_time(1500);
+ fosa_abs_time_t abs_time2 = fosa_msec_to_abs_time(400);
+ fosa_abs_time_t abs_time_aux = fosa_msec_to_abs_time(1500);
+ fosa_abs_time_t abs_time_result;
+
+ long numeric;
+ bool test;
+
+ /* fosa_abs_time_incr */
+ abs_time_result = fosa_abs_time_incr(abs_time1, rel_time2);
+ assert( check_exact_abs_msec(abs_time_result, 1900) );
+
+ /* fosa_abs_time_decr */
+ abs_time_result = fosa_abs_time_decr(abs_time1, rel_time2);
+ assert( check_exact_abs_msec(abs_time_result, 1100) );
+
+ /* fosa_abs_time_decr (negative) */
+ abs_time_result = fosa_abs_time_decr(abs_time2, rel_time1);
+// assert( check_exact_abs_msec(abs_time_result, -1100) );
+
+ /* fosa_abs_time_extract_interval */
+ rel_time_result = fosa_abs_time_extract_interval(abs_time2, abs_time1);
+ assert( check_exact_rel_msec(rel_time_result, 1100) );
+
+ /* fosa_abs_time_extract_interval (negative) */
+ rel_time_result = fosa_abs_time_extract_interval(abs_time1, abs_time2);
+// assert( check_exact_rel_msec(rel_time_result, -1100) );
+
+ /* fosa_rel_time_add */
+ rel_time_result = fosa_rel_time_add(rel_time1, rel_time2);
+ assert( check_exact_rel_msec(rel_time_result, 1900) );
+
+ /* fosa_rel_time_decr */
+ rel_time_result = fosa_rel_time_decr(rel_time1, rel_time2);
+ assert( check_exact_rel_msec(rel_time_result, 1100) );
+
+ /* fosa_rel_time_decr (negative) */
+ rel_time_result = fosa_rel_time_decr(rel_time2, rel_time1);
+// assert( check_exact_rel_msec(rel_time_result, 1100) );
+
+/*
+ struct timespec t1 = {0, 876352172};
+ fosa_rel_time_t t1_rel = fosa_timespec_to_rel_time(t1);
+ long factor = 573102543;
+ struct timespec product = {502239658, 336773396};
+ fosa_rel_time_t product_rel = fosa_timespec_to_rel_time(product);
+*/
+
+ struct timespec t1 = {0, 876352172};
+ struct timespec product = {50223965, 570771688};
+ long factor = 57310254;
+ struct timespec product_divided_by_17 = {2954350, 915927746}; // inexact division
+ struct timespec product_divided_by_3 = {16741321, 856923896}; // exact division
+
+ fosa_rel_time_t t1_rel = fosa_timespec_to_rel_time(t1);
+ fosa_rel_time_t product_rel = fosa_timespec_to_rel_time(product);
+ fosa_rel_time_t product_17_rel = fosa_timespec_to_rel_time(product_divided_by_17);
+ fosa_rel_time_t product_3_rel = fosa_timespec_to_rel_time(product_divided_by_3);
+
+ /* fosa_rel_time_times_integer */
+ /* fosa_rel_time_divided_by_integer */
+ rel_time_result = fosa_rel_time_times_integer(rel_time2, 4);
+ assert( check_exact_rel_msec(rel_time_result, 1600) );
+
+ rel_time_result = fosa_rel_time_divided_by_integer(rel_time_result, 4);
+ assert( check_exact_rel_msec(rel_time_result, 400) );
+
+ rel_time_result = fosa_rel_time_times_integer(t1_rel, factor);
+ assert( fosa_rel_time_equal(rel_time_result, product_rel) );
+
+ rel_time_result = fosa_rel_time_divided_by_integer(product_rel, factor);
+ assert( fosa_rel_time_equal(rel_time_result, t1_rel) );
+
+ rel_time_result = fosa_rel_time_divided_by_integer(product_rel, 17);
+ assert( fosa_rel_time_equal(rel_time_result, product_17_rel) );
+
+ rel_time_result = fosa_rel_time_divided_by_integer(product_rel, 3);
+ assert( fosa_rel_time_equal(rel_time_result, product_3_rel) );
+
+ /* fosa_abs_time_smaller */
+ test = fosa_abs_time_smaller(abs_time1, abs_time2);
+ assert(test == false);
+
+ test = fosa_abs_time_smaller(abs_time1, abs_time_aux);
+ assert(test == false);
+
+ test = fosa_abs_time_smaller(abs_time2, abs_time1);
+ assert(test);
+
+ /* fosa_rel_time_smaller */
+ test = fosa_rel_time_smaller(rel_time1, rel_time2);
+ assert(test == false);
+
+ test = fosa_rel_time_smaller(rel_time1, rel_time_aux);
+ assert(test == false);
+
+ test = fosa_rel_time_smaller(rel_time2, rel_time1);
+ assert(test);
+
+ /* fosa_abs_time_smaller_or_equal */
+ test = fosa_abs_time_smaller_or_equal(abs_time1, abs_time2);
+ assert(test == false);
+
+ test = fosa_abs_time_smaller_or_equal(abs_time1, abs_time_aux);
+ assert(test);
+
+ test = fosa_abs_time_smaller_or_equal(abs_time2, abs_time1);
+ assert(test);
+
+ /* fosa_rel_time_smaller_or_equal */
+ test = fosa_rel_time_smaller_or_equal(rel_time1, rel_time2);
+ assert(test == false);
+
+ test = fosa_rel_time_smaller_or_equal(rel_time1, rel_time_aux);
+ assert(test);
+
+ test = fosa_rel_time_smaller_or_equal(rel_time2, rel_time1);
+ assert(test);
+
+ /* fosa_msec_to_rel_time */
+ rel_time_result = fosa_msec_to_rel_time(1850);
+ assert( check_exact_rel_msec(rel_time_result, 1850) );
+
+ /* fosa_rel_time_to_msec */
+ numeric = fosa_rel_time_to_msec(rel_time1);
+ assert(numeric == 1500);
+
+ /* fosa_msec_to_abs_time */
+ abs_time_result = fosa_msec_to_rel_time(1320);
+ assert( check_exact_abs_msec(abs_time_result, 1320) );
+
+ /* fosa_abs_time_to_msec */
+ numeric = fosa_abs_time_to_msec(abs_time2);
+ assert(numeric == 400);
+
+ /* fosa_usec_to_rel_time */
+ rel_time_result = fosa_usec_to_rel_time(1850000);
+ assert( check_exact_rel_msec(rel_time_result, 1850) );
+
+ /* fosa_rel_time_to_usec */
+ numeric = fosa_rel_time_to_usec(rel_time1);
+ assert(numeric == 1500000);
+
+ /* fosa_msec_to_abs_time */
+ abs_time_result = fosa_usec_to_rel_time(1320000);
+ assert( check_exact_abs_msec(abs_time_result, 1320) );
+
+ /* fosa_abs_time_to_msec */
+ numeric = fosa_abs_time_to_usec(abs_time2);
+ assert(numeric == 400000);
+
+ /* fosa_timespec_to_rel_time */
+ struct timespec tspec_aux = {1, 750000000};
+ rel_time_result = fosa_timespec_to_rel_time(tspec_aux);
+ assert( check_exact_rel_msec(rel_time_result, 1750) );
+
+ /* fosa_rel_time_to_timespec */
+ tspec_result = fosa_rel_time_to_timespec(rel_time1);
+ test = memcmp(&tspec_result, &tspec1, sizeof(tspec_result) );
+ assert(test == 0);
+
+ /* fosa_timespec_to_abs_time */
+ struct timespec tspec_aux_extra = {1, 200000000};
+ abs_time_result = fosa_timespec_to_abs_time(tspec_aux_extra);
+ assert( check_exact_abs_msec(abs_time_result, 1200) );
+
+ /* fosa_abs_time_to_timespec */
+ tspec_result = fosa_abs_time_to_timespec(abs_time2);
+ test = memcmp(&tspec_result, &tspec2, sizeof(tspec_result) );
+ assert(test == 0);
+
+
+
+ printf("End of test OK!!\n");
+
+ return 0;
+}
+
+// -------------------------------------------------------------
+
+static int check_exact_abs_msec(fosa_abs_time_t abs_time, long msec)
+{
+ fosa_abs_time_t time_check;
+ int cmp = -1;
+
+ time_check = fosa_msec_to_abs_time(msec);
+ cmp = memcmp(&time_check, &abs_time, sizeof(time_check) );
+
+ if (cmp == 0)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+// -------------------------------------------------------------
+
+static int check_exact_rel_msec(fosa_rel_time_t rel_time, long msec)
+{
+ fosa_rel_time_t time_check;
+ int cmp = -1;
+
+ time_check = fosa_msec_to_rel_time(msec);
+ cmp = memcmp(&time_check, &rel_time, sizeof(time_check) );
+
+ if (cmp == 0)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
--- /dev/null
+\95 Brief description: \r
+ To port FRSH from MARTE to OSE, FOSA was introduced. Here are the \r
+ first increment of the implementation of FOSA on OSE.\r
+\r
+\95 Version: First increment EP3v1, in the FRESCOR project.\r
+\r
+\95 Status: Not complete version. Though running tests of the implemented\r
+ parts.\r
+\r
+\95 Authors: of this folder (src_ose) and its content are \r
+ erik.thorin@enea.com\r
+ malin.ling@enea.com\r
+\r
+\95 Most recent versions of the software: Contact Enea.\r
+\r
+--------------------------------------------------------------------------\r
+----------- Short User Guide ---------------------------------------------\r
+--------------------------------------------------------------------------\r
+To make FOSA work on OSE, first install and then run the test program.\r
+\r
+Content the user guide:\r
+ - To install from Enea Linköpings Subversion\r
+ - To run the test program on the soft kernel\r
+ - To install from FRESCOR Subversion\r
+\r
+-------------To install from Enea Linköpings Subversion-------------------\r
+\95 Install a clean OSE5.2 installation with the standard choice. \r
+\r
+\95 Replace your newly created refsys catalogue with the one from \r
+ svn+ssh://selinsrv01/proj/FRESCOR/Repository/ose_including_frsh/trunk.\r
+(Can only be made from within Enea)\r
+\r
+\r
+-------------To run the test program on the soft kernel-------------------\r
+\95 Start cygwin.\r
+\r
+\95 Type "make all" in OSE5.2/refsys/rtose/sfk-win32/.\r
+\r
+\95 Start ose by typing "obj/rtose_debug/rtose.exe -c rtose5.conf".\r
+\r
+\95 Run the test program by typing "fosa_test".\r
+\r
+\r
+-------------To install from FRESCOR Subversion---------------------------\r
+\95 Install a clean OSE5.2 installation with the standard choice. \r
+\r
+\95 Copy the folders to these paths:\r
+ {Repository} = http://www.frescor.org/private/svn/frescor/fosa/trunk\r
+ \r
+ {Repository}/ \r
+ -> OSE5.2/refsys/modules/frescor_fosa\r
+ \r
+ {Repository}/src_ose/frescor_fosa_handlers \r
+ -> OSE5.2/refsys/modules/frescor_fosa_handlers\r
+ \r
+ {Repository}/src_ose/frescor_fosa_test \r
+ -> OSE5.2/refsys/modules/frescor_fosa_test\r
+ \r
+ {Repository}/../../frsh/trunk \r
+ -> OSE5.2/refsys/modules/frescor_frsh\r
+ \r
+\95 Merge the OSE part of the following three files into its counterparts. \r
+ This point is due to the bad design of FRSH and FOSA. FOSA are not a \r
+ clean API, it also uses things from FRSH. The OSE parts are clearly \r
+ marked in the files with "////// OSE ///////" in the beginning and \r
+ "////// End of OSE ///////" in the end.\r
+\r
+ {Repository}/src_ose/copies_of_changed_files/fosa_opaque_types.h\r
+ -> OSE5.2/refsys/modules/frescor_fosa/include/fosa_opaque_types.h\r
+\r
+ {Repository}/src_ose/copies_of_changed_files/fosa_types.h\r
+ -> OSE5.2/refsys/modules/frescor_fosa/include/fosa_types.h\r
+ \r
+ {Repository}/src_ose/copies_of_changed_files/frsh_fosa_opaque.h\r
+ -> OSE5.2/refsys/modules/frescor_frsh/include/frsh_fosa_opaque.h\r
+ \r
+\r
+\95 Change the file krn.con in the OSE board catalogue \r
+ i.e. OSE5.2/refsys/rtose/sfk-win32/krn.con\r
+ Add the following lines:\r
+\r
+ /* Added by Erik Thorin in krn.con */\r
+ CREATE_HANDLER (fosa_ose_create_handler)\r
+ SWAP_IN_HANDLER (fosa_ose_swap_in_handler)\r
+ SWAP_OUT_HANDLER (fosa_ose_swap_out_handler)\r
+ SWAP_OUT_HANDLER (fosa_ose_swap_out_handler2)\r
+ KILL_HANDLER (fosa_ose_kill_handler)\r
+ USER_AREA (21) /* Size of per process user area. */\r
+ /* End added by Erik Thorin */\r
+\r
+\95 Add the following lines to the file rtose.mk in the same catalogue \r
+\r
+ #Added by Erik Thorin in rtose.mk\r
+ override MODS += frescor_fosa_handlers\r
+ override MODS += frescor_fosa\r
+ override MODS += frescor_fosa_test\r
+ #override MODS += frescor_frsh\r
+ #End added by Erik Thorin\r
+\r
+\r
+--------------------------------------------------------------------------\r
+----------- End of the User Guide ----------------------------------------\r
+--------------------------------------------------------------------------\r
+\r
+\r
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+\r
+This work has been funded in part by the European Community\92s Sixth\r
+Framework Programme under the FRESCOR project (FP6/2005/IST/5-034026).
\ No newline at end of file
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+// This file is part of the FRSH implementation
+//
+// FRSH is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// FRSH is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// distributed with FRSH; see file COPYING. If not, write to the
+// Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// As a special exception, if you include this header file into source
+// files to be compiled, this header file does not by itself cause
+// the resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+// -----------------------------------------------------------------------
+//fosa_opaque_types.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+// Implementation dependent definitions
+
+#ifndef _FOSA_OPAQUE_TYPES_H_
+#define _FOSA_OPAQUE_TYPES_H_
+
+
+#if defined(RT_LINUX) || defined(MARTE_OS)
+
+#include <pthread.h>
+#include <signal.h>
+#include <time.h>
+
+#ifdef RT_LINUX
+#include <rtl_timer.h>
+#endif
+
+
+#define FOSA_CLOCK_ID_T_OPAQUE clockid_t
+
+#define FOSA_TIMER_ID_T_OPAQUE timer_t
+
+#define FOSA_COND_T_OPAQUE pthread_cond_t
+
+/*********
+ * ADS
+ *********/
+
+#define FOSA_ADS_ACTIONS_T_OPAQUE int
+/*should be posix_appsched_actions_t*/
+
+#endif // RT_LINUX || MARTE_OS
+
+
+//////////////////////////////// OSE ////////////////////////////////////
+#if defined(OSE)
+
+#include "ose.h"
+#include "sys/time.h"
+//#include "fosa_types.h" //Possible circular reference.....................
+#include "frsh_fosa.h"
+//#include "../src_ose/fosa_ose_implementation_specific.h"
+
+#define FOSA_CLOCK_ID_T_OPAQUE PROCESS//ok?...........................
+
+//#define FOSA_CLOCK_REALTIME 0 //Should be used.............
+#define CLOCK_MONOTONIC 0 //Should not be used...........
+
+#define FOSA_OSE_MAX_COND_CUEUE 100
+/*
+ * author erth
+ *
+ * This struct is used for the condition varables. It has a maximum queue
+ * length pre allocated in memory. This might be better implemented by a
+ * linked list or something like that. But this is for now. Then the
+ * constant above gets unnnecessary.
+ */
+typedef struct {
+ PROCESS pid[ FOSA_OSE_MAX_COND_CUEUE ];
+ int pid_queue_length;
+} fosa_ose_cond_t;
+
+#define FOSA_COND_T_OPAQUE fosa_ose_cond_t
+
+// This structure represents a timerid.
+typedef struct {
+ PROCESS clock_id;
+ SIGSELECT sig_no;
+ frsh_signal_info_t info;
+ OSTMOREF ose_tmoref;
+} fosa_ose_timer_id_t;
+
+#define FOSA_TIMER_ID_T_OPAQUE fosa_ose_timer_id_t *
+
+/*********
+ * ADS
+ *********/
+
+typedef enum {
+ REJECT, ACTIVATE, SUSPEND, TIMEOUT, THREAD_NOTIFICATION
+} action_t;
+
+#endif
+//////////////////////////// End of OSE /////////////////////////////////
+
+
+////////////////////////// DUMMY_OS //////////////////////////////////////
+#if defined(DUMMY_OS)
+
+/* With this define we make sure that we are truly POSIX and OSE */
+/* independent at the FRSH code. */
+/*****************************************************************/
+
+#define FOSA_CLOCK_ID_T_OPAQUE int
+#define FOSA_SYSTEM_CLOCK_OPAQUE 42
+
+#define FOSA_TIMER_ID_T_OPAQUE int
+
+#define FOSA_COND_T_OPAQUE int
+
+/*********
+ * ADS
+ *********/
+
+#define FOSA_ADS_ACTIONS_T_OPAQUE int
+
+
+
+
+#endif /* DUMMY */
+//////////////////////////End of DUMMY_OS ////////////////////////////////////
+
+#endif // _FOSA_OPAQUE_TYPES_H_
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+// This file is part of the FRSH implementation
+//
+// FRSH is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// FRSH is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// distributed with FRSH; see file COPYING. If not, write to the
+// Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// As a special exception, if you include this header file into source
+// files to be compiled, this header file does not by itself cause
+// the resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+// -----------------------------------------------------------------------
+//fosa_types.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+
+#ifndef _FOSA_TYPES_H_
+#define _FOSA_TYPES_H_
+
+#include "fosa_opaque_types.h"
+
+/**
+ * @addtogroup clocksandtimers
+ *
+ * @{
+ **/
+// identifier of a clock
+// either a real-time clock or a cpu-time clock
+typedef FOSA_CLOCK_ID_T_OPAQUE fosa_clock_id_t;
+
+#define FOSA_SYSTEM_CLOCK FOSA_SYSTEM_CLOCK_OPAQUE
+
+// identifier of a one-shot timer
+typedef FOSA_TIMER_ID_T_OPAQUE fosa_timer_id_t;
+
+/*@}*/
+
+/**
+ * @addtrogroup mutexesandcondvars
+ *
+ * @{
+ **/
+// a condition variable
+typedef FOSA_COND_T_OPAQUE fosa_cond_t;
+/*@}*/
+
+/**
+ * @addtogroup appdefsched
+ *
+ * @{
+ **/
+
+/*********
+ * ADS
+ *********/
+
+/**
+ * The urgency used to orde the threads of the same priority in the
+ * underlying scheduler. Support for urgency scheduling is required
+ * for supporting the hierarchhical scheduling module
+ **/
+typedef int fosa_ads_urgency_t;
+
+//////////////////////////////// OSE ////////////////////////////////////
+#if defined(OSE)
+//Added by Erik Thorin, also moved fosa_ads_urgensy_t typedef to above
+//this, instead of after the enum typedef.
+
+// This structure represents an action and are a node in the linked list
+// fosa_ads_actions_t.
+typedef struct fosa_ose_action_def {
+ action_t action;
+ frsh_thread_id_t tid;
+ fosa_ads_urgency_t urgency;
+ fosa_clock_id_t clock_id;
+ struct timespec at_time;
+ struct fosa_ose_action_def* NextAction; //fosa_ose_action_t*
+} fosa_ose_action_t;
+
+// This struct are a linked list of actions, where actions are described
+// by the structure fosa_ose_action_t.
+typedef struct {
+ fosa_ose_action_t* FirstAction;
+ fosa_ose_action_t* LastAction;
+} fosa_ose_ads_actions_t;
+
+#define FOSA_ADS_ACTIONS_T_OPAQUE fosa_ose_ads_actions_t
+
+#endif /* OSE */
+//////////////////////////// End of OSE /////////////////////////////////
+
+/**
+ * ADS actions
+ *
+ * This type is used to represent a list of scheduling actions that the
+ * scheduler will later request to be executed by the system. The pos-
+ * sible actions are of the following kinds:
+ * - reject a thread that has requested attachment to this scheduler
+ * - activate an application-scheduled thread with the desired value
+ * of urgency
+ * - suspend an application-scheduled thread
+ * - program a timeout
+ * - program a timed notification associated to a particular
+ * application-scheduled thread.
+ *
+ * No comparison or assignment operators are defined for this type
+ **/
+typedef FOSA_ADS_ACTIONS_T_OPAQUE fosa_ads_actions_t;
+
+
+/**
+ * Causes of error in the appsched_error primitive operation
+ **/
+typedef enum {FOSA_ADS_THREAD_NOT_ATTACHED, FOSA_ADS_INVALID_ACTION}
+ fosa_ads_error_cause_t;
+
+
+
+/**
+ * Scheduler primitive operations
+ *
+ * This structure is used to create application schedulers. It
+ * contains pointers to the primitive operations that are invoked by
+ * the system when a scheduling event occurs:
+ *
+ * - The \b init() primitive operation is invoked by the system just after
+ * the scheduler has been created using fosa_ads_scheduler_create().
+ *
+ * - The \b new_thread() primitive operation is invoked by the system when
+ * a thread has requested attachment to this scheduler; this can be a
+ * newly created thread (via fosa_thread_create()), or an existing thread
+ * that was not running under ads scheduler (via
+ * fosa_ads_set_appscheduled()).\n \n
+ * .
+ * The thread can be rejected by the scheduler adding a
+ * reject-thread action to the actions parameter using
+ * fosa_ads_actions_add_reject(). If no reject-thread action is
+ * added, the thread is accepted.\n \n
+ * .
+ * Newly created threads shall be activated by the system after the
+ * execution of the new_thread() primitive operation. The urgency of
+ * an accepted thread (either newly created or existing) shall be set
+ * to a value of zero, unless an activate-thread action with a
+ * different value of urgency is added via
+ * fosa_ads_actions_add_activate().\n \n
+ * .
+ * If a request to attach a thread to this scheduler was made via
+ * fosa_ads_set_appscheduled(), at the finalization of the new_thread()
+ * primitive operation if the newly attached thread is blocked by the
+ * system (not by the scheduler itself via a suspend scheduling
+ * action), a thread-block event shall be generated for the scheduler
+ * immediately and, consequently, the thread_block() primitive
+ * operation shall be invoked by the system.
+ *
+ * - The \b thread_terminate() primitive operation is invoked by the system
+ * when a thread attached to this scheduler is terminating (via an
+ * explicit or implicit thread termination, or cancellation, or when
+ * it is no longer sceduled by the ads scheduler (via
+ * fosa_ads_setappscheduled()). \n\n
+ * .
+ * Before the thread_terminate() primitive operation is invoked by
+ * the system, all the thread-notification events programmed for that
+ * thread are cancelled. \n\n
+ * .
+ * In the case of a thread that is terminating, the
+ * thread_terminate() primitive operation is executed before the
+ * execution of the cleanup handlers and of the thread-specific data
+ * destructor functions. In that way, the thread parameter corresponds
+ * to a valid thread Id and the thread-specific data is valid and can
+ * be accessed from the thread_terminate() primitive operation. \n\n
+ * .
+ * Also for terminating threads, after the thread_terminate() primitive
+ * operation finishes, the system shall lower the urgency of the
+ * thread identified by thread to a value of zero, and shall deattach
+ * it from the ads scheduler. Then, the thread shall execute the
+ * cleanup handlers and the thread-specific data destructor functions
+ * outside the management of its former scheduler. Notice that in a
+ * multiprocessor system this may imply the suspension of the thread
+ * identified by parameter thread during the execution of the
+ * thread_terminate() primitive operation.
+ *
+ * - The \b thread_ready() primitive operation is invoked by the system
+ * when a thread attached to this scheduler that was blocked has
+ * become unblocked by the system.
+ *
+ * - The \b thread_block() primitive operation is invoked by the system
+ * when a thread attached to this scheduler has blocked.
+ *
+ * - The \b change_sched_param_thread() primitive operation is invoked by
+ * the system when the scheduling parameters of a thread attached to
+ * this scheduler have been changed, but the thread continues to run
+ * under this scheduler. The change includes either the regular
+ * scheduling parameters (fosa_thread_set_prio() or the application-
+ * defined scheduling parameters, via fosa_ads_set_appsched_param().
+ *
+ * - The \b explicit_call_with_data() primitive operation is invoked by the
+ * system when a thread (identified by the thread parameter) has
+ * explicitly invoked the scheduler with a message containing
+ * scheduling information, and possibly requesting a reply message,
+ * via fosa_ads_invoke_withdata().
+ *
+ * - The \b notification_for_thread() primitive operation is invoked by the
+ * system when the time for a thread-notification previously programed
+ * by the scheduler via fosa_ads_actions_add_thread_notification()
+ * is reached. Parameter clock identifies the clock for which the
+ * thread-notification was programmed.
+ *
+ * - The \b timeout() primitive operation is invoked by the system when a
+ * timeout requested by the scheduler (via
+ * fosa_ads_actions_add_timeout()) has expired.
+ *
+ * - The \b signal() primitive operation is invoked by the system when a
+ * signal belonging to the set of signals for which the scheduler is
+ * waiting (via fosa_ads_set_handled_signal_set()) has been
+ * generated. \n\n
+ * .
+ * The signal number and its associated information (if any) are
+ * passed in the arguments signal and siginfo.\n\n
+ * .
+ * The signal is consumed with the invocation of this primitive
+ * operation, which implies that it will not cause the execution of
+ * any signal handler, nor it may be accepted by any thread waiting
+ * for this signal number.
+ *
+ * - The \b appsched_error() primitive operation is invoked by the system
+ * when an error in the scheduling actions list specified in a
+ * previous primitive operation is detected. The cause of the error is
+ * notified in the parameter cause. The defined causes of error are
+ * described fosa_ads_error_cause_tappdefsched
+ *
+ * Every primitive operation receives the argument sched_data. It is a
+ * pointer to a memory area containing information shared by all the
+ * scheduler operations. It can be used to store the data structures
+ * required by the scheduler (for example, a ready queue and a delay
+ * queue). Scheduler operations should not use any other global data out
+ * of this memory area.
+ *
+ * The actions argument is used by the scheduler to request the operating
+ * system to execute a set of scheduling actions at the end of the
+ * primitive operation. It is passed empty by the system, and the
+ * scheduler may add multiple scheduling actions.
+ *
+ * The current_time argument contains the system time
+ * measured immediately before the invocation of the primitive operation
+ * using the FOSA_CLOCK_REALTIME clock
+ *
+ * In addition to these common parameters, most of the primitive
+ * operations receive a thread argument. This argument allows the
+ * primitive operations to know which is the thread that has produced or
+ * is related to the event.
+ **/
+typedef struct {
+ void (*init) (void * sched_data, void * arg);
+ void (*new_thread) (void * sched_data,
+ frsh_thread_id_t thread,
+ fosa_ads_actions_t * actions,
+ struct timespec *current_time);
+ void (*thread_terminate) (void * sched_data,
+ frsh_thread_id_t thread,
+ fosa_ads_actions_t * actions,
+ struct timespec *current_time);
+ void (*thread_ready) (void * sched_data,
+ frsh_thread_id_t thread,
+ fosa_ads_actions_t * actions,
+ struct timespec *current_time);
+ void (*thread_block) (void * sched_data,
+ frsh_thread_id_t thread,
+ fosa_ads_actions_t * actions,
+ struct timespec *current_time);
+ //void (*thread_yield) (void * sched_data,
+ // frsh_thread_id_t thread,
+ // fosa_ads_actions_t * actions,
+ // struct timespec *current_time);
+ void (*change_sched_param_thread) (void * sched_data,
+ frsh_thread_id_t thread,
+ fosa_ads_actions_t * actions,
+ struct timespec *current_time);
+ //void msg_from_scheduler(void * sched_data,
+ // fosa_ads_scheduler_id_t scheduler_id,
+ // const void * msg, size_t msg_size,
+ // fosa_ads_actions_t * actions,
+ // struct timespec *current_time);
+ //void (*explicit_call) (void * sched_data,
+ // frsh_thread_id_t thread,
+ // int user_event_code,
+ // fosa_ads_actions_t * actions,
+ // struct timespec *current_time);
+ void (*explicit_call_with_data) (void * sched_data,
+ frsh_thread_id_t thread,
+ const void * msg, size_t msg_size,
+ void **reply, size_t *reply_size,
+ fosa_ads_actions_t * actions,
+ struct timespec *current_time);
+ void (*notification_for_thread) (void * sched_data,
+ frsh_thread_id_t thread,
+ fosa_clock_id_t clock,
+ fosa_ads_actions_t * actions,
+ struct timespec *current_time);
+ void (*timeout) (void * sched_data,
+ fosa_ads_actions_t * actions,
+ struct timespec *current_time);
+ void (*signal) (void * sched_data,
+ frsh_signal_t signal,
+ frsh_signal_info_t siginfo,
+ fosa_ads_actions_t * actions,
+ struct timespec *current_time);
+ //void (*priority_inherit) (void * sched_data,
+ // frsh_thread_id_t thread,
+ // int sched_priority,
+ // fosa_ads_actions_t * actions,
+ // struct timespec *current_time);
+ //void (*priority_uninherit) (void * sched_data,
+ // frsh_thread_id_t thread,
+ // int sched_priority,
+ // fosa_ads_actions_t * actions,
+ // struct timespec *current_time);
+ void (*appsched_error) (void * sched_data,
+ frsh_thread_id_t thread,
+ fosa_ads_error_cause_t cause,
+ fosa_ads_actions_t * actions);
+} fosa_ads_scheduler_ops_t;
+
+
+/*@}*/
+
+#endif // _FOSA_TYPES_H_
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH API
+//
+// FRSH API is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// FRSH API is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// distributed with FRSH API; see file COPYING. If not, write to the
+// Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// As a special exception, if you include this header file into source
+// files to be compiled, this header file does not by itself cause
+// the resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+// -----------------------------------------------------------------------
+//frsh_core_types.h
+//========================================================================================
+// ******** ******* ******** ** ** ******** ****** ******** **********
+// **///// /**////** **////// /** /** **///// /** ** **////// /** /**
+// ** /** /** /** /** /** ** /** ** /** /** /**
+// ******* /******* /********* /********** ******* /** ** /********* /**********
+// **//// /**///** ////////** /**//////** **//// /** ** ////////** /**//////**
+// ** /** //** /** /** /** ** /** ** /** /** /**
+// ** /** //** ******** /** /** ** /** ** ******** /** /**
+// // // // //////// // // // /******/ //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh" FOSA(Frescor Oper System Adaptation layer)
+//========================================================================================
+
+#ifndef FRSH_FOSA_OPAQUE_H_
+#define FRSH_FOSA_OPAQUE_H_
+
+/**
+ * @file frsh_fosa_opaque.h
+ **/
+
+
+/**
+ * \addtogroup frshfosa
+ *
+ * @{
+ **/
+
+
+//////////////////////////MaRTE OS & RT_LINUX /////////////////////////
+
+#if defined(MARTE_OS) || defined(RT_LINUX)
+
+#include <pthread.h>
+#include <signal.h>
+#include <errno.h>
+#include <time.h>
+
+#define FOSA_THREAD_ID_T_OPAQUE pthread_t
+
+#define FOSA_THREAD_ATTR_T_OPAQUE pthread_attr_t
+
+#define FOSA_SIGNAL_T_OPAQUE int
+
+#define FOSA_MUTEX_T_OPAQUE int
+
+// The minimum and maximum signal numbers that may be used by the FRSH
+// implementation
+#define FOSA_SIGNAL_MIN SIGRTMIN
+#define FOSA_SIGNAL_MAX SIGRTMIN+0
+
+#define FOSA_NULL_SIGNAL 0
+
+/* FOSA Errors */
+
+/* #include <error.h> */
+
+/** Not enough memory available **/
+#define FOSA_ENOMEM ENOMEM
+
+/** Invalid parameter **/
+#define FOSA_EINVAL EINVAL
+
+/** Still pending information **/
+#define FOSA_EAGAIN EAGAIN
+
+/** FOSA ADS errors **/
+#define FOSA_EREJECT EREJECT
+#define FOSA_EMASKED EMASKED
+
+
+#endif /* MARTE_OS || RT_LINUX */
+
+//////////////////////////End of MaRTE OS & RT_LINUX ///////////////////
+
+
+////////////////////////// OSE ///////////////////////////////////////////
+
+#ifndef OSE
+#define OSE
+#endif
+
+#if defined(OSE)
+/* OSE dependent includes and defines */
+
+#include <ose.h>
+#include <errno.h>
+#include <stddef.h>
+#include <sys/time.h>
+
+#define FOSA_THREAD_ID_T_OPAQUE PROCESS
+
+typedef struct {
+ OSPRIORITY prio; //OSE priority (map to FRSH priority if needed).
+ unsigned long stack_size;
+ char app_scheduled; //Preferred bool
+ void* appsched_param;
+ size_t appsched_param_size;
+} fosa_ose_process_attr_t;
+
+#define FOSA_THREAD_ATTR_T_OPAQUE fosa_ose_process_attr_t
+
+#define FOSA_SIGNAL_T_OPAQUE SIGSELECT
+
+/*
+ * author erth
+ *
+ * This struct is used as a mutex that stores the mutex, its priority
+ * ceiling and original priority.
+ *
+ * @param mutex is a pointer to a mutex.
+ * @param ceiling uses the FRSH priority numbers.
+ * @param orig_prio uses the OSE priority numbers (which are maped and
+ * reversed to the FRSH ones).
+ */
+typedef struct {
+ MUTEX ose_mutex;
+ int prio_ceiling;
+ OSPRIORITY process_original_prio;
+} fosa_ose_mutex_t;
+
+#define FOSA_MUTEX_T_OPAQUE fosa_ose_mutex_t
+
+#define FOSA_SIGNAL_MIN 257
+#define FOSA_SIGNAL_MAX 29999
+
+#define FOSA_NULL_SIGNAL NIL
+
+
+/* FOSA Errors */
+
+/** Not enough memory available **/
+#define FOSA_ENOMEM ENOMEM
+
+/** Invalid parameter **/
+#define FOSA_EINVAL EINVAL
+
+/** Still pending information **/
+#define FOSA_EAGAIN EAGAIN
+
+/** FOSA ADS errors **/
+#define FOSA_EREJECT -4
+#define FOSA_EMASKED -5
+#define FOSA_EPOLICY 102//ok?......................................
+
+#endif /* OSE */
+//////////////////////////End of OSE /////////////////////////////////////
+
+////////////////////////// DUMMY_OS //////////////////////////////////////
+
+#if defined(DUMMY_OS)
+
+/* With this define we make sure that we are truly POSIX and OSE */
+/* independent at the FRSH code. */
+/*****************************************************************/
+
+#define FOSA_THREAD_ID_T_OPAQUE int
+
+#define FOSA_THREAD_ATTR_T_OPAQUE int
+
+#define FOSA_SIGNAL_T_OPAQUE int
+
+#define FOSA_MUTEX_T_OPAQUE int
+
+// The minimum and maximum signal numbers that may be used by the FRSH
+// implementation
+#define FOSA_SIGNAL_MIN 42
+#define FOSA_SIGNAL_MAX 42
+
+#define FOSA_NULL_SIGNAL 0
+
+/* FOSA Errors */
+
+/* #include <error.h> */
+
+/** Not enough memory available **/
+#define FOSA_ENOMEM -1
+
+/** Invalid parameter **/
+#define FOSA_EINVAL -2
+
+/** Still pending information **/
+#define FOSA_EAGAIN -3
+
+/** FOSA ADS errors **/
+#define FOSA_EREJECT -4
+#define FOSA_EMASKED -5
+
+
+#endif /* DUMMY */
+//////////////////////////End of DUMMY_OS ////////////////////////////////////
+
+
+
+
+
+
+#endif /* !FRSH_FOSA_OPAQUE_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or
+// without modification, are permitted provided that the
+// following conditions are met:
+//
+// * Redistributions of source code must retain the above
+// copyright notice, this list of conditions and the
+// following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the
+// following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+// * Neither the name of FRESCOR nor the names of its
+// contributors may be used to endorse or promote products
+// derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+// -----------------------------------------------------------------------
+//fosa_app_def_sched.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include "string.h"
+#include "malloc.h"
+#include "heapapi.h"
+#include "ose.h"
+
+#include "fosa.h"
+#include "fosa_app_def_sched.h"
+#include "fosa_ose_implementation_specific.h"
+
+#include "frsh_internal.h"
+
+//Debug purpose only.................
+#include "stdio.h"
+
+/**
+ * @defgroup appdefsched Application Defined Scheduling
+ * @ingroup fosa
+ *
+ * This module defines the function and types for an abstraction of
+ * the Application Defined Scheduling.
+ *
+ * @{
+ **/
+
+
+
+/********************************
+ * Application-defined scheduling
+ ********************************/
+
+/**
+ * We make the following ASSUMPTIONS:
+ *
+ * - The ADS always executes in the user memory space, so we don't
+ * need to manage the memory space translation.
+ *
+ * - Only one application scheduler exists, so we don't need an
+ * scheduler_id.
+ **/
+
+/*
+ * author erth
+ *
+ * Creation of the ads scheduler that takes the events from OSE calls the
+ * right scheduler callback that returns a list of actions that is
+ * executed in the right order by this function.
+ *
+ * author erth swedish:
+ *
+ * Denna funktion skall kunna ta emot event (att process nu blivit
+ * blockad, terminerad, signallerad eller ready) från "OSE" eller annan
+ * del av FOSA. Därefter skall rätt funktion i structen med
+ * funktionspekare anropas. Vilket ÄR FRSH schemaläggaren. Sedan fyller
+ * FRSH schemaläggaren på med action noder i action listan. När anropet
+ * till "rätt funktion" returnerar så skall den nu inte längre tomma
+ * listan med actions utföras. Efter detta loopas det tillbaka till att
+ * vänta på en ny action, alternativt ta emot nästa meddelande i action
+ * kön (OSE:s signal kö till denna process).
+ */
+OS_PROCESS(fosa_scheduler_process)
+{
+ struct timespec current_time;
+ fosa_ose_scheduler_startup_t *sig;
+ fosa_ads_scheduler_ops_t scheduler_ops;
+ frsh_sched_data_t* frsh_sched_data;
+
+ SIGSELECT sel_any[] = { 0 };
+ SIGSELECT sel_start_sig[] = {1, FOSA_OSE_STARTUP_SIGNAL};
+ SIGSELECT event = 0;
+ PROCESS asking_pid = 0;
+ PROCESS event_pid = 0;
+
+
+ // Receive the scheduler startup signal
+ sig = (fosa_ose_scheduler_startup_t *) receive(sel_start_sig);
+
+ scheduler_ops = sig->scheduler_ops;
+ frsh_sched_data = (frsh_sched_data_t *)
+ malloc(sig->scheduler_data_size);
+
+ // Initialize the scheduler
+ //scheduler_ops.frsh_callback_init(frsh_sched_data, sig->init_args);
+ free_buf((union SIGNAL**)&sig);
+
+ // Initialize the queue of actions
+ fosa_ose_action_t* tmp_action;
+ fosa_ads_actions_t actions;
+ fosa_ose_ads_actions_init(&actions);
+
+ fosa_ose_event_signal_t *event_sig;
+ while(1) {
+ //Recieve the event
+ event_sig = (fosa_ose_event_signal_t *) receive(sel_any);
+ event = event_sig->sig_no;
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time);
+
+ //Call the right scheduler callback function.
+ switch (event) {
+
+ case FOSA_OSE_BLOCK_SIGNAL:
+ event_pid = event_sig->pid;
+ printf("FOSA SCHEDULER: Process %x blocked.\n",
+ event_pid); //Debug purpose only...................
+ //scheduler_ops.frsh_callback_thread_block(
+ // frsh_sched_data,
+ // frsh_thread_id_t thread,
+ // &actions,
+ // ¤t_time)
+ break;
+
+ case FOSA_OSE_READY_SIGNAL:
+ event_pid = event_sig->pid;
+ printf("FOSA SCHEDULER: Process %x ready.\n",
+ event_pid); //Debug purpose only...................
+ //scheduler_ops.frsh_callback_thread_ready(
+ // frsh_sched_data,
+ // frsh_thread_id_t thread,
+ // &actions,
+ // ¤t_time)
+ break;
+
+ case FOSA_OSE_SIGNAL_SCHED_SIGNAL:
+ //scheduler_ops.frsh_callback_signal(
+ // frsh_sched_data,
+ // frsh_signal_t signal,
+ // frsh_signal_info_t signal_info,
+ // &actions,
+ // ¤t_time)
+ break;
+
+ case FOSA_OSE_TERMINATE_SIGNAL:
+ event_pid = event_sig->pid;
+ printf("FOSA SCHEDULER: Process %x terminated.\n",
+ event_pid); //Debug purpose only...................
+ //scheduler_ops.frsh_callback_thread_terminate(
+ // frsh_sched_data,
+ // event_sig->tid,
+ // &actions,
+ // ¤t_time)
+ break;
+
+ case FOSA_OSE_NEW_THREAD_SIGNAL:
+ event_pid = event_sig->pid;
+ asking_pid = sender((union SIGNAL**)&event_sig);
+ printf("FOSA SCHEDULER: Process %x new.\n", event_pid); //Debug purpose only...................
+ //scheduler_ops.frsh_callback_new_thread(
+ // frsh_sched_data,
+ // event_sig->tid,
+ // &actions,
+ // ¤t_time);
+ /*
+ * author erth
+ *
+ * We also need to save the process that the question was
+ * sent from. To be able to reply with a reject or activate
+ * in the action below. Since the action type can't save
+ * it, it's stored in the variable asking_pid.
+ *
+ * If the thread is rejected a REJECT action is added to
+ * the actions list. But if accepted, no REJECT action is
+ * added. Instead of adding a ACCEPT action if there were
+ * one. Now you need to search through the list
+ * of actions to see if there is any reject action. If
+ * none, it is accepted. Bad design of FOSA API.
+ */
+ tmp_action = actions.FirstAction;
+ while (tmp_action != NULL)
+ {
+ if (tmp_action->action == REJECT)
+ break;
+ tmp_action = tmp_action->NextAction;
+ }
+ if (tmp_action == NULL)
+ fosa_ose_execute_action_accept(asking_pid);
+ break;
+
+ /*case FOSA_OSE_EMPTY:
+ //scheduler_ops.frsh_callback_explicit_call_with_data((void *) frsh_sched_data,
+ // frsh_thread_id_t thread_id,
+ // const void * msg,
+ // size_t msg_size,
+ // void **reply,
+ // size_t *reply_size,
+ // fosa_ads_actions_t * actions,
+ // ¤t_time)
+ break;
+
+ case FOSA_OSE_EMPTY:
+ //scheduler_ops.frsh_callback_change_sched_param_thread(
+ // frsh_sched_data,
+ // frsh_thread_id_t thread,
+ // &actions,
+ // ¤t_time)
+ break;
+
+ case FOSA_OSE_EMPTY:
+ //scheduler_ops.frsh_callback_appsched_error(
+ // frsh_sched_data,
+ // frsh_thread_id_t thread,
+ // fosa_ads_error_cause_t cause,
+ // &actions)
+ break;
+
+ case FOSA_OSE_SHUTDOWN_FRSH:
+ //Shutdown the possible parts of frsh and fosa and return
+ //all allocated memory. Restart FRSH again?
+ free(frsh_sched_data);
+ kill_proc(current_process());
+ break;
+ */
+ case FOSA_OSE_TEST_EVENT_SIGNAL:
+ ramlog_printf("FOSA: Sucess by: receive an event in the \
+ scheduler.\n");
+ fosa_ose_adsactions_add_test(&actions, (action_t)SUSPEND);
+ break;
+
+ default:
+ ramlog_printf("FOSA: Unknown event (sig_no: %d) given to \
+ scheduler. The scheduler process shutdown.\n", event);
+ kill_proc(current_process());
+ break;
+ }
+ free_buf((union SIGNAL **)&event_sig);
+
+ //Execute the received actions in the action list, returned from
+ //the callback scheduler functions above.
+ while(actions.LastAction != NULL){
+ switch (actions.FirstAction->action) {
+ case ACTIVATE:
+ //fosa_ose_execute_action_activate(
+ // actions.FirstAction->thread);
+ break;
+
+ case REJECT:
+ //fosa_ose_execute_action_reject(
+ // asking_pid, actions.FirstAction->thread);
+ break;
+
+ case SUSPEND:
+ printf("Sucess by: Action %d executed.\n",
+ actions.FirstAction->action); //Debug purpose only...................
+ //fosa_ose_execute_action_suspend(
+ // actions.FirstAction->thread);
+ break;
+
+ case THREAD_NOTIFICATION:
+ //fosa_ose_execute_action_thread_notification(
+ // actions.FirstAction);
+ break;
+
+ case TIMEOUT:
+ //fosa_ose_execute_action_timeout(
+ // actions.FirstAction);
+ break;
+
+ default:
+ ramlog_printf("FOSA SCHEDULER: Unknown action (no: %d\
+ ) given to scheduler. The scheduler process shutdown.\
+ \n", actions.FirstAction->action);
+ kill_proc(current_process());
+ break;
+ }
+ fosa_ose_adsactions_remove_first(&actions);
+ }
+ }
+ kill_proc(current_process());
+}
+
+/**
+ * fosa_ads_scheduler_create()
+ *
+ * Create the application defined scheduler
+ *
+ * The application defined scheduler is created with the primitive
+ * operations specified in the object pointed to by scheduler_ops.
+ *
+ * The clock used to read the time immediately before the invocation
+ * of each primitive operation, to be reported to the scheduler via
+ * the current_time parameter of each primitive operation is the
+ * FOSA_CLOCK_REALTIME clock.
+ *
+ * The scheduler_data_size parameter is used to request that a memory
+ * area of this size must be created and reserved for the scheduler to
+ * store its state. A pointer to this area is passed to the scheduler
+ * operations in the sched_data parameter.
+ *
+ * Parameter init_arg points to an area that contains configuration
+ * information for the scheduler. The function creates a memory area
+ * of init_arg_size bytes and copies into it the area pointed by
+ * arg. A pointer to this new created area will be passed to the
+ * primitive operation init() in its arg parameter.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of scheduler_ops was invalid
+ * EAGAIN: The system lacks enough resources to create the scheduler
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_scheduler_create
+ (const fosa_ads_scheduler_ops_t * scheduler_ops,
+ size_t scheduler_data_size,
+ void * init_args,
+ size_t init_args_size)
+{
+ /*
+ * author erth
+ *
+ * There are no way to kill this process and to turn off the fosa
+ * implementation. That would be nice to have, actually almost need to
+ * have! Other wise ther will be many schedulers if this function are
+ * called several times. Michael Gonzales sais that there are no
+ * reason to turn of the scheduler... I think there should be a way to
+ * turn off as many tings as possible anyway.
+ */
+
+ // Error check.
+ if (scheduler_ops == NULL) return FOSA_EINVAL;
+ //Can better check be performed?
+
+ // Create scheduler startup signal
+ fosa_ose_scheduler_startup_t *sig;
+ sig = (fosa_ose_scheduler_startup_t *)alloc(
+ sizeof(fosa_ose_scheduler_startup_t) + init_args_size +
+ scheduler_data_size,
+ FOSA_OSE_STARTUP_SIGNAL);
+
+ //Stupid to make copy here????........................................
+ sig->scheduler_ops = *scheduler_ops;
+ sig->scheduler_data_size = scheduler_data_size;
+ sig->init_args = init_args;
+ sig->init_args_size = init_args_size;
+
+ //Make ose priority from fosa priority, and set attr.
+ OSPRIORITY prio = (OSPRIORITY) fosa_get_priority_max()
+ + fosa_get_priority_min() - FRSH_SCHEDULER_PRIORITY;
+
+
+ // Create the scheduler
+ char name[] = "fosa_scheduler_process";
+ PROCESS pid = create_process(
+ OS_PRI_PROC, // Process type.
+ name, // Name.
+ fosa_scheduler_process, // Entrypoint.
+ 1000, // Stacksize.
+ prio, // Priority. 28+3-29=2 To low?
+ 0, // Timeslice.
+ 0, // 0 = Part of callers block.......??
+ NULL, // No signal redirection.
+ 0, // OSvector.
+ 0); // OSuser.
+
+ send((union SIGNAL **)&sig, pid);
+ start(pid);
+
+ // EAGAIN error check taken care of by OSE.
+ return 0;
+}
+
+
+/**
+ * fosa_thread_attr_set_appscheduled()
+ *
+ * Set the appscheduled attribute of a thread attributes object
+ *
+ * This function is used to set the appscheduled attribute in the
+ * object pointed to by attr. This attribute controls the kind of
+ * scheduling used for threads created with it. If true, the thread is
+ * scheduled by the application scheduler. If not, it is scheduled by
+ * the system under a fixed priority scheduler
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of attr is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_set_appscheduled
+ (frsh_thread_attr_t *attr,
+ bool appscheduled)
+{
+ if (attr == NULL) return FOSA_EINVAL;
+
+ attr->app_scheduled = appscheduled;
+
+ return 0;
+}
+
+/**
+ * fosa_thread_attr_get_appscheduled()
+ *
+ * Get the appscheduled attribute of a thread attributes object
+ *
+ * This function is used to get the appscheduled attribute in the
+ * object pointed to by attr. This attribute controls the kind of
+ * scheduling used for threads created with it. If true, the thread is
+ * scheduled by the application scheduler. If not, it is scheduled by
+ * the system under a fixed priority scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of attr is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_get_appscheduled
+ (const frsh_thread_attr_t *attr,
+ bool *appscheduled)
+{
+ if (attr == NULL) return FOSA_EINVAL;
+
+ *appscheduled = attr->app_scheduled;
+
+ return 0;
+}
+
+/**
+ * fosa_thread_attr_set_appsched_params()
+ *
+ * Set the appsched_param attribute of a thread attributes object
+ *
+ * This function is used to set the appsched_param attribute in the
+ * object pointed to by attr. For those threads with appscheduled set
+ * to true, this attribute represents the application-specific
+ * scheduling parameters. If successful, the function shall set the
+ * size of the appsched_param attribute to the value specified by
+ * paramsize, and shall copy the scheduling parameters occupying
+ * paramsize bytes and pointed to by param into that attribute
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of attr is invalid, or paramsize is less than
+ * zero or larger than FOSA_ADS_SCHEDPARAM_MAX
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_set_appsched_params
+ (frsh_thread_attr_t *attr,
+ const void *param,
+ size_t paramsize)
+{
+ if (attr == NULL) return FOSA_EINVAL;
+
+ attr->appsched_param = heap_realloc_shared(
+ attr->appsched_param, paramsize, __FILE__, __LINE__);
+ if (attr->appsched_param == NULL) return ENOMEM;
+
+ // Copy *param to above allocated memory
+ memcpy( attr->appsched_param, param, paramsize );
+ attr->appsched_param_size = paramsize;
+
+ return 0;
+}
+
+/**
+ * fosa_thread_attr_get_appsched_params()
+ *
+ * Get the appsched_param attribute of a thread attributes object
+ *
+ * This function is used to get the appsched_param attribute from the
+ * object pointed to by attr. For those threads with appscheduled set
+ * to true, this attribute represents the application-specific
+ * scheduling parameters. If successful, the function shall set the
+ * value pointed to by paramsize to the size of the appsched_param
+ * attribute, and shall copy the scheduling parameters occupying
+ * paramsize bytes into the variable pointed to by param. This
+ * variable should be capable of storing a number of bytes equal to
+ * paramsize.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of attr is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_get_appsched_params
+ (const frsh_thread_attr_t *attr,
+ void *param,
+ size_t *paramsize)
+{
+ if (attr == NULL)
+ return FOSA_EINVAL;
+ else if (attr->appsched_param == NULL)
+ return FOSA_EINVAL;
+
+ if (attr->app_scheduled) {
+ /*
+ * author erth
+ *
+ * This is not logical. The size of the memory area
+ * should be returned, but memory of (at least) the same size need
+ * to be already reserved, by the one who calls this function.
+ * This means the caller need to already know the size of the
+ * memory. Then why return the size? Or why not reserve the memory
+ * here? Reasoning in circles!!!...................................
+ */
+
+ //param = (void *) malloc(attr->appsched_param_size); // Should not be done here!?!!
+ //in that case a (void **param) are needed, not a (void *param).
+ memcpy( param, attr->appsched_param, attr->appsched_param_size );
+ *paramsize = attr->appsched_param_size;
+ } else {
+ return FOSA_EINVAL;
+ }
+
+ /*
+ * author erth
+ *
+ * Since allocated memory at attr->appsched_param are not freed here
+ * this is possibly a memoryleak,
+ * where or when are this memory returned?...........................
+ */
+
+ return 0;
+}
+
+/**
+ * fosa_ads_set_appscheduled()
+ *
+ * Dynamically set the appscheduled attribute of a thread
+ *
+ * This function is used to dynamically set the appscheduled attribute
+ * of the thread identified by thread. This attribute controls the
+ * kind of scheduling used for threads created with it. If true, the
+ * thread is scheduled by the application scheduler. If not, it is
+ * scheduled by the system under a fixed priority scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of thread is invalid
+ *
+ * EREJECT: the attachment of the thread to the frsh schehduler
+ * was rejected by the frsh scheduler possibly because of
+ * incorrect attributes, or because the requested minimum
+ * capacity cannot be guaranteed
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_set_appscheduled
+ (frsh_thread_id_t thread,
+ bool appscheduled)
+{
+ fosa_ose_process_info_t* process = fosa_ose_process_get_node(thread);
+ if (process == NULL) return FOSA_EINVAL;
+
+ //Ask the scheduler if ok to add the thread?..........................
+ //Or possible to use the user area variable of the process?...........
+
+ process->app_scheduled = appscheduled;
+ return 0;
+}
+
+/**
+ * fosa_ads_getappscheduled()
+ *
+ * Dynamically get the appscheduled attribute of a thread
+ *
+ * This function is used to dynamically get the appscheduled attribute
+ * of the thread identified by thread. This attribute controls the
+ * kind of scheduling used for threads created with it. If true, the
+ * thread is scheduled by the application scheduler. If not, it is
+ * scheduled by the system under a fixed priority scheduler
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of thread is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_get_appscheduled
+ (frsh_thread_id_t thread,
+ bool *appscheduled)
+{
+ fosa_ose_process_info_t* process = fosa_ose_process_get_node(thread);
+ if (process == NULL) return FOSA_EINVAL;
+
+ *appscheduled = process->app_scheduled;
+ return 0;
+}
+
+
+/**
+ * fosa_ads_setappschedparam()
+ *
+ * Dynamically set the appsched_param attribute of a thread
+ *
+ * This function is used to dynamically set the appsched_param
+ * attribute of the thread identified by thread. For those threads
+ * with appscheduled set to true, this attribute represents the
+ * application-specific scheduling parameters. If successful, the
+ * function shall set the size of the appsched_param attribute to the
+ * value specified by paramsize, and shall copy the scheduling
+ * parameters occupying paramsize bytes and pointed to by param into
+ * that attribute
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of thread is invalid, or paramsize is less than
+ * zero or larger than FOSA_ADS_SCHEDPARAM_MAX
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_set_appsched_params
+ (frsh_thread_id_t thread,
+ const void *param,
+ size_t paramsize)
+{
+ fosa_ose_process_info_t* process = fosa_ose_process_get_node(thread);
+ if ((paramsize < 0) ||
+ (paramsize > FOSA_ADS_SCHEDPARAM_MAX) ||
+ (process == NULL)) {
+ return FOSA_EINVAL;
+ }
+
+ process->appsched_param = heap_realloc_shared(
+ process->appsched_param, paramsize, __FILE__, __LINE__);
+ memcpy(process->appsched_param, param, paramsize);
+ process->appsched_param_size = paramsize;
+
+ return 0;
+}
+
+/**
+ * fosa_ads_get_appsched_params()
+ *
+ * Dynamically get the appsched_param attribute of a thread
+ *
+ * This function is used to dynamically get the appsched_param
+ * attribute of the thread identified by thread. For those threads
+ * with appscheduled set to true, this attribute represents the
+ * application-specific scheduling parameters. If successful, the
+ * function shall set the variable pointed to by paramsize to the size
+ * of the appsched_param attribute, and shall copy the scheduling
+ * parameters occupying paramsize bytes into the variable pointed to
+ * by param. This variable should be capable of storing a number of
+ * bytes equal to paramsize.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: The value of thread is invalid, or paramsize is less than
+ * zero or larger than FOSA_ADS_SCHEDPARAM_MAX
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications.
+ **/
+int fosa_ads_get_appsched_params
+ (frsh_thread_id_t thread,
+ void *param,
+ size_t *paramsize)
+{
+ fosa_ose_process_info_t* process = fosa_ose_process_get_node(thread);
+ if (process == NULL) return FOSA_EINVAL;
+
+ *paramsize = process->appsched_param_size;
+ memcpy(param, process->appsched_param, process->appsched_param_size);
+
+ return 0;
+}
+
+
+/*********************************
+ * ADS actions
+ *
+ * A scheduling actions object is used to specify a series of actions
+ * to be performed by the system at the end of a scheduler primitive
+ * operation. The order of the actions added to the object shall be
+ * preserved.
+ *
+ *********************************/
+
+/*
+ * author erth
+ *
+ * This function are introcuded to avoid code multiplication in the
+ * fosa_adsactions_add_* functions and it should also only be called by
+ * these functions. It returns 0 if successful, otherwise the errors given
+ * by its calling function.
+ */
+int fosa_ose_adsactions_add(fosa_ads_actions_t* sched_actions,
+ action_t action,
+ frsh_thread_id_t thread,
+ fosa_ads_urgency_t urgency,
+ fosa_clock_id_t clock_id,
+ time_t sec,
+ long nsec)
+{
+ // How to initialize fosa_ads_actions_t? Set pointers to NULL............
+ bool sched_actions_first_element = false;
+
+ // Chcek for errors.
+ if (sched_actions->LastAction == NULL) {
+ sched_actions_first_element = true;
+ } else if (sched_actions->LastAction->NextAction != NULL)
+ return FOSA_EINVAL;
+
+ // Make new action node.
+ fosa_ose_action_t* NewAction = (fosa_ose_action_t*)
+ heap_alloc_shared(sizeof(fosa_ose_action_t), __FILE__, __LINE__);
+ if (NewAction == NULL) return FOSA_ENOMEM;
+
+ NewAction->action = action;
+ NewAction->tid = thread;
+ NewAction->urgency = urgency;
+ NewAction->clock_id = clock_id;
+ NewAction->at_time.tv_sec = sec;
+ NewAction->at_time.tv_nsec = nsec;
+ NewAction->NextAction = NULL;
+
+ // Add action node to list.
+ if (sched_actions_first_element)
+ sched_actions->FirstAction = NewAction;
+ else
+ (sched_actions->LastAction)->NextAction = NewAction;
+
+ sched_actions->LastAction = NewAction;
+
+ return 0;
+}
+
+/**
+ * fosa_adsactions_add_reject()
+ *
+ * Add a reject-thread action
+ *
+ * This function adds a thread-reject action to the object referenced
+ * by sched_actions, that will serve to notify that the thread
+ * identified by thread has not been accepted by the scheduler to be
+ * scheduled by it, possibly because the thread contained invalid
+ * application scheduling attributes, or because there are not enough
+ * resources for the new thread. At the end of the new_thread()
+ * scheduler primitive operation, the parent of the rejected thread
+ * waiting on a fosa_thread_create() or the rejected thread itself
+ * waiting on a fosa_ads_set_appscheduled() function shall complete the
+ * function with an error code of EREJECT. If no reject-thread action
+ * is added during the new_thread() scheduler primitive operation, the
+ * thread is accepted to be scheduled by the scheduler and the
+ * associated fosa_thread_create() or the fosa_ads_set_appscheduled()
+ * function shall be completed without error. For the function to
+ * succeed, it has to be called from the new_thread() primitive
+ * operation and for the thread that is requesting attachment to the
+ * scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * ENOMEM: There is insufficient memory to add this action
+ * EPOLICY: The thread specified by thread is not the one requesting
+ * attachment to the scheduler, or the function is not being
+ * called from the new_thread primitive operation
+ * EINVAL: The value specified by sched_actions is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+
+
+int fosa_adsactions_add_reject(
+ fosa_ads_actions_t *sched_actions,
+ frsh_thread_id_t thread)
+{
+ if (thread != current_process()) return FOSA_EPOLICY;
+
+ return fosa_ose_adsactions_add( sched_actions, //sched_actions
+ REJECT, //action
+ thread, //thread
+ 0, //urgency
+ 0, //clock_id
+ 0, //sec
+ 0); //nsec
+}
+
+/**
+ * fosa_adsactions_add_activate()
+ *
+ * Add a thread-activate action
+ *
+ * This function adds a thread-activate action to the object
+ * referenced by sched_actions. In case the thread had been previously
+ * suspended via posix_appsched_actions_addsuspend(), it will be
+ * activated at the end of the primitive operation.
+ *
+ * In those implementations that do not support urgency scheduling,
+ * the urgencu value is ignored. These implementations cannot support
+ * the frsh hierarchical scheduling module.
+ *
+ * In those implementations supporting urgency-scheduling, the action
+ * will cause the change of the urgency of the thread to the value
+ * specified in the urgency argument. Besides, if the thread was
+ * already active at the time the thread-activate action is executed,
+ * the change or urgency will imply a reordering of the thread in its
+ * priority queue, so that for threads of the same priority, those
+ * with more urgency will be scheduled before those of less urgency.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * ENOMEM: There is insufficient memory to add this action
+ * EPOLICY: The thread specified by thread has its appscheduled
+ * attribute set to false,
+ * EINVAL: The value specified by sched_actions is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_activate(
+ fosa_ads_actions_t *sched_actions,
+ frsh_thread_id_t thread,
+ fosa_ads_urgency_t urgency)
+{
+ return fosa_ose_adsactions_add( sched_actions, //sched_actions
+ ACTIVATE, //action
+ thread, //thread
+ urgency, //urgency
+ 0, //clock_id
+ 0, //sec
+ 0); //nsec
+}
+
+/**
+ * fosa_adsactions_add_suspend()
+ *
+ * Add a thread-suspend action
+ *
+ * This function adds a thread-suspend action to the object referenced
+ * by sched_actions, that will cause the thread identified by thread
+ * to be suspended waiting for a thread-activate action at the end of
+ * the scheduler operation. If the thread was already waiting for a
+ * thread-activate action the thread-suspend action has no effect. It
+ * is an error trying to suspend a thread that is blocked by the
+ * operating system.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * ENOMEM: There is insufficient memory to add this action
+ * EPOLICY: The thread specified by thread has its appscheduled
+ * attribute set to false,
+ * EINVAL: The value specified by sched_actions is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_suspend(
+ fosa_ads_actions_t *sched_actions,
+ frsh_thread_id_t thread)
+{
+ return fosa_ose_adsactions_add( sched_actions, //sched_actions
+ SUSPEND, //action
+ thread, //thread
+ 0, //urgency
+ 0, //clock_id
+ 0, //sec
+ 0); //nsec
+}
+
+/**
+ * fosa_adsactions_add_timeout()
+ *
+ * Add a timeout action
+ *
+ * This function adds a timeout action to the object referenced by
+ * sched_actions, that will cause the timeout() scheduler operation to
+ * be invoked if no other scheduler operation is invoked before
+ * timeout expires. The timeout shall expire when the clock specified by
+ * clock_id reaches the absolute time specified by the at_time
+ * argument.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * ENOMEM: There is insufficient memory to add this action
+ * EPOLICY: The thread specified by thread has its appscheduled
+ * attribute set to false,
+ * EINVAL: The value specified by sched_actions is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_timeout(
+ fosa_ads_actions_t *sched_actions,
+ fosa_clock_id_t clock_id,
+ const struct timespec *at_time)
+{
+ return fosa_ose_adsactions_add( sched_actions, //sched_actions
+ TIMEOUT, //action
+ current_process(), //thread
+ 0, //urgency
+ clock_id, //clock_id
+ at_time->tv_sec, //sec
+ at_time->tv_nsec); //nsec
+}
+
+/**
+ * fosa_adsactions_add_thread_notification()
+ *
+ * Add a timed-thread-notification action
+ *
+ * This function adds a thread-notification action associated with the
+ * thread specified in the thread argument that will cause the
+ * notification_for_thread() scheduler operation to be invoked at the
+ * time specified by at_time. This operation shall be invoked when the
+ * clock specified by clock_id reaches the absolute time specified by
+ * the at_time argument. In particular, a cpu-time clock may be used
+ * for parameter clock_id.Only one thread-notification can be active
+ * for each thread and clock. Calling the function shall remove the
+ * former thread-notification, if any, that had been programmed for
+ * the same thread and clock. A value of NULL for parameter at_time is
+ * used to cancel a previous thread-notification, if any, for the
+ * thread specified by thread and the clock specified by clock_id.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * ENOMEM: There is insufficient memory to add this action
+ * EPOLICY: The thread specified by thread has its appscheduled
+ * attribute set to false,
+ * EINVAL: The value specified by sched_actions is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_adsactions_add_thread_notification(
+ fosa_ads_actions_t *sched_actions,
+ frsh_thread_id_t thread,
+ fosa_clock_id_t clock_id,
+ const struct timespec *at_time)
+{
+ return fosa_ose_adsactions_add( sched_actions, //sched_actions
+ THREAD_NOTIFICATION,//action
+ thread, //thread
+ 0, //urgency
+ clock_id, //clock_id
+ at_time->tv_sec, //sec
+ at_time->tv_nsec); //nsec
+}
+
+
+/**
+ * fosa_ads_set_handled_signal_set()
+ *
+ * Specifiy the set of signals that will be handled by the application
+ * scheduler
+ *
+ * This function is used to dynamically set the set of signals that
+ * are handled by the application scheduler. When a signal included
+ * in this set is generated, the signal() primitive operation of the
+ * application scheduler shall be executed. When a signal in tis set
+ * is generated, it shall always imply the execution of the signal()
+ * primitive operation, regardless of whether that signal could be
+ * accepted by some other thread. Once the signal() primitive
+ * operation is executed the signal is consumed, so no signal handlers
+ * shall be executed and no threads using a sigwait operation shall
+ * return for that particular signal instance. For this function to
+ * succeed, it has to be called from a primitive operation of a
+ * scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EPOLICY: The function has not been called from a scheduler
+ * primitive operation
+ * EINVAL: The value specified by set is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_set_handled_signal_set(frsh_signal_t set[])
+{
+ /*
+ * author erth
+ *
+ * This function is not neccisary in OSE since set[] is used as an
+ * argument in the calls to fosa_signal_wait() and
+ * fosa_signal_timedwait() functions. Also decided to be empty in
+ * Barcelona meeting 2007-01-31.
+ */
+ return 0;
+}
+
+/**
+ * fosa_ads_invoke_withdata()
+ *
+ * Explicitly invoke the scheduler, with data
+ *
+ * This function can be used by any thread in the process to invoke
+ * the ads scheduler or to share data with it.
+ *
+ * If successful, the function shall cause the execution of the
+ * primitive operation explicit_call_with_data() of the ads scheduler
+ * with its thread parameter equal to the thread ID of the calling
+ * thread, and its msg_size parameter equal to msg_size. In addition,
+ * if msg_size is larger than zero, the function shall make available
+ * to the scheduler a memory area whose contents are identical to the
+ * memory area pointed to by msg in the msg parameter of the
+ * explicit_call_with_data() primitive operation (note that copying
+ * the information is not needed).
+ *
+ * The function shall not return until the system has finished
+ * execution of the explicit_call_with_data() primitive operation. If
+ * the reply argument is non NULL, the memory area pointed to by the
+ * reply parameter of explicit_call_with_data() primitive operation is
+ * copied into the memory area pointed to by reply, and its size is
+ * copied into the variable pointed to by reply_size. The size of the
+ * reply information is limited to the value FOSA_ADS_SCHEDINFO_MAX.
+ *
+ * The function shall fail if the size specified by msg_size is larger
+ * than FOSA_ADS_SCHEDINFO_MAX. The function shall fail if primitive
+ * operation explicit_call_with_data() is set to NULL for the ads
+ * scheduler.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EPOLICY: The function been called from inside a scheduler
+ * primitive operation
+ * EINVAL: The value of msg_size is less than zero or larger than
+ * FOSA_ADS_SCHEDINFO_MAX
+ * EMASKED: The operation cannot be executed because the primitive
+ * operation explicit_call_with_data() is set to NULL
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ads_invoke_withdata
+ (const void *msg, size_t msg_size, void *reply, size_t *reply_size)
+{
+ //Not implemented yet!!...........................................
+
+ /*
+ * author erth
+ *
+ * This function should send a message to the fosa_scheduler_process,
+ * that calls the frsh_callback_explicit_call_with_data(),
+ * that creates a reply message that are
+ * sent back to this process from fosa_scheduler_process,
+ * here we then set the reply message and
+ * this function return
+ *
+ * For example a call to frsh_contract_negotiate() results in a call
+ * to this function. If the messages were not sent the execution of the
+ * callback would be made of the calling processes. Which are not good.
+ */
+
+ return 0;
+ }
+
+/*}*/
+
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or
+// without modification, are permitted provided that the
+// following conditions are met:
+//
+// * Redistributions of source code must retain the above
+// copyright notice, this list of conditions and the
+// following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the
+// following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+// * Neither the name of FRESCOR nor the names of its
+// contributors may be used to endorse or promote products
+// derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+// -----------------------------------------------------------------------
+//fosa_clocks_and_timers.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include "fosa.h"
+#include "fosa_ose_implementation_specific.h"
+#include "malloc.h"
+
+//Debug purpose only.......................
+#include "stdio.h"
+
+/**
+ * @defgroup clocksandtimers Clocks and Timers
+ * @ingroup fosa
+ *
+ * This module defines the types and functions to abstract clocks and
+ * timers for the FRSH implementation.
+ *
+ * @{
+ **/
+
+
+
+/*************************
+ * Timing: Clocks
+ *************************/
+
+/**
+ * fosa_get_time()
+ *
+ * Get the time from a clock
+ *
+ * This function sets the variable pointed to by current_time to the
+ * current value of the clock specified by clockid, which may be the
+ * FOSA_CLOCK_REALTIME constant or a value obtained with
+ * fosa_get_cputime_clock()
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of clockid is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_clock_get_time(fosa_clock_id_t clockid,
+ struct timespec *current_time)
+{
+ if (clockid == FOSA_CLOCK_REALTIME) {
+ OSTICK ticks;
+ OSTICK micros;
+ ticks = get_systime(µs);
+ //If micros == NULL this are not provided.
+ fosa_ose_systime_to_timespec(ticks, micros, current_time);
+ } else if (fosa_ose_is_process(clockid)) {
+ // Opimization, save the last called pid and a pointer to it's
+ // execution time. Make if statement to check for it.
+
+ //The clock are an execution time measurement.
+ //extern struct* global_time_ptr;
+
+ // Find the pid in the global linked list.
+
+ // Save the executiontime in current_time->tv_nsec and
+ // current_time->tv_sec.
+ // fosa_ose_systime_to_timespec(systick, micro, current_time);
+ } else {
+ //No valid clock_id.
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+/**
+ * fosa_get_cputime_clock()
+ *
+ * Get the identifier of a cpu-time clock
+ *
+ * This function stores in the variable pointed to by clockid the
+ * identifier of a cpu-time clock for the thread specified by tid.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of tid is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_get_cputime_clock(frsh_thread_id_t tid, fosa_clock_id_t *clockid)
+{
+ //Might need to change. Possibility to have many clocks? Probably not
+ //One clock but many timers. .........................................
+
+ if (!fosa_ose_is_process(tid)) return EINVAL;
+ *clockid = (fosa_clock_id_t) tid;
+ return 0;
+}
+
+
+/*************************
+ * Timing: Timers
+ *************************/
+
+/**
+ * fosa_create_timer()
+ *
+ * Create a one-shot timer
+ *
+ * This function creates a timer based on the clock specified by clock,
+ * and associates to this timer a notification mechanism consisting of
+ * a signal and associated information. Initially, the timer is in the
+ * disarmed state, i.e., not counting time. It can be armed to start
+ * counting time with fosa_timer_arm().
+ *
+ * The function stores the identifier of the newly created timer in the
+ * variable pointed to by timerid.
+ *
+ * When the timer expires, the signal number specified by signal will be
+ * sent together with the information specified by info, to the thread
+ * that armed the timer (@see fosa_timer_arm()).
+ *
+ * In those implementations that do not support queueing a
+ * signal with information to a thread (such as POSIX), the signal may
+ * be sent to any thread that is waiting for this signal via
+ * fosa_signal_wait(). Portability can be ensured by having the receiver
+ * thread be the one who is waiting for the signal.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of clockid or signal is invalid
+ *
+ * EAGAIN: the system lacks enough resources to create the timer
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+ int fosa_timer_create
+ (fosa_clock_id_t clockid, frsh_signal_t signal,
+ frsh_signal_info_t info, fosa_timer_id_t *timerid)
+{
+ *timerid = (fosa_timer_id_t)malloc(sizeof(fosa_ose_timer_id_t));
+ fosa_timer_id_t timer_id = *timerid; //To clearify only.
+
+ timer_id->sig_no = signal;
+ timer_id->info = info;
+ timer_id->clock_id = clockid;
+ timer_id->ose_tmoref = -1;
+
+ return 0;
+}
+
+/**
+ * Delete a timer
+ *
+ * The function deletes the timer specified by timerid, which becomes
+ * unusable. If the timer was armed, it is automatically disarmed before
+ * deletion.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of timerid is not valid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_timer_delete(fosa_timer_id_t timerid)
+{
+ if (timerid->clock_id == FOSA_CLOCK_REALTIME) {
+ cancel_tmo(&(timerid->ose_tmoref));
+ } else {
+ //Maybe do something with some global data accessible in the
+ //swap-handlers...................................................
+ }
+ timerid->ose_tmoref = -1;
+ free(timerid);
+ //Errors taken care of by OSE.
+ return 0;
+}
+
+/**
+ * fosa_timer_arm()
+ *
+ * Arm a timer
+ *
+ * The timer specified by timer is armed and starts counting time.
+ *
+ * If abstime is true, the value pointed to by value is the absolute
+ * time at which the timer will expire. If value specifies a time instant
+ * in the past, the timer expires immediately.
+ *
+ * If abstime is false, the value pointed to by value is the relative interval
+ * that must elapse for the timer to expire.
+ *
+ * In both cases, absolute or relative, the time is measured with the clock
+ * associated with the timer when it was created.
+ *
+ * If the timer was already armed, the previous time or interval is discarded
+ * and the timer is rearmed with the new value.
+ *
+ * When the timer expires, it is disarmed.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of timerid or value is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_timer_arm
+ (fosa_timer_id_t timerid, bool abstime,
+ const struct timespec *value)
+{
+ /*printf("Timerid sig_no %d, info %d, clock_id %d, ose_tmoref %d\n",
+ timerid->sig_no, timerid->info.value, timerid->clock_id,
+ timerid->ose_tmoref);
+ printf("Lika? %d == %d\n",timerid->clock_id, FOSA_CLOCK_REALTIME);*/
+
+ OSTIME timeout_ms = value->tv_nsec / 1000000 +
+ value->tv_sec * 1000;
+
+ //if (timerid->ose_tmoref != -1) {
+ // restart_tmo(&(timerid->ose_tmoref), timeout_ms);
+ //}
+ //else
+ if (timerid->clock_id == FOSA_CLOCK_REALTIME) {
+ if (abstime) {
+ //Absolute time
+ } else {
+ fosa_ose_signal_t *ose_sig;
+ ose_sig = (fosa_ose_signal_t *)
+ alloc(sizeof(fosa_ose_signal_t), timerid->sig_no);
+ ose_sig->info = timerid->info;
+ ose_sig->sig_no = timerid->sig_no;
+
+ timerid->ose_tmoref = request_tmo_sig(timeout_ms,
+ (union SIGNAL **) &ose_sig);
+ }
+ } else {
+ if (abstime) {
+ return EINVAL;
+ /*
+ * author erth
+ *
+ * A absolute timer for a clock that measures the time a
+ * process has used the CPU does not make sense. Therefore
+ * error is given.
+ */
+ } else {
+ //En absolut timer mäter tiden jämfört med systemtiden. Medens
+ //en realtiv gör det i antal sekunder och nanosekunder från
+ //och med nu.
+
+ //Do something, preapare a signal?................................
+ }
+ }
+ return 0;
+}
+/*
+ * author erth
+ *
+ * Ange i den globala variabel som swap-handlern använder vilken
+ * timeouten är. Då startar swap-handlern att räkna tid? Om abstime är
+ * falsk.
+ */
+
+/**
+ * fosa_timer_disarm()
+ *
+ * Disarm a timer
+ *
+ * The timer specified by timer is disarmed, and will not expire unless
+ * it is rearmed. If the timer was already disramed, the function has
+ * no effect.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of timerid or value is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_timer_disarm(fosa_timer_id_t timerid)
+{
+ if (timerid->clock_id == FOSA_CLOCK_REALTIME) {
+ //OSTIME time = 500;
+ //restart_tmo(&(timerid->ose_tmoref),time);
+ //Hur kolla om signal är given?...................................
+ cancel_tmo(&(timerid->ose_tmoref));
+ } else {
+ //Maybe do something with some global data accessible in the
+ //swap-handlers...................................................
+ }
+ timerid->ose_tmoref = -1;
+ return 0;
+}
+/*
+ * author erth
+ *
+ * Ta bort timeouten i den globala variabel som swap-handlern använder.
+ * Då slutar swap-handlern att räkna tid?
+ */
+
+/*@}*/
+
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or
+// without modification, are permitted provided that the
+// following conditions are met:
+//
+// * Redistributions of source code must retain the above
+// copyright notice, this list of conditions and the
+// following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the
+// following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+// * Neither the name of FRESCOR nor the names of its
+// contributors may be used to endorse or promote products
+// derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+// -----------------------------------------------------------------------
+//fosa_mutexes_and_condvars.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include <ose.h>
+
+#include "frsh_configuration_parameters.h"
+
+#include "fosa.h"
+#include "fosa_ose_implementation_specific.h"
+
+/**
+ * @defgroup mutexesandcondvars Mutexes and Condvars
+ * @ingroup fosa
+ *
+ * This module defines the types and functions to abstract mutexes and
+ * conditional variables for the FRSH implementation.
+ *
+ * @{
+ **/
+
+/*******************************************************
+ * Mutexes with priority ceiling
+ ******************************************************/
+
+/**
+ * fosa_mutex_init()
+ *
+ * Initialize a frsh mutex
+ *
+ * The mutex pointed to by mutex is initialized as a mutex using
+ * the priority ceiling protocol. A priority ceiling of prioceiling
+ * is assigned to this mutex.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of prioceiling is invalid
+ * EAGAIN: the system lacked the necessary resources to create the mutex
+ * ENOMEM: Insufficient memory exists to initialize the mutex
+ * EBUSY: The system has detected an attempt to reinitialize the mutex
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_mutex_init(frsh_mutex_t *mutex, int prioceiling)
+{
+ if ((prioceiling < fosa_get_priority_min()) ||
+ (prioceiling > fosa_get_priority_max())) {
+ return FOSA_EINVAL;
+ }
+ // Other errors taken care of by OSE.
+
+ mutex->prio_ceiling = prioceiling;
+ // As initial value the lowest(!) OSE priority is used.
+ mutex->process_original_prio = FRSH_HIGHEST_THREAD_PRIORITY;
+ ose_mutex_init(&mutex->ose_mutex, 0);
+
+ return 0;
+}
+
+/**
+ * fosa_mutex_destroy()
+ *
+ * Destroy a frsh mutex
+ *
+ * The mutex pointed to by mutex is destroyed
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of mutex is invalid
+ * EBUSY: The mutex is in use (is locked)
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_mutex_destroy(frsh_mutex_t *mutex)
+{
+ ose_mutex_destroy(&mutex->ose_mutex);
+ // Errors taken care of by OSE.
+ return 0;
+}
+
+/**
+ * fosa_mutex_set_prioceiling()
+ *
+ * Dynamically set the priority ceiling of a mutex
+ *
+ * This function locks the mutex (blocking the calling thread if
+ * necessary) and after it is locked it changes its priority ceiling
+ * to the value specified by new_ceiling, and then it unlocks the
+ * mutex. The previous value of the ceiling is returned in
+ * old_ceiling.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of mutex or prioceiling is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_mutex_set_prioceiling
+ (frsh_mutex_t *mutex, int new_ceiling, int *old_ceiling)
+{
+ if ((new_ceiling < fosa_get_priority_min()) ||
+ (new_ceiling > fosa_get_priority_max())) {
+ return FOSA_EINVAL;
+ }
+
+ *old_ceiling = mutex->prio_ceiling;
+
+ ose_mutex_lock(&mutex->ose_mutex);
+ mutex->prio_ceiling = new_ceiling;
+ ose_mutex_unlock(&mutex->ose_mutex);
+
+ return 0;
+}
+
+/**
+ * fosa_mutex_get_prioceiling()
+ *
+ * Dynamically get the priority ceiling of a mutex
+ *
+ * This function copies into the variable pointed to by ceiling the
+ * current priority ceiling of the mutex referenced by mutex
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of mutex is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_mutex_get_prioceiling(const frsh_mutex_t *mutex, int *ceiling)
+{
+ //if (???) return FOSA_EINVAL; //How to check this?..........................
+
+ *ceiling = mutex->prio_ceiling;
+
+ return 0;
+}
+
+/**
+ * fosa_mutex_lock()
+ *
+ * Lock a mutex
+ *
+ * This function locks the mutex specified by mutex. If it is already
+ * locked, the calling thread blocks until the mutex becomes
+ * available. The operation returns with the mutex in the locked
+ * state, with the calling thread as its owner.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of mutex is invalid, or the priority of the
+ * calling thread is higher than the priority ceiling of the mutex
+ * EDEADLK: the current thread already owns this mutex
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_mutex_lock(frsh_mutex_t *mutex)
+{
+ PROCESS pid = current_process();
+ OSPRIORITY ose_orig_pri = get_pri(pid);
+
+ // Mapping of OSE prio to FOSA prio.
+ int original_frsh_prio = fosa_get_priority_max()
+ + fosa_get_priority_min() - (int) ose_orig_pri;
+ if (original_frsh_prio > mutex->prio_ceiling) {
+ // This is a step from the ICPP ptotocol, where no error is given.
+ return FOSA_EINVAL;
+ }
+
+ OSPRIORITY ose_prio_ceiling = (OSPRIORITY) fosa_get_priority_max()
+ + fosa_get_priority_min() - mutex->prio_ceiling;
+ set_pri_for(pid, ose_prio_ceiling);
+
+ ose_mutex_lock( &(mutex->ose_mutex) );
+ // Change the original priority of mutex after lock is locked.
+ mutex->process_original_prio = ose_orig_pri;
+ // Other errors taken care of by OSE.
+ return 0;
+}
+
+/**
+ * fosa_mutex_trylock()
+ *
+ * Try locking a mutex
+ *
+ * This function is identical to fosa_mutex_lock() except that if the
+ * mutex is already locked the call returns immediately with an error
+ * indication.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of mutex is invalid, or the priority of the
+ * calling thread is higher than the priority ceiling of the mutex
+ * EBUSY: the mutex was already locked
+ *
+ * Alternatively, except for EBUSY, in case of error the
+ * implementation is allowed to notify it to the system console and
+ * then terminate the FRSH implementation and dependant applications
+ **/
+int fosa_mutex_trylock(frsh_mutex_t *mutex)
+{
+ PROCESS pid = current_process();
+ OSPRIORITY ose_orig_pri = get_pri(pid);
+
+ //Mapping of OSE prio to FOSA prio.
+ int original_frsh_prio = fosa_get_priority_max() + fosa_get_priority_min()
+ - (int) ose_orig_pri;
+ if (original_frsh_prio > mutex->prio_ceiling) {
+ // This is a step from the ICPP ptotocol, where no error is given.
+ return FOSA_EINVAL;
+ }
+ OSPRIORITY ose_prio_ceiling = (OSPRIORITY) fosa_get_priority_max()
+ + fosa_get_priority_min() - mutex->prio_ceiling;
+ set_pri_for(pid, ose_prio_ceiling);
+
+ int ret_code = ose_mutex_trylock(&mutex->ose_mutex);
+
+ // Other errors taken care of by OSE.
+ if (ret_code == 0) {
+ set_pri_for(pid, ose_orig_pri);
+ return EBUSY;
+ } else {
+ mutex->process_original_prio = ose_orig_pri;
+ return 0;
+ }
+}
+
+/**
+ * fosa_mutex_unlock()
+ *
+ * Unlock a mutex
+ *
+ * This function must be called by the owner of the mutex referenced
+ * by mutex, to unlock it. If there are threads blocked on the mutex
+ * the mutex becomes available and the highest priority thread is
+ * awakened to acquire the mutex.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of mutex is invalid
+ * EPERM: the calling thread is not the owner of the mutex
+ *
+ * Alternatively, except for EBUSY, in case of error the
+ * implementation is allowed to notify it to the system console and
+ * then terminate the FRSH implementation and dependant applications
+ **/
+int fosa_mutex_unlock(frsh_mutex_t *mutex)
+{
+ // Errors taken care of by OSE.
+ ose_mutex_unlock( &(mutex->ose_mutex) );
+ set_pri_for(current_process(), mutex->process_original_prio);
+
+ return 0;
+}
+
+/**********************
+ * Condition variables
+ *********************/
+
+/**
+ * fosa_cond_init()
+ *
+ * Initiatize a condition variable
+ *
+ * The condition variable referenced by cond is initialized with
+ * the attributes required by the FOSA implementation.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EAGAIN: the system lacked the necessary resources to create the
+ * condition variable
+ * ENOMEM: Insufficient memory exists to initialize the condition variable
+ * EBUSY: The system has detected an attempt to reinitialize the
+ * condition variable
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_cond_init(fosa_cond_t *cond)
+{
+ cond->pid_queue_length = -1;
+ return 0;
+}
+
+/**
+ * fosa_cond_destroy()
+ *
+ * Destroy a condition variable
+ *
+ * The condition variable pointed to by cond is destroyed
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of cond is invalid
+ * EBUSY: The condition variable is in use (a thread is waiting on it)
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_cond_destroy(fosa_cond_t *cond)
+{
+ //With other design a free memory operation could be done here.............
+ return 0;
+}
+
+/**
+ * fosa_cond_signal()
+ *
+ * Signal a condition variable
+ *
+ * This call unblocks at least one of the threads that are waiting on
+ * the condition variable referenced by cond. If there are no threads
+ * waiting, the function has no effect
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of cond is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_cond_signal(fosa_cond_t *cond)
+{
+ fosa_ose_signal_t *sig;
+ sig = (fosa_ose_signal_t *)alloc(
+ sizeof(fosa_ose_signal_t), FOSA_OSE_CONDVAR_SIGNAL);
+
+ PROCESS receiver = cond->pid[0];
+ send((union SIGNAL **)&sig, receiver);
+
+ cond->pid[cond->pid_queue_length] = (PROCESS) 0;
+ cond->pid_queue_length -=1;
+ int i;
+ for (i = 0; i <= cond->pid_queue_length; ++i) {
+ cond->pid[i] = cond->pid[i+1];
+ }
+ return 0;
+}
+
+/**
+ * fosa_cond_broadcast()
+ *
+ * Broadcast a condition variable
+ *
+ * This call unblocks all of the threads that are waiting on the
+ * condition variable referenced by cond. If there are no threads
+ * waiting, the function has no effect.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of cond is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_cond_broadcast(fosa_cond_t *cond)
+{
+ fosa_ose_signal_t* sig[cond->pid_queue_length];
+ int i;
+ PROCESS receiver;
+
+ for (i = 0; i <= cond->pid_queue_length; ++i) {
+ sig[i] = (fosa_ose_signal_t *)alloc(
+ sizeof(fosa_ose_signal_t), FOSA_OSE_CONDVAR_SIGNAL);
+ receiver = cond->pid[i];
+ send((union SIGNAL **)&sig[i], receiver);
+ cond->pid[i] = (PROCESS) 0;
+ }
+ cond->pid_queue_length = -1;
+ return 0;
+}
+
+/**
+ * fosa_cond_wait()
+ *
+ * Wait at a condition variable
+ *
+ * This call is used to block on the condition variable referenced by
+ * cond. It shall be called with the mutex referenced by mutex
+ * locked. The function releases the mutex and blocks the calling
+ * thread until the condition is signalled by some other thread and
+ * the calling thread is awakened. Then it locks the mutex and
+ * returns with the mutex locked by the calling thread.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of cond or mutex is invalid, or different
+ * mutexes were used for concurrent wait operations on cond, or
+ * the mutex was not owned by the calling thread
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_cond_wait(fosa_cond_t *cond, frsh_mutex_t *mutex)
+{
+ fosa_mutex_unlock(mutex);
+
+ cond->pid_queue_length += 1;
+ cond->pid[cond->pid_queue_length] = current_process();
+
+ static const SIGSELECT condvar_signal[] = {1,FOSA_OSE_CONDVAR_SIGNAL};
+ union SIGNAL *sig;
+
+ sig = receive(condvar_signal);
+
+ fosa_mutex_lock(mutex);
+ return 0;
+}
+
+/**
+ * fosa_cond_timedwait()
+ *
+ * Wait at a condition variable, with a timeout
+ *
+ * This function is equal to fosa_cond_wait(), except that the maximum
+ * wait time is limited to the absolute time referenced by abstime, as
+ * measured by the FOSA_CLOCK_REALTIME clock.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the value of cond or mutex or abstime is invalid, or different
+ * mutexes were used for concurrent wait operations on cond, or
+ * the mutex was not owned by the calling thread
+ * ETIMEDOUT: the timeout expired
+ *
+ * Alternatively, except for ETIMEDOUT, in case of error the
+ * implementation is allowed to notify it to the system console and
+ * then terminate the FRSH implementation and dependant applications
+ **/
+int fosa_cond_timedwait(fosa_cond_t *cond, frsh_mutex_t *mutex,
+ const struct timespec abstime)
+{
+ fosa_mutex_unlock(mutex);
+
+ cond->pid_queue_length += 1;
+ cond->pid[cond->pid_queue_length] = current_process();
+
+ static const SIGSELECT condvar_signal[] = {1,FOSA_OSE_CONDVAR_SIGNAL};
+ union SIGNAL *sig;
+
+ OSTIME millisec = abstime.tv_sec * 1000 + abstime.tv_nsec / 1000;
+
+ sig = receive_w_tmo(millisec, condvar_signal);
+
+ if(sig == NIL) return ETIMEDOUT;
+
+ fosa_mutex_lock(mutex);
+ return 0;
+}
+
+/*@}*/
+
+
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or
+// without modification, are permitted provided that the
+// following conditions are met:
+//
+// * Redistributions of source code must retain the above
+// copyright notice, this list of conditions and the
+// following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the
+// following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+// * Neither the name of FRESCOR nor the names of its
+// contributors may be used to endorse or promote products
+// derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+// -----------------------------------------------------------------------
+//fosa_ose_implementation_specific.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include "ose.h"
+#include "heapapi.h"
+
+#include "fosa.h"
+#include "fosa_ose_implementation_specific.h"
+
+#include "frsh.h"
+#include "frsh_scheduler.h"
+
+
+//For debug purpose only.
+#include "stdio.h"
+
+//The following function is placed in the fosa_app_def_sched.c file.
+extern int fosa_ose_adsactions_add(fosa_ads_actions_t* sched_actions,
+ action_t action,
+ frsh_thread_id_t thread,
+ fosa_ads_urgency_t urgency,
+ fosa_clock_id_t clock_id,
+ time_t sec,
+ long nsec);
+
+/* Application Defined Scheduling Callbacks */
+/********************************************/
+//extern void frsh_callback_init(void *sched_data, void *arg);
+/*
+extern void frsh_callback_new_thread(void *sched_data, frsh_thread_id_t thread,
+ fosa_ads_actions_t *actions, struct timespec *current_time);
+
+extern static void frsh_callback_thread_terminate(void *sched_data, frsh_thread_id_t thread,
+ fosa_ads_actions_t *actions, struct timespec *current_time);
+
+extern static void frsh_callback_thread_ready(void *sched_data, frsh_thread_id_t thread,
+ fosa_ads_actions_t *actions, struct timespec *current_time);
+
+extern static void frsh_callback_thread_block(void *sched_data, frsh_thread_id_t thread,
+ fosa_ads_actions_t *actions, struct timespec *current_time);
+
+extern static void frsh_callback_change_sched_param_thread(void *sched_data, frsh_thread_id_t thread,
+ fosa_ads_actions_t *actions,
+ struct timespec *current_time);
+
+extern static void frsh_callback_explicit_call_with_data(void * sched_data,
+ frsh_thread_id_t thread,
+ const void * msg, size_t msg_size,
+ void **reply, size_t *reply_size,
+ fosa_ads_actions_t * actions,
+ struct timespec *current_time);
+
+
+extern static void frsh_callback_notification_for_thread(void * sched_data,
+ frsh_thread_id_t thread,
+ fosa_clock_id_t clock,
+ fosa_ads_actions_t * actions,
+ struct timespec *current_time);
+
+
+extern static void frsh_callback_timeout(void *sched_data, fosa_ads_actions_t *actions,
+ struct timespec *current_time);
+
+extern static void frsh_callback_signal(void *sched_data, frsh_signal_t signal, frsh_signal_info_t siginfo,
+ fosa_ads_actions_t *actions, struct timespec *current_time);
+
+extern static void frsh_callback_appsched_error(void *sched_data, frsh_thread_id_t thread,
+ fosa_ads_error_cause_t cause, fosa_ads_actions_t *actions);
+*/
+
+
+//Osäker på hur dessa funktioner skall implementeras...........................
+
+/**
+ * fosa_ose_convert_prio_to_ose()
+ *
+ * Maps fosa priority to ose priority. FOSA internal function.
+ * Faster if defined as a macro?...............................................
+ **/
+//OSPRIORITY fosa_ose_convert_prio_to_ose(int fosa_prio)
+//{
+// return (OSPRIORITY) fosa_get_priority_max() +
+// fosa_get_priority_min() - fosa_prio;
+//}
+
+/**
+ * fosa_ose_convert_prio_to_fosa()
+ *
+ * Maps ose priority to fosa priority. FOSA internal function.
+ **/
+//int fosa_ose_convert_prio_to_fosa(OSPRIORITY ose_prio)
+//{
+// return fosa_get_priority_max() +
+// fosa_get_priority_min() - (int) ose_prio;
+//}
+
+unsigned int process_name_number = 0;
+
+bool fosa_ose_keys_initialized = false;
+bool fosa_ose_keys_taken[FOSA_MAX_KEYS];
+
+bool fosa_ose_is_process(PROCESS Pid)
+{
+ switch (get_ptype(Pid))
+ {
+ case OS_BG_PROC:
+ case OS_PRI_PROC:
+ case OS_TI_PROC:
+ case OS_INT_PROC:
+ case OS_PHANTOM:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void fosa_ose_ads_actions_init(fosa_ads_actions_t *sched_actions)
+{
+ sched_actions->FirstAction = NULL;
+ sched_actions->LastAction = NULL;
+}
+
+void fosa_ose_adsactions_remove_first(fosa_ads_actions_t *sched_actions)
+{
+ fosa_ose_action_t* action_to_remove;
+
+ action_to_remove = sched_actions->FirstAction;
+ sched_actions->FirstAction = sched_actions->FirstAction->NextAction;
+ if (sched_actions->FirstAction == NULL) {
+ sched_actions->LastAction = NULL;
+ }
+
+ heap_free_shared(action_to_remove);
+}
+
+void fosa_ose_systime_to_timespec(unsigned long ticks,
+ unsigned long microsec, struct timespec* time)
+{
+ // If the unsigned long are 32 bit then this function can measure up
+ // to 1,36 years before it loops to zero.
+ unsigned long microsec_per_tick = system_tick();
+ unsigned long tics_per_sec = (1000000 / microsec_per_tick);
+ time->tv_sec = ticks / tics_per_sec;
+ time->tv_nsec = (ticks % tics_per_sec) * 10000000 + microsec * 1000;
+}
+
+void fosa_ose_execute_action_activate(PROCESS pid)
+{
+ start(pid);
+}
+
+void fosa_ose_execute_action_suspend(PROCESS pid)
+{
+ /*
+ * author erth
+ *
+ * A check to see that the process have not locked a mutex before the
+ * stop command are executed would be good to avoid deadlooks.
+ */
+ stop(pid);
+}
+
+void fosa_ose_execute_action_reject(PROCESS pid)
+{
+ //Send signal to the pid with the message to reject it.
+ fosa_ose_event_signal_t *reply_sig;
+ reply_sig = (fosa_ose_event_signal_t *)
+ alloc(sizeof(fosa_ose_event_signal_t),
+ FOSA_OSE_REJECT);
+ send((union SIGNAL **)&reply_sig, pid);
+}
+
+void fosa_ose_execute_action_accept(PROCESS pid)
+{
+ //Send signal to the pid with the message to accept it.
+ fosa_ose_event_signal_t *reply_sig;
+ reply_sig = (fosa_ose_event_signal_t *)
+ alloc(sizeof(fosa_ose_event_signal_t),
+ FOSA_OSE_ACCEPT);
+ send((union SIGNAL **)&reply_sig, pid);
+}
+
+fosa_ose_process_info_t* fosa_ose_processes = NULL;
+
+fosa_ose_process_info_t* fosa_ose_process_get_node(frsh_thread_id_t pid) {
+ if (fosa_ose_processes == NULL) return NULL; //Not found.
+ fosa_ose_process_info_t* node = fosa_ose_processes;
+
+ while(node->pid != pid) {
+ node = node->NextProcess;
+ if (node == NULL) break;
+ }
+ return node;
+}
+
+int fosa_ose_process_list_node_remove(frsh_thread_id_t pid) {
+ if (fosa_ose_processes == NULL) return FOSA_EINVAL;
+ fosa_ose_process_info_t* node = fosa_ose_processes;
+ fosa_ose_process_info_t* prev_node = NULL;
+
+ while(node->pid != pid) {
+ if (node->NextProcess == NULL) return FOSA_EINVAL;
+ prev_node = node;
+ node = node->NextProcess;
+ }
+
+ if (prev_node == NULL) {
+ //New first node in list, or now list gets empty.
+ fosa_ose_processes = node->NextProcess;
+ } else {
+ //Not first node.
+ prev_node->NextProcess = node->NextProcess;
+ }
+
+ if(node->appsched_param != NULL)
+ heap_free_shared(node->appsched_param);
+ heap_free_shared(node);
+
+ return 0;
+}
+
+int frsh_ose_callback_test() {
+ ramlog_printf("Sucess by: frsh_ose_callback_test()");
+ return 0;
+}
+
+int fosa_ose_adsactions_add_test(
+ fosa_ads_actions_t *sched_actions,
+ action_t string)
+{
+ return fosa_ose_adsactions_add( sched_actions, //sched_actions
+ string, //action
+ current_process(), //thread
+ 0, //urgency
+ 0, //clock_id
+ 0, //sec
+ 0); //nsec
+}
+
+
+void fosa_ose_scheduler_ops_init(fosa_ads_scheduler_ops_t *scheduler_ops)
+{
+ //Cnage functions to point to here!..........................................
+ scheduler_ops->init = (void *) &frsh_ose_callback_test;
+ scheduler_ops->new_thread = (void *) &frsh_ose_callback_test;
+ scheduler_ops->thread_terminate = (void *) &frsh_ose_callback_test;
+ scheduler_ops->thread_ready = (void *) &frsh_ose_callback_test;
+ scheduler_ops->thread_block = (void *) &frsh_ose_callback_test;
+ scheduler_ops->signal = (void *) &frsh_ose_callback_test;
+ scheduler_ops->change_sched_param_thread = (void *) NULL;
+ scheduler_ops->explicit_call_with_data = (void *) NULL;
+ scheduler_ops->notification_for_thread = (void *) NULL;
+ scheduler_ops->timeout = (void *) NULL;
+ scheduler_ops->appsched_error = (void *) NULL;
+}
+
+void fosa_ose_send_event_to_scheduler( PROCESS event_pid,
+ SIGSELECT event_sig)
+{
+ //Send signal to fosa scheduler.
+ fosa_ose_event_signal_t *sig;
+ sig = (fosa_ose_event_signal_t *)
+ alloc(sizeof(fosa_ose_event_signal_t),
+ event_sig);
+ sig->pid = event_pid;
+ PROCESS scheduler_pid;
+ hunt("fosa_scheduler_process", 0,
+ &scheduler_pid, (union SIGNAL **) NULL);
+ if (scheduler_pid != 0) {
+ send((union SIGNAL **)&sig, scheduler_pid);
+ } else {
+ ramlog_printf(
+ "Failiure by: fosa_scheduler_process not found.\n");
+ }
+}
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or
+// without modification, are permitted provided that the
+// following conditions are met:
+//
+// * Redistributions of source code must retain the above
+// copyright notice, this list of conditions and the
+// following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the
+// following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+// * Neither the name of FRESCOR nor the names of its
+// contributors may be used to endorse or promote products
+// derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+// -----------------------------------------------------------------------
+//fosa_ose_implementation_specific.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+/*
+ * Intended to be used only by internal .c files to include all
+ * internal declarations visible only within the src library directory.
+ *
+ * It is not used by any .h file to avoid include deadlocks.
+ */
+
+
+#ifndef FOSA_OSE_IMPLEMENTATION_SPECIFIC_H
+#define FOSA_OSE_IMPLEMENTATION_SPECIFIC_H
+
+#include "fosa_ose_signals.sig" //The only place where this file is incl.
+#include "fosa_ose_types.h"
+
+#include "ose.h"
+//#include "fosa.h"
+
+//Debug purpose only:
+#include "ramlog.h"
+
+/*************************
+ * Global Data
+ *************************/
+
+/*
+ * author erth
+ *
+ * This global variable is used to initialize a process when made by
+ * fosa_thread_create. It makes the names of the processes to
+ * "fosa_ose_1", "fosa_ose_2" and so on.
+ */
+extern unsigned int process_name_number;
+
+/*
+ * author erth
+ *
+ * Global bool to keep track of if the keys array are initialized (all set
+ * two false) these are used in the functions fosa_key_create() and
+ * fosa_key_destroy().
+ */
+extern bool fosa_ose_keys_initialized;
+extern bool fosa_ose_keys_taken[];
+
+/*************************
+ * General Help Functions
+ *************************/
+
+/*
+ * author erth
+ *
+ * Function to convert systime, or actually system_tick and microseconds
+ * to timespec, or seconds and nanoseconds.
+ */
+void fosa_ose_systime_to_timespec(unsigned long ticks,
+ unsigned long microsec, struct timespec* time);
+
+/*************************
+ * Process Specific Functions
+ *************************/
+
+/*
+ * author erth
+ *
+ * Internal function that takes a pid as argument and returns true if it
+ * is an active process (OS_BG_PROC, OS_PRI_PROC, OS_TI_PROC, OS_INT_PROC
+ * or OS_PHANTOM process), otherwise false are returned.
+ */
+bool fosa_ose_is_process(PROCESS Pid);
+
+extern fosa_ose_process_info_t* fosa_ose_processes;
+
+/*
+ * author erth
+ *
+ * This function returns a pointer to the node with the given pid in the
+ * fosa_ose_processes list.
+ */
+fosa_ose_process_info_t* fosa_ose_process_get_node(frsh_thread_id_t pid);
+
+/*
+ * author erth
+ *
+ * This function is called to remove a node in the list fosa_ose_processes
+ * prefferable from the kill handler, or the scheduler.
+ *
+ * return 0 if success.
+ */
+int fosa_ose_process_list_node_remove(frsh_thread_id_t pid);
+
+/*************************
+ * Application defined scheduling functions
+ *************************/
+
+/*
+ * author erth
+ *
+ * Function to initialize an action queue. This function should be used
+ * before the fosa_ads_actions_t type can be used by other functions.
+ */
+void fosa_ose_ads_actions_init(fosa_ads_actions_t *sched_actions);
+
+/*
+ * author erth
+ *
+ * Function to remove the first action in an fosa_ads_actions_t queue.
+ */
+void fosa_ose_adsactions_remove_first(fosa_ads_actions_t *sched_actions);
+
+void fosa_ose_execute_action_activate(PROCESS pid);
+
+void fosa_ose_execute_action_suspend(PROCESS pid);
+
+void fosa_ose_execute_action_reject(PROCESS pid);
+
+void fosa_ose_execute_action_accept(PROCESS pid);
+
+void fosa_ose_execute_action_thread_notification(
+ fosa_ose_action_t* action);
+
+void fosa_ose_execute_action_timeout(
+ fosa_ose_action_t* action);
+
+
+/*
+ * author erth
+ *
+ * This function initialize the scheduler operations.
+ */
+void fosa_ose_scheduler_ops_init(fosa_ads_scheduler_ops_t *scheduler_ops);
+
+/*
+ * author erth
+ *
+ * This function are used to send an event to the fosa scheduler.
+ * @param event_pid the pid that the event is about.
+ * @param event_isg the event that has occured.
+ */
+void fosa_ose_send_event_to_scheduler( PROCESS event_pid,
+ SIGSELECT event_sig);
+
+
+/*************************
+ * Test Help Functions
+ *************************/
+
+//For test purpose only........remove.....................................
+//Bad design if this has to be here!!!....................................
+extern void * test_function(char * text);
+
+/*
+ * author erth
+ *
+ * Callback to test the callback functionality of fosa. Returns 0 if
+ * succesful. Otherwise it returns an error.
+ */
+int frsh_ose_callback_test();
+
+/*
+ * author erth
+ *
+ * fosa_ose_adsactions_add_test()
+ *
+ * Test action that can be added to an actions list.
+ *
+ * This function adds a test action to the that will cause the
+ * test action to be invoked.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * ENOMEM: There is insufficient memory to add this action
+ * EPOLICY: The thread specified by thread has its appscheduled
+ * attribute set to false,
+ * EINVAL: The value specified by sched_actions is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_ose_adsactions_add_test(fosa_ads_actions_t *sched_actions,
+ action_t string);
+
+/**
+ * fosa_ose_convert_prio_to_ose()
+ *
+ * Maps fosa priority to ose priority. FOSA internal function.
+ **/
+//OSPRIORITY fosa_ose_convert_prio_to_ose(int fosa_prio);
+
+/**
+ * fosa_ose_convert_prio_to_fosa()
+ *
+ * Maps ose priority to fosa priority. FOSA internal function.
+ **/
+//int fosa_ose_convert_prio_to_fosa(OSPRIORITY ose_prio);
+
+
+#endif /* FOSA_OSE_IMPLEMENTATION_SPECIFIC_H */
+
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+//fosa_ose_signals.h\r
+//==============================================\r
+// ******** ****** ******** **********\r
+// **///// /** ** **////// /** /**\r
+// ** /** ** /** /** /**\r
+// ******* /** ** /********* /**********\r
+// **//// /** ** ////////** /**//////**\r
+// ** /** ** /** /** /**\r
+// ** /** ** ******** /** /**\r
+// // /******/ //////// // // \r
+//\r
+// FOSA(Frescor Operating System Adaptation layer)\r
+//================================================\r
+\r
+/*\r
+ * Intended to be used only by fosa_ose_implementation_specific.h. \r
+ * Declared like this to use the OSE way of signal declarations.\r
+ * \r
+ * It is not used by any .h file apart from that one to avoid include \r
+ * deadlocks and it is neither not accessible to any API client.\r
+ */\r
+\r
+#ifndef FOSA_OSE_SIGNALS_SIG\r
+#define FOSA_OSE_SIGNALS_SIG\r
+\r
+#include "ose.h"\r
+\r
+//used for debugging.\r
+//#include "stdio.h"\r
+\r
+/**\r
+ * @defgroup fosa_ose OSE implementation of fosa\r
+ * @ingroup fosa\r
+ *\r
+ * This module defines the fosa functions and types for OSE.\r
+ *\r
+ * @{\r
+ **/\r
+\r
+/*************************\r
+ * Decalaration of OSE signals.\r
+ *************************/ \r
+\r
+/*\r
+ * author erth\r
+ *\r
+ * General signal type used of fosa.\r
+ */\r
+typedef struct {\r
+ SIGSELECT sig_no;\r
+ frsh_signal_info_t info;\r
+} fosa_ose_signal_t;\r
+\r
+/*\r
+ * author erth\r
+ *\r
+ * Signal number used when a new process are created. Specially when the \r
+ * scheduler are created.\r
+ */\r
+#define FOSA_OSE_STARTUP_SIGNAL 256\r
+\r
+/*\r
+ * author erth\r
+ *\r
+ * Signal used when a new process is crated. To pass information about\r
+ * the POSIX like entrypoint. \r
+ */\r
+typedef struct {\r
+ SIGSELECT sig_no;\r
+ frsh_thread_code_t code;\r
+ void * arg;\r
+} fosa_ose_signal_startup_t;\r
+\r
+\r
+/*\r
+ * author erth\r
+ *\r
+ * Signal used when starting the fosa scheduler process. This information\r
+ * need to be passed to the newly created process.\r
+ */\r
+typedef struct {\r
+ SIGSELECT sig_no;\r
+ fosa_ads_scheduler_ops_t scheduler_ops; \r
+ size_t scheduler_data_size;\r
+ void * init_args;\r
+ size_t init_args_size;\r
+} fosa_ose_scheduler_startup_t;\r
+\r
+\r
+/*\r
+ * author erth\r
+ *\r
+ * Signal used when asking the scheduler if a new thread can be created.\r
+ */\r
+typedef struct {\r
+ SIGSELECT sig_no;\r
+ PROCESS tid; \r
+} fosa_ose_new_thread_t;\r
+\r
+/*\r
+ * author erth\r
+ *\r
+ * Signal used when signalling for scheduling events.\r
+ */\r
+typedef struct {\r
+ SIGSELECT sig_no;\r
+ PROCESS pid; \r
+} fosa_ose_event_signal_t;\r
+\r
+/*\r
+ * author erth\r
+ *\r
+ * Signal number used when signaling condition variables.\r
+ */\r
+#define FOSA_OSE_CONDVAR_SIGNAL 257\r
+\r
+/*\r
+ * author erth\r
+ *\r
+ * Signal types ar declared here to contain the following parameters. A \r
+ * union SIGNAL declaration must include a signal number and the signal\r
+ * structures of the signals that will be used by the program.\r
+ */\r
+union SIGNAL\r
+{\r
+ SIGSELECT sig_no;\r
+ fosa_ose_signal_t fosa_ose_signal;\r
+ fosa_ose_signal_startup_t fosa_ose_signal_startup;\r
+ fosa_ose_new_thread_t fosa_ose_new_thread;\r
+ fosa_ose_scheduler_startup_t fosa_ose_scheduler_startup;\r
+ fosa_ose_event_signal_t fosa_ose_event_signal;\r
+};\r
+\r
+/*\r
+ * author erth\r
+ *\r
+ * Signal numbers used when signaling callbacks from OSE to scheduler.\r
+ */\r
+#define FOSA_OSE_BLOCK_SIGNAL 1\r
+#define FOSA_OSE_TERMINATE_SIGNAL 2\r
+#define FOSA_OSE_SIGNAL_SCHED_SIGNAL 3\r
+#define FOSA_OSE_READY_SIGNAL 4\r
+#define FOSA_OSE_TEST_EVENT_SIGNAL 5\r
+#define FOSA_OSE_SHUTDOWN_FRSH 6\r
+#define FOSA_OSE_NEW_THREAD_SIGNAL 7\r
+#define FOSA_OSE_INIT_SIGNAL 8\r
+#define FOSA_OSE_EMPTY 9\r
+\r
+#define FOSA_OSE_REJECT 10\r
+#define FOSA_OSE_ACCEPT 11\r
+\r
+#endif /* FOSA_OSE_SIGNALS_SIG */\r
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+\r
+/*\r
+ * author erth\r
+ *\r
+ * This file are used by two parts of the fosa impelementation. Booth the\r
+ * fosa functions and the ose-handlers such as create and swap handlers. \r
+ */\r
+\r
+#ifndef FOSA_OSE_TYPES_H_\r
+#define FOSA_OSE_TYPES_H_\r
+\r
+#include <ose.h>\r
+\r
+/*\r
+ * author erth\r
+ *\r
+ * Structure to make a linked list with the FRSH processes. This contains\r
+ * all information needed by FRSH that should be saved per process. But \r
+ * this list actually does not belong to any process. Node added when \r
+ * process crated and removed when it terminates. \r
+ */\r
+typedef struct fosa_ose_process_info_def {\r
+ PROCESS pid;\r
+ OSBOOLEAN app_scheduled;\r
+ void* appsched_param;\r
+ size_t appsched_param_size;\r
+ struct fosa_ose_process_info_def* NextProcess;\r
+ \r
+ //Executiontime\r
+ OSTICK nr_of_ticks;\r
+ signed long nr_of_micros;\r
+ \r
+ //Budgeted time should also be here.....\r
+ \r
+} fosa_ose_process_info_t;\r
+\r
+/*Extend the memory storage area for each process for fast acess of \r
+ * data in kernel handlers (avoiding list iteration). This is done by\r
+ * configuring the "user area" statically. Add USER_AREA (<size>) to\r
+ * krn.con file (sfk-win32 folder) where size is the extra number of \r
+ * bytes that is to be allocated in the user area for each process. \r
+ * The user area can be reached only by the kernel handlers (create,\r
+ * swap in/out and kill). Should contain:\r
+ * -pointer to the list storage node for the current process\r
+ * -slice start time (temporary value not needed globally)\r
+ */\r
+typedef struct user_area{\r
+ OSTICK tick_slice_start_time; /*unsigned long = 4 byte*/\r
+ OSTICK micro_slice_start_time; /*unsigned long = 4 byte*/\r
+ fosa_ose_process_info_t *list_position_ptr; /*pointer (4 byte ?)*/\r
+ OSBOOLEAN fosa_process; /*size of unsigned char (1byte?)*/\r
+ PROCESS pid; /*4byte*/\r
+}user_area_t; /* sizeof(struct user_area) must match krn.con USER_AREA configuration! */\r
+\r
+#endif /*FOSA_OSE_TYPES_H_*/\r
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or
+// without modification, are permitted provided that the
+// following conditions are met:
+//
+// * Redistributions of source code must retain the above
+// copyright notice, this list of conditions and the
+// following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the
+// following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+// * Neither the name of FRESCOR nor the names of its
+// contributors may be used to endorse or promote products
+// derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+// -----------------------------------------------------------------------
+//fosa_threads_and_signals.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include <ose.h>
+#include <stdio.h>
+#include <heapapi.h>
+#include <string.h>
+
+#include "frsh_configuration_parameters.h"
+
+#include "fosa.h"
+#include "fosa_ose_implementation_specific.h"
+
+/*
+ * author erth
+ *
+ * General entrypoint used when creating a process with POSIX look alike
+ * entrypoint. Recieves a signal and calls function received in signal
+ * with arguments also received in signal.
+ */
+static OS_PROCESS(fosa_ose_process_entrypoint)
+{
+ static const SIGSELECT accepted_signal[]
+ = { 1 ,FOSA_OSE_STARTUP_SIGNAL };
+ union SIGNAL* sig = receive(accepted_signal);
+
+ switch(sig->sig_no) {
+ case FOSA_OSE_STARTUP_SIGNAL:
+ {
+ fosa_ose_signal_startup_t *startsig
+ = (fosa_ose_signal_startup_t *)sig;
+
+ // Call FOSA entrypoint.
+ startsig->code( startsig->arg );
+
+ break;
+ }
+ default:
+ // Call error() for all unexpected signals.
+ error2(0xFFFFFFFE, (OSERRCODE)sig);
+ break;
+ }
+ free_buf(&sig);
+ kill_proc(current_process());
+}
+
+/**
+ * @defgroup threadandsignals Thread and Signals
+ * @ingroup fosa
+ *
+ * This module defines the functions that manipulate frsh_threads and
+ * frsh_signals inside FRSH implementation.
+ *
+ * Applications can refer to FRSH threads but they cannot create them
+ * directly, instead they must use frsh_thread_create*() which in turn
+ * use fosa_thread_create().
+ *
+ * For signals, we assume that the OS provides a direct mapping
+ * for frsh_signal_t and frsh_signal_info_t in the native interface.
+ *
+ * @{
+ **/
+
+
+
+/*************************
+ * Thread identification
+ *************************/
+
+/**
+ * fosa_thread_equal()
+ *
+ * Compare two thread identifiers to determine if they refer to the
+ * same thread
+ **/
+
+bool fosa_thread_equal(frsh_thread_id_t t1, frsh_thread_id_t t2)
+{
+ return (t1 == t2);
+}
+
+
+/**
+ * fosa_thread_self()
+ *
+ * Return the thread id of the calling thread
+ **/
+frsh_thread_id_t fosa_thread_self()
+{
+ return current_process();
+}
+
+/*************************
+ * Thread creation and termination
+ *************************/
+
+/**
+ * fosa_thread_create()
+ *
+ * This function creates a new thread using the attributes specified
+ * in attr. If attr is NULL, default attributes are used. The new
+ * thread starts running immediately, executing the function specified
+ * by code, with an argument equal to arg. Upon successful return, the
+ * variable pointed to by tid will contain the identifier of the newly
+ * created thread. The set of signals that may be synchronously
+ * accepted is inherited from the parent thread.
+ *
+ * Returns 0 if successful; otherwise it returs a code error:
+ *
+ * EAGAIN: the system lacks the necessary resources to create a
+ * new thread or the maximum number of threads has been
+ * reached
+ *
+ * EINVAL: the value specified by attr is invalid (for instance,
+ * it has not been correctly initialized)
+ *
+ * EREJECT: the cretion of the thread was rejected by the frsh scheduler
+ * possibly because of incorrect attributes, or because the
+ * requested minimum capacity cannot be guaranteed
+ *
+ **/
+int fosa_thread_create
+ (frsh_thread_id_t *tid, const frsh_thread_attr_t *attr,
+ frsh_thread_code_t code, void * arg)
+{
+ //Attributes
+ OSPRIORITY priority;
+ OSADDRESS stack_size;
+ fosa_ose_process_info_t* NewProcess =
+ (fosa_ose_process_info_t *)heap_alloc_shared(
+ sizeof(fosa_ose_process_info_t), __FILE__, __LINE__);
+
+ //Initialize new node for fosa_ose_processes list.
+ if(attr == NULL) {
+ // If NULL, the lowest(!) OSE priority is used.
+ priority = FRSH_HIGHEST_THREAD_PRIORITY;
+ stack_size = 1000;
+ NewProcess->pid = 0; //Unknown at this stage.
+ NewProcess->app_scheduled = false;
+ NewProcess->appsched_param = NULL;
+ NewProcess->appsched_param_size = 0;
+ } else {
+ if ((attr->prio < fosa_get_priority_min()) ||
+ (attr->prio > fosa_get_priority_max())) {
+ return FOSA_EINVAL;
+ }
+ priority = attr->prio;
+ stack_size = attr->stack_size;
+ NewProcess->pid = 0; //Unknown at this stage.
+ NewProcess->app_scheduled = attr->app_scheduled;
+ NewProcess->appsched_param = attr->appsched_param; //!............Kasst?
+ NewProcess->appsched_param_size = attr->appsched_param_size;
+ }
+ NewProcess->nr_of_micros = 0;
+ NewProcess->nr_of_ticks = 0;
+
+ //Add new first node in fosa_ose_processes list.
+ NewProcess->NextProcess = fosa_ose_processes;
+ fosa_ose_processes = NewProcess;
+
+ //Create process name
+ char name[25];
+ sprintf( name, "fosa_ose_%u", ++process_name_number );
+
+ (*tid) = create_process(
+ OS_PRI_PROC, // Process type.
+ name, // Name.
+ fosa_ose_process_entrypoint,// Entrypoint.
+ stack_size, // Stacksize.
+ priority, // Priority.
+ 0, // Timeslice.
+ 0, // 0 = Part of callers block.
+ NULL, // No signal redirection.
+ 0, // OSvector.
+ 0); // OSuser.
+
+ fosa_ose_processes->pid = *tid;
+
+ //Make the scheduler to call the new_thread callback.
+ fosa_ose_send_event_to_scheduler(*tid, FOSA_OSE_NEW_THREAD_SIGNAL);
+
+ //Receive from scheduler if accepted or rejected.
+ SIGSELECT sel_reply[] = {2, FOSA_OSE_REJECT, FOSA_OSE_ACCEPT};
+ fosa_ose_event_signal_t *reply_sig;
+ reply_sig = (fosa_ose_event_signal_t *) receive(sel_reply);
+ if (reply_sig->sig_no != FOSA_OSE_ACCEPT) {
+ //event_sig->sig_no == FOSA_OSE_REJECT or something else.
+ fosa_ose_process_list_node_remove(0);
+ kill_proc(*tid);
+ return FOSA_EREJECT;
+ }
+
+ //New thread accepted
+ start(*tid);
+
+ //Allocate, initialize and send signal with fosa entrypoint.
+ fosa_ose_signal_startup_t *entrypoint;
+ entrypoint = (fosa_ose_signal_startup_t *)
+ alloc(sizeof(fosa_ose_signal_startup_t),
+ FOSA_OSE_STARTUP_SIGNAL);
+ entrypoint->code = code;
+ entrypoint->arg = arg;
+ send((union SIGNAL **)&entrypoint, *tid);
+
+ return 0;
+}
+
+
+/**
+ * Note: no thread termination primitive is provided. The termination
+ * of a thread will be notifoed by the system to the FRSH scheduler
+ * through the scheduler API
+ **/
+
+
+/**************************************************
+ * Thread-specific data
+ * (extended with access from a different thread)
+ *
+ * Several data items (pointers) may be associated with each thread
+ * Each item is identified through a key, an integer value between 0
+ * and FOSA_MAX_KEYS-1. The caller is responsible of allocating and
+ * deallocating the memory area pointed to by the pointer
+ **************************************************/
+
+/**
+ * fosa_key_create()
+ *
+ * Create a new key for thread specific data.
+ *
+ * Prior to setting data in a key, we need ask the system to create
+ * one for us.
+ *
+ * @return 0 if successful \n
+ * FOSA_EINVAL If we already have reached the FOSA_MAX_KEYS limit.
+ * FOSA_ENOMEM If there are no enough memory resources to
+ * create the key.
+ **/
+int fosa_key_create(int *key) {
+ /*
+ * author erth
+ *
+ * This function should return a new int each time it is called. If
+ * destroy is called for a number that int is freed and can be
+ * returned again.
+ */
+ if (!fosa_ose_keys_initialized) {
+ memset(fosa_ose_keys_taken, false, sizeof(bool) * FOSA_MAX_KEYS);
+ fosa_ose_keys_initialized = true;
+ }
+
+ int i;
+ for (i = 0; i < FOSA_MAX_KEYS; i++) {
+ if (fosa_ose_keys_taken[i] == false) break;
+ }
+
+ if (i >= FOSA_MAX_KEYS) {
+ return FOSA_EINVAL;
+ }
+
+ // First empty key found (number i).
+ fosa_ose_keys_taken[i] = true;
+ *key = i;
+
+ return 0;
+}
+
+/**
+ * fosa_key_destroy()
+ *
+ * Destroy a key
+ *
+ * This destroys the key and isables its use in the system
+ *
+ * @return 0 if successful \n
+ * FOSA_EINVAL The key is not initialised or is not in FOSA key range.
+ **/
+int fosa_key_destroy(int key) {
+ fosa_ose_keys_taken[key] = false;
+ return 0;
+}
+
+/**
+ * fosa_thread_set_specific_data()
+ *
+ * Set thread-specific data
+ *
+ * For the thread identified by tid, the thread-specifid data field
+ * identified by key will be set to the value specified by value
+ *
+ * Returns 0 if successful; otherwise, an error code is returned
+ * EINVAL: the value of key is not between 0 and FOSA_MAX_KEYS-1
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_set_specific_data
+ (int key, frsh_thread_id_t tid, const void * value)
+{
+ if ((key < 0) ||
+ (key > FOSA_MAX_KEYS-1)) {
+ return FOSA_EINVAL;
+ }
+
+ char ose_key[30];
+ sprintf(ose_key, "fosa_key_%u", key);
+
+ bool sucess = set_envp(tid, ose_key, (OSADDRESS) value);
+
+ if (sucess) return 0;
+ else return FOSA_EINVAL;
+}
+
+
+
+/**
+ * fosa_thread_get_specific_data()
+ *
+ * Get thread-specific data
+ *
+ * For the thread identified by tid, the thread-specifid data field
+ * identified by key will be copied to the variable pointed to by value
+ *
+ * Returns 0 if successful; otherwise, an error code is returned
+ * EINVAL: the value of key is not between 0 and FOSA_MAX_KEYS-1
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_get_specific_data(int key, frsh_thread_id_t tid,
+ void ** value)
+{
+ if ((key < 0) ||
+ (key > FOSA_MAX_KEYS-1)) {
+ return FOSA_EINVAL;
+ }
+
+ char ose_key[30];
+ sprintf( ose_key, "fosa_key_%u", key );
+
+ *value = (void*) get_envp(tid, ose_key);
+
+ return 0;
+}
+
+
+/******************************************************************
+ * Thread scheduling
+ *
+ * This implementation of FRSH assumes an underlying fixed priority
+ * scheduler with priorities in a range, with a minimum and a
+ * maximumm, a number of priority levels with at least 31
+ * priorities. A larger number implies a larger priority. In systems
+ * in which the underlying scheduler uses the opposite convention, a
+ * mapping is automatically provided by the OS adaptation layer.
+ *******************************************************************/
+
+/**
+ * fosa_get_priority_max()
+ *
+ * Return the maximum priority value used in this implementation
+ **/
+int fosa_get_priority_max()
+{
+ return FRSH_HIGHEST_THREAD_PRIORITY;
+}
+// Priority values in OSE are 0 - 31, where 0 represents the highest
+// priority and 31 the lowest.
+
+/**
+ * fosa_get_priority_min()
+ *
+ * Return the minimum priority value used in this implementation
+ **/
+int fosa_get_priority_min()
+{
+ return FRSH_LOWEST_THREAD_PRIORITY;
+}
+// Priority values in OSE are 0 - 31, where 0 represents the highest
+// priority and 31 the lowest.
+
+/**
+ * fosa_thread_attr_set_prio()
+ *
+ * Change the priority of a thread attributes object
+ *
+ * The priority of the thread attriutes object specified by attr is
+ * set to the value specified by prio. This function has no runtime
+ * effect on the priority, except when the attributes object is used
+ * to create a thread, when it will be created with the specified
+ * priority
+ *
+ * Returns 0 if successful, or the following error code:
+ * EINVAL: the specified priority value is not between the
+ * minimum and the maximum priorities defined in this
+ * FRSH implementation
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_attr_set_prio(frsh_thread_attr_t *attr, int prio)
+{
+ if ((prio < fosa_get_priority_min()) ||
+ (prio > fosa_get_priority_max())) {
+ return FOSA_EINVAL;
+ }
+ else {
+ //Make ose priority from fosa priority, and set attr.
+ attr->prio = (OSPRIORITY) fosa_get_priority_max()
+ + fosa_get_priority_min() - prio;
+
+ return 0;
+ }
+}
+
+/**
+ * fosa_thread_attr_get_prio()
+ *
+ * Get the priority from a thread attributes object
+ *
+ * This function sets the variable pointed to by prio to the
+ * priority stored in the thread attributes object attr.
+ *
+ * Returns 0
+ **/
+int fosa_thread_attr_get_prio
+ (const frsh_thread_attr_t *attr, size_t *prio)
+{
+ // Map OSE priority to FOSA priority.
+ *prio = fosa_get_priority_max() + fosa_get_priority_min()
+ - (int) attr->prio;
+
+ return 0;
+}
+
+/**
+ * fosa_thread_set_prio()
+ *
+ * Dynamically change the priority of a thread
+ *
+ * The priority of the thread identified by tid is
+ * set to the value specified by prio.
+ *
+ * Returns 0 if successful, or the following error code:
+ * EINVAL: the specified priority value is not between the
+ * minimum and the maximum priorities defined in this
+ * FRSH implementation
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_set_prio(frsh_thread_id_t tid, int prio)
+{
+ if ((prio < fosa_get_priority_min()) ||
+ (prio > fosa_get_priority_max())) {
+ return FOSA_EINVAL;
+ }
+ // Map FOSA priority to OSE priority.
+ OSPRIORITY new_ose_prio = (OSPRIORITY) fosa_get_priority_max()
+ + fosa_get_priority_min() - prio;
+
+ OSPRIORITY org_prio = get_pri(tid);
+
+ if (org_prio == new_ose_prio) return 0;
+
+ int new_prio = set_pri_for(tid, new_ose_prio);
+ if(new_prio == org_prio) {
+ return FOSA_EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+/**
+ * fosa_thread_get_prio()
+ *
+ * Dynamically get the priority of a thread
+ *
+ * This function sets the variable pointed to by prio to the
+ * priority of the thread identified by tid
+ *
+ * Returns 0
+ **/
+int fosa_thread_get_prio (frsh_thread_id_t tid, int *prio)
+{
+ OSPRIORITY ose_prio = get_pri(tid);
+ // Map OSE priority to FOSA priority.
+ *prio = fosa_get_priority_max() + fosa_get_priority_min()
+ - (int) ose_prio;
+ return 0;
+}
+
+
+
+/*******************************************************************
+ * Signals
+ *
+ * Signals represent events that may be notified by the system, or
+ * sent explicitly by the application, and for which a thread may
+ * synchronously wait. Signals carry an associated piece of
+ * information (an integer or a pointer) and are queued until they are
+ * accepted. Signals are identified by an integer signal number (of
+ * the type frsh_signal_t) in the range FOSA_SIGNAL_MIN,
+ * FOSA_SIGNAL_MAX. This range is required to have at least <tbd>
+ * values.
+ *******************************************************************/
+
+/**
+ * fosa_set_accepted_signals()
+ *
+ * Establish the set of signals that may be synchronously accepted
+ * by the calling thread
+ *
+ * The function uses the array of signal numbers specified by set,
+ * which must be of size equal to size
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the array contains one or more values which are not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size
+ * is less than 0
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_set_accepted_signals(frsh_signal_t set[], int size)
+{
+ /*
+ * author erth
+ *
+ * This function is not neccisary in OSE since set[] is used as an
+ * argument in the calls to fosa_signal_wait() and
+ * fosa_signal_timedwait() functions. Also decided to be empty in
+ * Barcelona meeting 2007-01-31.
+ */
+ return 0;
+}
+
+
+/**
+ * fosa_signal_queue()
+ *
+ * Queue a signal
+ *
+ * This function is used to explicitly send a signal with a specified
+ * value
+ *
+ * The signal number specified by signal is sent together with the
+ * information specified by info, to the thread identified by
+ * receiver. In those implementations that do not support queueing a
+ * signal with information to a thread (such as POSIX), the signal may
+ * be sent to any thread that is waiting for this signal via
+ * fosa_signal_wait(). Portability can be ensured by having the receiver
+ * thread be the one who is waiting for the signal.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the signal specified by signal is not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX
+ *
+ * EAGAIN: no resources are available to queue the signal; the
+ * maximum number of queued signals has been reached, or a
+ * systemwide resource limit has been exceeded
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_signal_queue
+ (frsh_signal_t signal, frsh_signal_info_t info,
+ frsh_thread_id_t receiver)
+{
+ if ((signal < FOSA_SIGNAL_MIN) || (signal > FOSA_SIGNAL_MAX)) {
+ return FOSA_EINVAL;
+ }
+
+ fosa_ose_signal_t *ose_sig;
+ ose_sig = (fosa_ose_signal_t *)
+ alloc(sizeof(fosa_ose_signal_t), signal);
+
+ ose_sig->info = info;
+ send((union SIGNAL **)&ose_sig, receiver);
+
+ //Other errors taken care of by OSE.
+ return 0;
+}
+
+
+/**
+ * fosa_signal_queue_scheduler()
+ *
+ * Queue a signal destinated to the scheduler
+ *
+ * This is a special case of fosa_signal_queue() in which the
+ * destinator is the scheduler itself. It is needed by the service
+ * thread to notify the results to the scheduler.
+ *
+ * The problem with this case is that, depending on the implementation,
+ * this call would be translated to a true signal or to a scheduler
+ * notification message.
+ *
+ * Besides for the scheduler we don't have always a destinator
+ * thread_id needed in frsh_signal_queue for OSE.
+ *
+ * So the fosa implementation will solve this issue internally.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the signal specified by signal is not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX
+ *
+ * EAGAIN: no resources are available to queue the signal; the
+ * maximum number of queued signals has been reached, or a
+ * systemwide resource limit has been exceeded
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_signal_queue_scheduler(frsh_signal_t signal,
+ frsh_signal_info_t info) {
+ PROCESS scheduler;
+ hunt("fosa_scheduler_process", 0, &scheduler, (union SIGNAL **) NULL);
+ if (scheduler == 0) return EINVAL;
+
+ return fosa_signal_queue(signal, info, scheduler);
+}
+
+
+/**
+ * fosa_signal_wait()
+ *
+ * Wait for a signal
+ *
+ * The function waits for the arrival of one of the signals in the
+ * array of signal numbers specified by set, which must be of size
+ * equal to size. If there is a signal already queued, the function
+ * returns immediately. If there is no signal of the specified set
+ * queued, the calling thread is suspended until a signal from that
+ * set arrives. Upon return, if signal_received is not NULL the number
+ * of the signal received is stored in the variable pointed to by
+ * signal_received; and if info is not NULL the associated information
+ * is stored in the variable pointed to by info.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the array contains one or more values which are not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size
+ * is less than 0
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_signal_wait
+ (frsh_signal_t set[], int size, frsh_signal_t *signal_received,
+ frsh_signal_info_t *info)
+{
+ if (size < 0) return FOSA_EINVAL;
+ int i = 0;
+ for (i = 0; i < size; ++i) {
+ if ((set[i] < FOSA_SIGNAL_MIN) ||
+ (set[i] > FOSA_SIGNAL_MAX)) {
+ return FOSA_EINVAL;
+ }
+ }
+ // No check for signals before receiving is needed.
+
+ // Receive
+ SIGSELECT sig_set[size+1];
+ sig_set[0] = size;
+ for (i = 1; i < size+1; ++i)
+ sig_set[i] = set[i-1];
+ union SIGNAL *ose_sig_union;
+ ose_sig_union = receive(sig_set);
+
+ fosa_ose_signal_t *ose_sig =
+ (fosa_ose_signal_t *)ose_sig_union;
+
+ // Return
+ if( signal_received != NULL )
+ *signal_received = ose_sig->sig_no;
+ if( info != NULL )
+ *info = ose_sig->info;
+
+ free_buf(&ose_sig_union);
+
+ return 0;
+}
+
+
+/**
+ * fosa_signal_timedwait()
+ *
+ * Timed wait for a signal
+ *
+ * This function behaves the same as fosa_signal_wait(), except that
+ * the suspension time is limited to the time interval specified in
+ * the timespec structure referenced by timeout.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * EINVAL: the array contains one or more values which are not
+ * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size
+ * is less than 0, or timeout is invalid
+ * EAGAIN: The timeout expired
+ *
+ * Alternatively, in case of the EINVAL error the implementation is
+ * allowed to notify it to the system console and then terminate the
+ * FRSH implementation and dependant applications
+ **/
+int fosa_signal_timedwait
+ (frsh_signal_t set[], int size, frsh_signal_t *signal_received,
+ frsh_signal_info_t *info, const struct timespec *timeout)
+{
+ if (size < 0) return FOSA_EINVAL;
+ int i = 0;
+ for (i = 0; i < size; ++i) {
+ if ((set[i] < FOSA_SIGNAL_MIN) ||
+ (set[i] > FOSA_SIGNAL_MAX)) {
+ return FOSA_EINVAL;
+ }
+ }
+ // No check for signals before receiving is needed.
+
+ // Receive
+ SIGSELECT sig_set[size+1];
+ sig_set[0] = size;
+ for (i = 1; i < size+1; ++i)
+ sig_set[i] = set[i-1];
+
+ OSTIME millisec = timeout->tv_sec * 1000 + timeout->tv_nsec / 1000;
+
+ union SIGNAL *ose_sig_union;
+ ose_sig_union = receive_w_tmo(millisec, sig_set);
+
+ // Timed out?
+ if(ose_sig_union == NIL) return FOSA_EAGAIN;
+
+ fosa_ose_signal_t *ose_sig =
+ (fosa_ose_signal_t *)ose_sig_union;
+
+ // Return
+ if( signal_received != NULL )
+ *signal_received = ose_sig->sig_no;
+ if( info != NULL )
+ *info = ose_sig->info;
+
+ free_buf(&ose_sig_union);
+
+ return 0;
+}
+
+/*}*/
--- /dev/null
+TARGETS := lib\r
+include ../../environment.mk\r
+\r
+COMPANY = Enea Embedded Technology AB\r
+VERSION = 1.0\r
+LIBDESC = CPU load measurements\r
+\r
+#object files for fosa_handlers library\r
+LIBOBJECTS += fosa_handlers.o\r
+LIBOBJECTS += fosa_ose_exe_time.o\r
+\r
+#Path to source code for $(LIBOBJECTS)\r
+vpath %.c $(REFSYSROOT)/modules/frescor_fosa_handlers\r
+\r
+INCLUDE += -I$(REFSYSROOT)/modules/frescor_fosa/src_ose\r
+INCLUDE += -I$(REFSYSROOT)/modules/frescor_fosa/include\r
+INCLUDE += -I$(REFSYSROOT)/modules/frescor_frsh/include\r
+\r
+include $(REFSYSROOT)/modules/modules.mk\r
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or
+// without modification, are permitted provided that the
+// following conditions are met:
+//
+// * Redistributions of source code must retain the above
+// copyright notice, this list of conditions and the
+// following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the
+// following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+// * Neither the name of FRESCOR nor the names of its
+// contributors may be used to endorse or promote products
+// derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+// -----------------------------------------------------------------------
+
+/*
+ * author erth
+ *
+ * File containing swap handlers for application defined scheduling.
+ */
+#include "ose.h"
+#include "cpu_intlock.h"
+#include "stdio.h"
+#include "ramlog.h"
+#include "efs.h"
+#include "ose_heap.h"
+
+#include "fosa.h"
+#include "fosa_ose_implementation_specific.h"
+
+extern fosa_ose_process_info_t* fosa_ose_processes;
+
+static PROCESS time_hogs[64];
+static int alert_cnt;
+
+static PROCESS terminated_pids[64];
+static int terminate_cnt;
+
+/*
+ * author erth
+ *
+ * The process is created and started by adding this to osemain.con
+ * PRI_PROC( time_hog_alerter, time_hog_alerter, 1000, 2, DEFAULT, 0
+ * , NULL )
+ */
+OS_PROCESS(fosa_ose_block_callback)
+{
+ //ramlog_printf("I processen time_hog_alerter.\n");
+ //printf("I processen time_hog_alerter.\n");
+
+ //struct OS_pcb *pcbbuf;
+ set_pri(0); /* Make me as important as I should be. */
+ set_fsem(0, current_process());
+ Msr msr;
+
+ for(;;)
+ {
+ wait_fsem(1);
+ LOCK_SAVE(msr);
+ if (alert_cnt > 0)
+ {
+ PROCESS pid = time_hogs[--alert_cnt];
+
+ /* This code can be used to decide if the process are in the
+ waiting state or not.
+ pcbbuf = get_pcb(pid);
+ OSADDRESS tProcState = pcbbuf->status;
+
+ if (tProcState == zero)
+ {
+ // Process is waiting.
+ //printf("Process %x waiting!\n", pid);
+ }
+ free_buf( (union SIGNAL **) &pcbbuf); */
+
+ fosa_ose_send_event_to_scheduler( pid, FOSA_OSE_BLOCK_SIGNAL);
+
+ }
+ LOCK_RESTORE(msr);
+ }
+}
+
+
+/*
+ * author erth
+ *
+ * This handler is pointed out in the file krn.con in the rtose/sfk-win32
+ * build directory. Where also the user area size are set.
+ */
+void fosa_ose_swap_out_handler2(struct user_area *ua)
+{
+ if ((fosa_ose_processes == NULL) ||
+ (ua->fosa_process == FALSE)) {
+ return;
+ }
+
+ extern PROCESS fosa_ose_block_callback_;
+
+ /*
+ * These two 'secret' kernel calls are needed to make it safe to call
+ * signal_fsem from a swapout handler.
+ */
+ extern void ZZS0910(void);
+ extern OSBOOLEAN ZZS0911(void);
+ Msr msr;
+
+ LOCK_SAVE(msr);
+ if (alert_cnt >= sizeof(time_hogs) / sizeof(time_hogs[0]))
+ error(0xdeaddead); /* time_hogs array too small. */
+ time_hogs[alert_cnt++] = current_process(); /* Now swapping out. */
+ LOCK_RESTORE(msr);
+ ZZS0910(); /* lock_dispatcher */
+ signal_fsem(fosa_ose_block_callback_);
+ ZZS0911(); /* unlock_dispatcher */
+
+}
+
+/*
+ * author erth
+ *
+ * The process is created and started by adding this to osemain.con
+ * PRI_PROC( time_hog_alerter, time_hog_alerter, 1000, 2, DEFAULT, 0
+ * , NULL )
+ */
+OS_PROCESS(fosa_ose_terminate_callback)
+{
+ set_pri(0); /* Make me as important as I should be. */
+ set_fsem(0, current_process());
+ Msr msr;
+
+ for(;;)
+ {
+ wait_fsem(1);
+ LOCK_SAVE(msr);
+ if (terminate_cnt > 0)
+ {
+ PROCESS pid = terminated_pids[--terminate_cnt];
+
+ fosa_ose_send_event_to_scheduler(pid,
+ FOSA_OSE_TERMINATE_SIGNAL);
+ }
+ LOCK_RESTORE(msr);
+ }
+}
+
+/*
+ * author erth
+ *
+ * This handler is pointed out in the file krn.con in the rtose/sfk-win32
+ * build directory. Where also the user area size are set.
+ */
+void fosa_ose_kill_handler(struct user_area *ua, PROCESS pid)
+{
+ if ((fosa_ose_processes == NULL) ||
+ (ua->fosa_process == FALSE)) {
+ return;
+ }
+
+ extern PROCESS fosa_ose_terminate_callback_;
+
+ /*
+ * author Fredrik Bredberg
+ *
+ * These two 'secret' kernel calls are needed to make it safe to
+ * call signal_fsem from a swapout handler.
+ */
+ extern void ZZS0910(void);
+ extern OSBOOLEAN ZZS0911(void);
+ Msr msr;
+
+ LOCK_SAVE(msr);
+ if (terminate_cnt >=
+ sizeof(terminated_pids) / sizeof(terminated_pids[0]))
+ error(0xdeaddead); /* terminated_pids array too small. */
+ terminated_pids[terminate_cnt++] = pid; /* Now swapping out. */
+ LOCK_RESTORE(msr);
+ ZZS0910(); /* lock_dispatcher */
+ signal_fsem(fosa_ose_terminate_callback_);
+ ZZS0911(); /* unlock_dispatcher */
+}
+
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+\r
+/**\r
+ * @file fosa_ose_exe_time.c\r
+ * @brief: Using swap handlers to measure execution time for \r
+ * individual ose processes. Time is measured in system ticks + a \r
+ * number of micro seconds. The temporary slice start time is saved in\r
+ * the process specific user area and the elapsed execution time is \r
+ * saved in a shared memory linked list.\r
+ * \r
+ * $Author: xmlin $$Date: 19/06/07 \r
+ * \r
+ */\r
+\r
+#include "ose.h"\r
+#include "stdlib.h"\r
+#include "malloc.h"\r
+#include "ramlog.h" \r
+#include "heapapi.h" \r
+#include "ose_heap.h"\r
+\r
+#include "string.h"\r
+#include "fosa_ose_types.h"\r
+\r
+extern fosa_ose_process_info_t* fosa_ose_processes;\r
+OSTIME micros_per_tick;\r
+\r
+/*Create handler is called when a process is to be created\r
+ * -set inital values to user_area variables\r
+ */\r
+void fosa_ose_create_handler(user_area_t *user_area_ptr, PROCESS id){\r
+ \r
+ if(fosa_ose_processes == NULL){ \r
+ /*Start up process*/\r
+ user_area_ptr->fosa_process = FALSE;\r
+ return;\r
+ }\r
+ else{\r
+ /*Possible FOSA Process*/\r
+ user_area_ptr->fosa_process = TRUE;\r
+ \r
+ /*initialize user area*/\r
+ user_area_ptr->pid = id;\r
+ user_area_ptr->list_position_ptr = NULL;\r
+ user_area_ptr->tick_slice_start_time = 0;\r
+ user_area_ptr->micro_slice_start_time = 0;\r
+ \r
+ micros_per_tick = system_tick();\r
+ ramlog_printf("FOSA HANDLERS: Create %x\n", id); \r
+ return;\r
+ }\r
+}\r
+\r
+\r
+/*Swap in handler is called when a process execution is started\r
+ * -If first time in swap in find the node of interest\r
+ * -If the node is not found it is not a fosa process\r
+ * -If a node is found save a pointer to that node in the user_area\r
+ * -also save the process slice swap in time\r
+ */\r
+void fosa_ose_swap_in_handler(user_area_t *user_area_ptr){\r
+ \r
+ if(user_area_ptr->fosa_process == FALSE){\r
+ /*if(test_app_started == 1)\r
+ ramlog_printf("FOSA HANDLERS: PREEMPTION by %x\n", user_area_ptr->pid);*/\r
+ return;\r
+ }\r
+ \r
+ if(fosa_ose_processes == NULL){\r
+ user_area_ptr->fosa_process = FALSE;\r
+ /*if(test_app_started == 1)\r
+ ramlog_printf("FOSA HANDLERS: PREEMPTION by %x\n", user_area_ptr->pid);*/\r
+ return;\r
+ }\r
+ \r
+ OSTICK ticks;\r
+ OSTICK micros;\r
+ ticks = get_systime(µs);\r
+ user_area_ptr->tick_slice_start_time = ticks;\r
+ user_area_ptr->micro_slice_start_time = micros;\r
+ \r
+ if(user_area_ptr->list_position_ptr != NULL){\r
+ /*Not first time in swap in*/\r
+ //ramlog_printf("FOSA HANDLERS: PREEMPTION - fosa process %x SWAPPED BACK IN\n", user_area_ptr->pid);\r
+ return;\r
+ }\r
+ \r
+ /*First time in swap in --- user_area_ptr->list_position_ptr == NULL*/\r
+ //ramlog_printf("FOSA HANDLERS: %x SWAPPED IN\n", user_area_ptr->pid);\r
+ fosa_ose_process_info_t *tmp_node_ptr = fosa_ose_processes;\r
+ \r
+ for(;;){\r
+ if(tmp_node_ptr->pid == user_area_ptr->pid){\r
+ \r
+ //ramlog_printf("FOSA HANDLERS: NODE found for: %x %x\n", \r
+ //tmp_node_ptr->pid, user_area_ptr->pid);\r
+ \r
+ user_area_ptr->list_position_ptr = tmp_node_ptr;\r
+ user_area_ptr->fosa_process = TRUE;\r
+ break;\r
+ }\r
+ \r
+ if(tmp_node_ptr->NextProcess != NULL){\r
+ \r
+ tmp_node_ptr = tmp_node_ptr->NextProcess;\r
+ }\r
+ else{\r
+ ramlog_printf("FOSA HANDLERS: NO node found with pid: %x => IGNORE process\n", \r
+ user_area_ptr->pid);\r
+ user_area_ptr->fosa_process = FALSE;\r
+ break;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+\r
+/*Swap out handler is called when a process slice is to terminate\r
+ * - calculate slice execution time\r
+ * - add to previous execution time for the process\r
+ * - save new total execution time value in the linked list\r
+ */\r
+void fosa_ose_swap_out_handler(user_area_t *user_area_ptr){\r
+ \r
+ if(user_area_ptr->fosa_process == FALSE){\r
+ /*if(test_app_started == 1)\r
+ ramlog_printf("FOSA HANDLERS: DISPATCH process: %x\n", user_area_ptr->pid);*/\r
+ return;\r
+ }\r
+ //ramlog_printf("FOSA HANDLERS: DISPATCH fosa process: %x\n", user_area_ptr->list_position_ptr->pid);\r
+ \r
+ OSTICK ticks;\r
+ signed long micros;\r
+ ticks = get_systime(µs);\r
+ \r
+ ticks = ticks-(user_area_ptr->tick_slice_start_time);\r
+ micros = micros-(user_area_ptr->micro_slice_start_time);\r
+ (user_area_ptr->list_position_ptr)->nr_of_ticks += ticks;\r
+ (user_area_ptr->list_position_ptr)->nr_of_micros += micros; \r
+ \r
+ while((user_area_ptr->list_position_ptr)->nr_of_micros < 0){\r
+ (user_area_ptr->list_position_ptr)->nr_of_ticks--;\r
+ (user_area_ptr->list_position_ptr)->nr_of_micros = micros_per_tick + (user_area_ptr->list_position_ptr)->nr_of_micros; \r
+ }\r
+ while((user_area_ptr->list_position_ptr)->nr_of_micros >= micros_per_tick){\r
+ (user_area_ptr->list_position_ptr)->nr_of_ticks++;\r
+ (user_area_ptr->list_position_ptr)->nr_of_micros =(user_area_ptr->list_position_ptr)->nr_of_micros - micros_per_tick;\r
+ }\r
+ user_area_ptr->tick_slice_start_time = 0;\r
+ user_area_ptr->micro_slice_start_time = 0;\r
+ return;\r
+}\r
+\r
+\r
+/*Delete node function\r
+ * -Redirect list pointers past the node\r
+ * -Free memory space for node\r
+ */\r
+/*void delete_node(PROCESS pid){\r
+ \r
+ fosa_ose_list_node_t *tmp_node_ptr = NULL;\r
+ \r
+ if(fosa_ose_processes->NextProcess != NULL){\r
+ tmp_node_ptr = fosa_ose_processes->NextProcess;\r
+ }\r
+ else if(fosa_ose_processes->NextProcess == NULL){\r
+ ramlog_printf("FOSA HANDLERS: ERROR: list empty %x not found\n", pid);\r
+ return;\r
+ }\r
+ \r
+ for(;;){\r
+ \r
+ if(tmp_node_ptr->pid == pid){ \r
+ if(tmp_node_ptr->NextProcess == NULL)\r
+ (tmp_node_ptr->prev_ptr)->NextProcess = NULL;\r
+ else{\r
+ (tmp_node_ptr->prev_ptr)->NextProcess = \r
+ tmp_node_ptr->NextProcess;\r
+ \r
+ (tmp_node_ptr->NextProcess)->prev_ptr = \r
+ tmp_node_ptr->prev_ptr;\r
+ }\r
+ \r
+ heap_free_shared(tmp_node_ptr);*/\r
+ /*ramlog_printf("FOSA HANDLERS: Deleted node, redirected pointers and freed memory for %x \n", pid);*/\r
+ /*break;\r
+ }\r
+ \r
+ if(tmp_node_ptr->NextProcess != NULL)\r
+ tmp_node_ptr = tmp_node_ptr->NextProcess;\r
+ else{*/\r
+ /*ramlog_printf("FOSA HANDLERS: ERROR: node not found for %x \n", pid);*/\r
+ /*break;\r
+ }\r
+ }\r
+}*/\r
+\r
+\r
+\r
+\r
--- /dev/null
+\r
+#osemain.con fragment for frescor_fosa_handlers\r
+OSEMAINCON += $(REFSYSROOT)/modules/frescor_fosa_handlers/osemain.con\r
+\r
+#fosa_handlers library to include in kernel link module\r
+LIBS += $(REFSYSROOT)/modules/frescor_fosa_handlers/$(LIBDIR)/libfrescor_fosa_handlers.a\r
+\r
+#Define needed by krn.con and board.c-files\r
+DEFINE += -DMODULES_FRESCOR_FOSA_HANDLERS\r
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or
+// without modification, are permitted provided that the
+// following conditions are met:
+//
+// * Redistributions of source code must retain the above
+// copyright notice, this list of conditions and the
+// following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the
+// following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+// * Neither the name of FRESCOR nor the names of its
+// contributors may be used to endorse or promote products
+// derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+// -----------------------------------------------------------------------
+
+/* osemain.con fragment for fosa_handlers - start. */
+
+/* SHELL_CMD_ATTRS(fosa_handlers, shellcmd_fosa_handlers, OS_PRI_PROC, 25, 2048) */
+/* SHELL_CMD_ATTRS(time, shellcmd_time, OS_PRI_PROC, 25, 2048) */
+/* #ifdef DURINFO */
+/* PRI_PROC(durinfo, durinfo, 1000, 19, DEFAULT, 0, NULL) */
+/* BG_PROC(background, background, 0, DEFAULT, 0, NULL) */
+/* #endif */
+
+/* osemain.con fragment for fosa_handlers - end. */
+
+/* Added by erth */
+
+PRI_PROC( fosa_ose_block_callback, fosa_ose_block_callback, 1000, 2, DEFAULT, 0, NULL )
+PRI_PROC( fosa_ose_terminate_callback, fosa_ose_terminate_callback, 1000, 2, DEFAULT, 0, NULL )
+
+/* End added by erth */
+
--- /dev/null
+#OSEROOT = /cygdrive/c/OSE/OSE5.2
+OSEROOT = ../../..
+
+TARGETS := lib lm
+include $(OSEROOT)/refsys/environment.mk
+include frescor_fosa_test.mk
+include $(OSEROOT)/refsys/modules/modules.mk
+
+
--- /dev/null
+COMPANY = Enea Embedded Technology AB
+VERSION = 0.1
+LIBDESC = A test of frescor_fosa functions
+
+FOSA_ROOT = $(REFSYSROOT)/modules/frescor_fosa
+FRSH_ROOT = $(REFSYSROOT)/modules/frescor_frsh
+
+#osemain.con fragment for fosa_test
+OSEMAINCON += $(REFSYSROOT)/modules/frescor_fosa_test/src/osemain.con
+
+INCLUDE += -I$(FOSA_ROOT)/include
+INCLUDE += -I$(FOSA_ROOT)/src_ose
+INCLUDE += -I$(FRSH_ROOT)/include
+
+#object files for fosa_test library
+LIBOBJECTS += fosa_test.o
+LIBOBJECTS += test_thread_and_signals.o
+LIBOBJECTS += test_mutexes.o
+LIBOBJECTS += test_condvars.o
+LIBOBJECTS += test_thread_attr.o
+LIBOBJECTS += test_clocks_and_timers.o
+LIBOBJECTS += test_appsched.o
+LIBOBJECTS += test_execution_time_measurement.o
+
+#Path to source code for $(LIBOBJECTS)
+vpath %.c $(REFSYSROOT)/modules/frescor_fosa_test/src
+
+#fosa_test library to include in kernel link module and load modules
+LIBS += $(REFSYSROOT)/modules/frescor_fosa_test/$(LIBDIR)/libfrescor_fosa_test.a
+LMLIBS += $(LIBDIR)/libfosa_test.a
+
+#When built as a load module, hello implements the main() function
+DEFINE += -DAPPLICATION_MAIN
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or
+// without modification, are permitted provided that the
+// following conditions are met:
+//
+// * Redistributions of source code must retain the above
+// copyright notice, this list of conditions and the
+// following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the
+// following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+// * Neither the name of FRESCOR nor the names of its
+// contributors may be used to endorse or promote products
+// derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+// -----------------------------------------------------------------------
+/**
+ * @file fosa_test.c
+ *
+ * @brief This file makes test for the adaption layer fosa.
+ *
+ */
+#include "sys/time.h"
+#include "ose.h"
+#include "efs.h"
+#include "stdio.h"
+#include "string.h"
+#include "ramlog.h"
+
+#include "test_configuration.h"
+#include "fosa.h"
+#include "frsh.h"
+#include "test_condvars.h"
+#include "test_mutexes.h"
+#include "test_thread_and_signals.h"
+#include "test_thread_attr.h"
+#include "test_clocks_and_timers.h"
+#include "test_appsched.h"
+#include "test_execution_time_measurement.h"
+
+
+const char fosa_test_synopsis[] = "frescor_fosa_test";
+const char fosa_test_descr[] = "test of frescor_fosa functions";
+
+
+typedef struct {
+ SIGSELECT signo;
+ char text[1]; /* Variable size. */
+}print_sig_t;
+
+union SIGNAL {
+ SIGSELECT signo;
+ print_sig_t print_sig;
+};
+
+static OS_PROCESS(world)
+{
+ static const SIGSELECT sel_any[] = { 0 };
+ union SIGNAL *sig;
+ int i;
+
+ for(i=0; i<2; i++) {
+ /* Receive first signal in signal queue. */
+ sig = receive(sel_any);
+
+ /* Check signal number. */
+ switch(sig->signo) {
+ /* Act on the PRINT_SIG signal. */
+ case TEST_SIG :
+ {
+ print_sig_t *prsig = (print_sig_t *)sig;
+ char text[100] = "";
+ strcat(text, prsig->text);
+ strcat(text,
+ ", recieved and printed by world process!\n");
+ fputs(text, stdout);
+ break;
+ }
+
+ case PRINT_SIG :
+ {
+ print_sig_t *prsig = (print_sig_t *)sig;
+ fputs(prsig->text, stdout);
+ break;
+ }
+
+ /* Call error() for all unexpected signals. */
+ default :
+ printf("Error i världen.\n ");
+ error2(0xFFFFFFFE, (OSERRCODE)sig);
+ break;
+ }
+ /* Free received signal. */
+ free_buf(&sig);
+ }
+ /* Send signal to world process. */
+ print_sig_t *my_sig;
+ PROCESS moon_pid;
+
+ /* Finn process id för world processen. */
+ hunt("moon", 0, &moon_pid, (union SIGNAL **) NULL);
+
+ /* Text att sända */
+ static const char ping_msg[] = "Pong! From world process";
+
+ /* Allokera minne för signalen och ge den ett signalnummer/typ. */
+ my_sig = (print_sig_t *)alloc(sizeof(print_sig_t) +
+ strlen(ping_msg), TEST_SIG);
+ strcpy(my_sig->text, ping_msg);
+
+ /* Sänd signalen till world */
+ send((union SIGNAL **)&my_sig, moon_pid);
+
+//-----------------------------Test case----------------------------------
+ //Test of function fosa_signal_queue().
+ frsh_signal_t signal_nr = 500;
+ frsh_signal_info_t signal_info;
+ signal_info.value = 8;
+ int ret_code;
+ for (i = 0; i < 3; ++i) {
+ ret_code = fosa_signal_queue(signal_nr+i, signal_info, moon_pid);
+ if (ret_code == 0) {
+ _printf("Sucess by: fosa_signal_queue() \n");
+ } else {
+ printf("Failiure by: fosa_signal_queue(), error code: %d \n",
+ ret_code);
+ }
+ signal_info.value++;
+ }
+ delay(200); //To make the recive timeout (fosa_signal_timedwait).
+ fosa_signal_queue(signal_nr+i, signal_info, moon_pid);
+//-----------------------------End test case------------------------------
+
+ /* Terminate self (open files are NOT flushed and closed). */
+ kill_proc(current_process());
+}
+
+static OS_PROCESS(moon)
+{
+ //delay(10000);
+//-----------------------------Test cases---------------------------------
+ test_fosa_threads_and_signals_from_moon(current_process());
+
+//-----------------------------End test cases-----------------------------
+
+ static const SIGSELECT sel_any[] = { 0 };
+ union SIGNAL *sig;
+ print_sig_t *my_sig;
+ PROCESS world_pid;
+
+ /* Send signal to world process. */
+ static const char ping_msg[] = "\nPing! From moon process";
+
+ /* Allokera minne för signalen och ge den ett signalnummer/typ. */
+ my_sig = (print_sig_t *)alloc(sizeof(print_sig_t) +
+ strlen(ping_msg), TEST_SIG);
+ strcpy(my_sig->text, ping_msg);
+
+ /* Finn process id för world processen. */
+ hunt("world", 0, &world_pid, (union SIGNAL **) NULL);
+
+ /* Sänd signalen till world */
+ send((union SIGNAL **)&my_sig, world_pid);
+
+ int i;
+ for(i=0; i<2; i++) {
+ /* Receive first signal in signal queue. */
+ sig = receive(sel_any);
+
+ /* Check signal number. */
+ switch(sig->signo)
+ {
+ /* Act on the PRINT_SIG signal. */
+ case TEST_SIG :
+ {
+ print_sig_t *prsig = (print_sig_t *)sig;
+ char text[100] = "";
+ strcat(text, prsig->text);
+ strcat(text,
+ ", recieved and printed by moon process!\n\n");
+ fputs(text, stdout);
+ break;
+ }
+
+ case PRINT_SIG :
+ {
+ print_sig_t *prsig = (print_sig_t *)sig;
+ fputs(prsig->text, stdout);
+
+ test_fosa_mutexes();
+ break;
+ }
+
+ /* Call error() for all unexpected signals. */
+ default :
+ printf("Error på månen.\n ");
+ error2(0xFFFFFFFE, (OSERRCODE)sig);
+ break;
+ }
+ free_buf(&sig);
+
+ }
+
+//-----------------------------Test case----------------------------------
+ //Test of function fosa_signal_wait().
+ frsh_signal_t set_of_accepted_signals[] ={499, 500, 502, 503};
+ frsh_signal_t signal_received;
+ frsh_signal_info_t signal_info;
+ int size = 4, ret_code = -1;
+ ret_code = fosa_signal_wait(set_of_accepted_signals, size,
+ &signal_received, &signal_info);
+ if ((signal_info.value == 8) &&
+ (signal_received == 500) &&
+ (ret_code == 0)) {
+ _printf("Sucess by: fosa_signal_wait() \n");
+ } else {
+ printf("Failiure by: fosa_signal_wait() \n");
+ }
+
+ //Test of function fosa_signal_timedwait().
+ //First test to receive directly and then if timeout.
+ //Better timedout test is needed................................
+ struct timespec *time_to_wait;
+ time_to_wait->tv_nsec = 40000; time_to_wait->tv_sec = 0;
+ ret_code = fosa_signal_timedwait(set_of_accepted_signals, size,
+ &signal_received, &signal_info, time_to_wait);
+ if ((signal_info.value == 10) &&
+ (signal_received == 502) &&
+ (ret_code == 0)) {
+ _printf("Sucess by: fosa_signal_timedwait() \n");
+ } else {
+ printf("Failiure by: fosa_signal_timedwait() \n");
+ }
+ time_to_wait->tv_nsec = 1000;
+ time_to_wait->tv_sec = 0;
+ ret_code = fosa_signal_timedwait(set_of_accepted_signals, size,
+ &signal_received, &signal_info, time_to_wait);
+ if (ret_code == FOSA_EAGAIN) {
+ _printf("Sucess by: fosa_signal_timedwait() \n");
+ // (int)ret_code);
+ } else {
+ printf("Failiure by: fosa_signal_timedwait(), ret_code: %d\n",
+ (int)ret_code);
+ }
+//-----------------------------End test case------------------------------
+
+ /* Terminate self (open files are NOT flushed and closed). */
+ kill_proc(current_process());
+}
+
+static OS_PROCESS(mars) {
+ test_fosa_condvars_from_process_one();
+ kill_proc(current_process());
+}
+
+static OS_PROCESS(mars2) {
+ test_fosa_condvars_from_process_two();
+ kill_proc(current_process());
+}
+
+const char hello_synopsis[] = "hello";
+const char hello_descr[] = "print hello world!";
+
+int fosa_test_main(int argc, char *argv[])
+{
+ printf("\n");
+
+//-----------------------------Test cases---------------------------------
+ _printf(
+ " Tis program tests the individual FOSA-functions. \n\n\
+ Testcases begin and the following tests are made. When you\n\
+ see this text the macro for viewing each successed test are turned \n\
+ on, standard are to have this off. If it is off, you will only see \n\
+ the tests that fail. Configure this in the file \n\
+ test_configuration.h and rebuild. \n\n");
+
+ ramlog_printf("FOSA_TEST: started.\n");
+
+ test_fosa_appsched();
+
+ test_fosa_thread_attr();
+
+ test_fosa_clocks_and_timers();
+
+ test_fosa_appsched_system_test();
+
+ test_fosa_execution_time_measurement();
+
+ //Test of function fosa_signal_queue().
+ //First test of limits then functionality.
+ frsh_signal_t frsh_signal[] = {250,30000,260}; //Not valid x2, valid.
+ frsh_signal_info_t info_union;
+ info_union.value=5;
+ int i;
+ for (i = 0; i < 3; ++i) {
+ //Not shore about the accepted process numbers here (error if to
+ //small number in the reciever in send. Might need to be at least
+ //documented.
+ int ret = fosa_signal_queue( frsh_signal[i],
+ info_union, (frsh_thread_id_t) current_process() );
+ if ((ret != FOSA_EINVAL && i==1) ||
+ (ret != FOSA_EINVAL && i==0) ||
+ (ret == FOSA_EINVAL && i>=2)) {
+ printf("Failiure by: fosa_signal_queue() \n");
+
+ } else {
+ _printf("Sucess by: fosa_signal_queue() \n");
+ }
+ }
+
+//-----------------------------End test cases-----------------------------
+
+ PROCESS world_pid;
+ static const SIGSELECT sel_attach[] = { 1, OS_ATTACH_SIG };
+ union SIGNAL *sig;
+ print_sig_t *prsig;
+ static const char msg[] = "world!!\n";
+
+ /* Create world process with same type and priority. */
+ world_pid = create_process(OS_PRI_PROC, /* Process type. */
+ "world", /* Name. */
+ world, /* Entrypoint. */
+ 1000, /* Stacksize. */
+ 3, /* Priority. */
+ 0, 0, NULL, 0, 0); /* Uninteresting. */
+ /* Supervise world process (attach default signal to it). */
+ attach(NULL, world_pid);
+
+ /* Make world process inherit my stdio etc. */
+ efs_clone(world_pid);
+
+
+ /* Allocate, initialize and send signal with text to print. */
+ prsig = (print_sig_t *)alloc(sizeof(print_sig_t) + strlen(msg),
+ PRINT_SIG);
+ strcpy(prsig->text, msg);
+ send((union SIGNAL **)&prsig, world_pid);
+
+ /* Print first part of message. */
+ printf("\nYellow ");
+
+//-----------------------------Test cases---------------------------------
+ //Test of function fosa_ose_execute_action_activate().
+ extern void fosa_ose_execute_action_activate();
+ fosa_ose_execute_action_activate(world_pid);
+
+ //Test of function fosa_ose_execute_action_suspend().
+ extern void fosa_ose_execute_action_suspend();
+ fosa_ose_execute_action_suspend(world_pid);
+
+ //Test of function fosa_thread_set/get_prio().
+ int new_prio = 20000, got_prio=-1;
+ int ret_code = -1;
+ ret_code = fosa_thread_set_prio(world_pid, new_prio);
+ if (ret_code == FOSA_EINVAL) {
+ _printf("Sucess by: fosa_thread_set/get_prio(), ret code. \n");
+ } else {
+ printf("Failiure by: fosa_thread_set/get_prio(), ret code. \n");
+ }
+ new_prio = 5;
+ ret_code = fosa_thread_set_prio(world_pid, new_prio);
+ if (ret_code == 0) {
+ _printf("Sucess by: fosa_thread_set/get_prio(), set \n");
+ } else {
+ printf("Failiure by: fosa_thread_set/get_prio(), set. \n");
+ }
+ ret_code = fosa_thread_get_prio(world_pid, &got_prio);
+ if ((ret_code == 0) && (got_prio == new_prio)) {
+ _printf("Sucess by: fosa_thread_set/get_prio() \n");
+ } else {
+ printf("Failiure by: fosa_thread_set/get_prio(). \n \
+ Prio set to %d, got %d. \n", new_prio, got_prio);
+ }
+
+//-----------------------------End test cases-----------------------------
+ /* Start world process. */
+ start(world_pid);
+
+ /*My own code*/
+ PROCESS moon_pid;
+ static const char moon_msg[] = "moon!\n";
+ moon_pid = create_process(OS_PRI_PROC, /* Process type. */
+ "moon", /* Name. */
+ moon, /* Entrypoint. */
+ 2000, /* Stacksize. */
+ 23, /* Priority. */
+ 0, 0, NULL, 0, 0); /* Uninteresting. */
+
+ attach(NULL, moon_pid);
+ efs_clone(moon_pid);
+ prsig = (print_sig_t *)alloc(sizeof(print_sig_t) + strlen(moon_msg),
+ PRINT_SIG);
+ strcpy(prsig->text, moon_msg);
+ send((union SIGNAL **)&prsig, moon_pid);
+
+//-----------------------------Test cases---------------------------------
+ test_fosa_threads_and_signals(world_pid, moon_pid);
+
+//-----------------------------End test cases-----------------------------
+ printf("Yelloww "); fflush(stdout);
+ start(moon_pid);
+
+ /* Wait for world and moon processes to terminate. */
+ sig = receive(sel_attach);
+ free_buf(&sig);
+ sig = receive(sel_attach);
+ free_buf(&sig);
+
+ //Mars process to test parts of condvars.
+ PROCESS mars_pid;
+ mars_pid = create_process(OS_PRI_PROC, /* Process type. */
+ "mars", /* Name. */
+ mars, /* Entrypoint. */
+ 2000, /* Stacksize. */
+ 23, /* Priority. */
+ 0, 0, NULL, 0, 0); /* Unintresting. */
+
+ attach(NULL, mars_pid);
+ efs_clone(mars_pid);
+
+ //Mars2 process to test parts of condvars.
+ PROCESS mars2_pid;
+ mars2_pid = create_process(OS_PRI_PROC, /* Process type. */
+ "mars2", /* Name. */
+ mars2, /* Entrypoint. */
+ 2000, /* Stacksize. */
+ 23, /* Priority. */
+ 0, 0, NULL, 0, 0); /* Unintresting. */
+
+ attach(NULL, mars2_pid);
+ efs_clone(mars2_pid);
+
+ start(mars_pid);
+ start(mars2_pid);
+
+ // Wait for two times Mars processes to terminate.
+ sig = receive(sel_attach);
+ free_buf(&sig);
+ sig = receive(sel_attach);
+ free_buf(&sig);
+
+ /* Expand LIBWHAT macro in order to reference library what-string. */
+#ifdef LIBWHAT
+ LIBWHAT
+#endif
+ _printf("\nFOSA_TEST: ended.\n");
+ _printf("\n");
+
+ /* Return success from my command. */
+ return 0;
+
+}
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or
+// without modification, are permitted provided that the
+// following conditions are met:
+//
+// * Redistributions of source code must retain the above
+// copyright notice, this list of conditions and the
+// following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the
+// following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+// * Neither the name of FRESCOR nor the names of its
+// contributors may be used to endorse or promote products
+// derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+// -----------------------------------------------------------------------
+/* osemain.con fragment for hello - start. */
+
+#ifdef LOAD_MODULE
+/* Building as (separately linked) load module. */
+
+#ifndef APPLICATION_MAIN
+#error APPLICATION_MAIN not defined!
+#endif
+
+#ifndef ONLY_ONCE
+#define ONLY_ONCE
+int main(int argc, char *argv[])
+{
+ extern int fosa_test_main(int argc, char *argv[]);
+
+ return fosa_test_main(argc, argv);
+}
+#endif
+
+#else
+/* Linking with kernel. */
+
+/* A late start hook that registers our shell commands. */
+SHELL_CMD(fosa_test, fosa_test_main)
+
+#endif
+
+/* osemain.con fragment for hello - end. */
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+#include "stdio.h"\r
+#include "test_configuration.h"\r
+#include "fosa.h"\r
+#include "fosa_ose_implementation_specific.h"\r
+\r
+void test_fosa_appsched_system_test(void){\r
+ //Nothing here.\r
+};\r
+\r
+\r
+void test_fosa_appsched(void) {\r
+ int ret_code = -1;\r
+ \r
+ //Test of function fosa_adsaction_add_reject().\r
+ fosa_ads_actions_t sched_actions;\r
+ fosa_ose_ads_actions_init(&sched_actions);\r
+ ret_code = fosa_adsactions_add_reject(\r
+ &sched_actions, current_process());\r
+ ret_code = fosa_adsactions_add_reject(\r
+ &sched_actions, current_process());\r
+ if ((ret_code == 0) && (sched_actions.LastAction->action == REJECT)) {\r
+ _printf("Sucess by: fosa_adsactions_add_reject() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_adsactions_add_reject() \n");\r
+ }\r
+ \r
+ //Test of function fosa_adsactions_add_activate().\r
+ fosa_ads_urgency_t urgency = 20;\r
+ ret_code = fosa_adsactions_add_activate(\r
+ &sched_actions, current_process(), urgency);\r
+ if ((ret_code == 0) && \r
+ (sched_actions.LastAction->action == ACTIVATE) &&\r
+ (sched_actions.LastAction->urgency == urgency)) {\r
+ _printf("Sucess by: fosa_adsactions_add_activate() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_adsactions_add_activate() \n");\r
+ } \r
+ \r
+ //Test of function fosa_adsaction_add_suspend().\r
+ ret_code = fosa_adsactions_add_suspend(\r
+ &sched_actions, current_process());\r
+ if ((ret_code == 0) && \r
+ (sched_actions.LastAction->action == SUSPEND)) {\r
+ _printf("Sucess by: fosa_adsaction_add_suspend() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_adsaction_add_suspend() \n");\r
+ } \r
+ \r
+ //Test of function fosa_adsactions_add_timeout().\r
+ fosa_clock_id_t clock_id = 5;\r
+ struct timespec at_time = {28, 30};\r
+ ret_code = fosa_adsactions_add_timeout(\r
+ &sched_actions, clock_id, &at_time);\r
+ if ((ret_code == 0) && \r
+ (sched_actions.LastAction->action == TIMEOUT)) {\r
+ _printf("Sucess by: fosa_adsactions_add_timeout() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_adsactions_add_timeout() \n");\r
+ }\r
+ \r
+ //Test of function fosa_adsactions_add_thread_notification().\r
+ ret_code = fosa_adsactions_add_thread_notification(\r
+ &sched_actions, current_process(), clock_id, &at_time);\r
+ if ((ret_code == 0) && \r
+ (sched_actions.LastAction->action == THREAD_NOTIFICATION)) {\r
+ _printf("Sucess by: fosa_adsactions_add_thread_notification() \\r
+ \n");\r
+ } else {\r
+ printf("Failiure by: fosa_adsactions_add_thread_notification() \\r
+ \n");\r
+ }\r
+ \r
+ //Test of function fosa_ads_scheduler_create().\r
+ fosa_ads_scheduler_ops_t scheduler_ops;\r
+ fosa_ose_scheduler_ops_init(&scheduler_ops); \r
+ size_t scheduler_data_size = 10;\r
+ char * init_args = NULL;//"Initial args to scheduler"; \r
+ size_t init_args_size = 0;//sizeof(init_args);\r
+ ret_code = fosa_ads_scheduler_create(&scheduler_ops, \r
+ scheduler_data_size,\r
+ (void *) init_args,\r
+ init_args_size);\r
+ if (ret_code == 0) {\r
+ _printf("Sucess by: fosa_ads_scheduler_create() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_ads_scheduler_create() \n");\r
+ }\r
+ \r
+ //Test of function receive an event in the scheduler.\r
+ union SIGNAL *sig;\r
+ sig = (union SIGNAL *)alloc(sizeof(union SIGNAL),\r
+ FOSA_OSE_TEST_EVENT_SIGNAL);\r
+ PROCESS scheduler_pid;\r
+ hunt("fosa_scheduler_process", 0, \r
+ &scheduler_pid, (union SIGNAL **) NULL);\r
+ if (scheduler_pid != 0) {\r
+ send(&sig, scheduler_pid);\r
+ //Result printed from the scheduler.\r
+ } else {\r
+ printf("Failiure by: receive an event in the scheduler, "\r
+ "fosa_scheduler_process not found.\n");\r
+ }\r
+}\r
+\r
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+#ifndef TEST_APPSCHED_H_\r
+#define TEST_APPSCHED_H_\r
+\r
+void test_fosa_appsched_system_test(void);\r
+\r
+void test_fosa_appsched(void);\r
+\r
+#endif /*TEST_APPSCHED_H_*/\r
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+#include "time.h"\r
+#include "stdio.h"\r
+#include "ose.h"\r
+#include "fosa.h"\r
+#include "test_configuration.h"\r
+\r
+#define FOSA_OSE_TEST_SIGNAL 300\r
+\r
+\r
+void test_fosa_clocks_and_timers(void) {\r
+ int ret_code = -1;\r
+ \r
+ //Test of function fosa_thread_get_cputime_clock().\r
+ PROCESS pid = current_process();\r
+ fosa_clock_id_t clock_id;\r
+ int ret_code2 = fosa_thread_get_cputime_clock(0, &clock_id);\r
+ ret_code = fosa_thread_get_cputime_clock(pid, &clock_id);\r
+ if ((ret_code == 0) && ( pid == clock_id) && (ret_code2 == EINVAL)){\r
+ _printf("Sucess by: fosa_thread_get_cputime_clock() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_thread_get_cputime_clock() \n");\r
+ } \r
+ \r
+ //Test of function fosa_clock_get_time().\r
+ struct timespec current_time;\r
+ ret_code = fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time);\r
+ if ((ret_code == 0) && \r
+ ((current_time.tv_sec > 0) || (current_time.tv_nsec > 0))) {\r
+ _printf("Sucess by: fosa_clock_get_time() \n");\r
+ //printf("Sucess by: fosa_clock_get_time(), time(s:ns): %010ld:%010ld \n",\r
+ // current_time.tv_sec,current_time.tv_nsec);\r
+ } else {\r
+ printf("Failiure by: fosa_clock_get_time(), time(s:ns): %010ld:%010ld \n",\r
+ current_time.tv_sec,current_time.tv_nsec);\r
+ }\r
+ \r
+ //Test of function fosa_timer_create().\r
+ clock_id = 0;\r
+ frsh_signal_info_t info;\r
+ fosa_timer_id_t timerid;\r
+ frsh_signal_t signal = FOSA_OSE_TEST_SIGNAL;\r
+ info.value = 50;\r
+ ret_code = fosa_timer_create(clock_id, signal, info, &timerid);\r
+ if (ret_code == 0) {\r
+ _printf("Sucess by: fosa_timer_create() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_timer_create() \n");\r
+ }\r
+ \r
+ //Test of function fosa_timer_arm().\r
+ bool abstime = false;\r
+ frsh_signal_t set[] = {FOSA_OSE_TEST_SIGNAL};\r
+ frsh_signal_t signal_received;\r
+ frsh_signal_info_t info_received;\r
+ struct timespec value = {0, 5000000};\r
+ \r
+ ret_code = fosa_timer_arm(timerid, abstime, &value);\r
+ fosa_signal_timedwait(set, 1, &signal_received, \r
+ &info_received, &value); \r
+ if ((ret_code == 0) &&\r
+ (signal_received == FOSA_OSE_TEST_SIGNAL) &&\r
+ (info_received.value == 50)) \r
+ {\r
+ _printf("Sucess by: fosa_timer_arm() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_timer_arm() \n");\r
+ }\r
+ \r
+ //Test of function fosa_timer_disarm().\r
+ fosa_timer_arm(timerid, abstime, &value);\r
+ ret_code = fosa_timer_disarm(timerid);\r
+ if (ret_code == 0) {\r
+ _printf("Sucess by: fosa_timer_disarm() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_timer_disarm() \n");\r
+ } \r
+\r
+ //Test of function fosa_timer_delete().\r
+ fosa_timer_arm(timerid, abstime, &value);\r
+ ret_code = fosa_timer_delete(timerid);\r
+ if (ret_code == 0) {\r
+ _printf("Sucess by: fosa_timer_delete() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_timer_delete() \n");\r
+ } \r
+}\r
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+#ifndef TEST_CLOCKS_AND_TIMERS_H_\r
+#define TEST_CLOCKS_AND_TIMERS_H_\r
+\r
+void test_fosa_clocks_and_timers(void);\r
+\r
+#endif /*TEST_CLOCKS_AND_TIMERS_H_*/\r
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+#include "frsh.h"\r
+#include "fosa.h"\r
+#include "stdio.h"\r
+#include "fosa_ose_signals.sig"\r
+#include "test_configuration.h"\r
+\r
+\r
+void test_fosa_condvars_from_process_one(void) {\r
+ int ret_code;\r
+ \r
+ //Test of function fosa_cond_init().\r
+ fosa_cond_t cv;\r
+ cv.pid_queue_length = -1;\r
+ ret_code = 0;//fosa_cond_init(&cv); \r
+ if ((ret_code == 0) && (cv.pid_queue_length == -1)) {\r
+ _printf("Sucess by: fosa_cond_init() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_cond_init() \n");\r
+ } \r
+\r
+ //Test of function fosa_cond_wait().\r
+ /*\r
+ * author erth\r
+ *\r
+ * Hunt for mars2 pid and send signal to it with a condvar in. Call \r
+ * condvar_wait from this process and let the other one make \r
+ * broadcast. \r
+ */\r
+ PROCESS mars2_pid = 0;\r
+ while (mars2_pid == 0) {\r
+ hunt("mars2",0,&mars2_pid,(union SIGNAL **) NULL);\r
+ }\r
+ \r
+ frsh_signal_info_t info;\r
+ info.area = &cv;\r
+ fosa_signal_queue( (frsh_signal_t) 300,\r
+ info, (frsh_thread_id_t) mars2_pid);\r
+ \r
+ frsh_mutex_t m;\r
+ fosa_mutex_init(&m, 11);\r
+ fosa_mutex_lock(&m);\r
+ \r
+ ret_code = -1;\r
+ ret_code = fosa_cond_wait(&cv, &m);\r
+ fosa_mutex_unlock(&m);\r
+ if (ret_code == 0) {\r
+ _printf("Sucess by: fosa_cond_wait() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_cond_wait() \n");\r
+ }\r
+ \r
+ //Test of function fosa_cond_signal().\r
+ ret_code = -1;\r
+ //delay(10);\r
+ ret_code = fosa_cond_signal(&cv);\r
+ if (ret_code == 0) {\r
+ _printf("Sucess by: fosa_cond_signal() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_cond_signal() \n");\r
+ } \r
+ \r
+}\r
+\r
+void test_fosa_condvars_from_process_two(void) {\r
+ int ret_code = -1;\r
+ //printf("--In Mars2 pid: 0x00%x", current_process()); fflush(stdout);\r
+ \r
+ //Receive signal with condition variable pointer in.\r
+ frsh_signal_t sig_set[] = { 300 };\r
+ \r
+ frsh_signal_info_t info;\r
+ frsh_signal_t signal_received;\r
+ fosa_signal_wait(sig_set, 1, &signal_received, &info);\r
+ \r
+ fosa_cond_t *cv;\r
+ cv = info.area;\r
+ \r
+ //Test of function fosa_cond_broadcast().\r
+ ret_code = fosa_cond_broadcast(cv);\r
+ if ((ret_code == 0) && (signal_received == 300)) {\r
+ _printf("Sucess by: fosa_cond_broadcast() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_cond_broadcast() \n");\r
+ } \r
+ \r
+ //Test of function fosa_cond_timedwait().\r
+ ret_code = -1;\r
+ struct timespec time;\r
+ time.tv_sec = 0; time.tv_nsec = 30000;\r
+ \r
+ frsh_mutex_t m;\r
+ fosa_mutex_init(&m, 11);\r
+ fosa_mutex_lock(&m);\r
+ ret_code = fosa_cond_timedwait(cv, &m, time);\r
+ \r
+ if (ret_code == 0) {\r
+ _printf("Sucess by: fosa_cond_timedwait() \n");\r
+ } else if(ret_code == ETIMEDOUT) {\r
+ printf("Failiure by: fosa_cond_timedwait(), timeout \n");\r
+ } else {\r
+ printf("Failiure by: fosa_cond_timedwait() \n");\r
+ }\r
+ \r
+ //Test of function fosa_cond_destroy().\r
+ ret_code = -1;\r
+ ret_code = fosa_cond_destroy(cv);\r
+ if (ret_code == 0) {\r
+ _printf("Sucess by: fosa_cond_destroy() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_cond_destroy() \n");\r
+ } \r
+\r
+}\r
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+#ifndef TEST_CONDVARS_H_\r
+#define TEST_CONDVARS_H_\r
+\r
+void test_fosa_condvars_from_process_one(void);\r
+\r
+void test_fosa_condvars_from_process_two(void);\r
+\r
+#endif /*TEST_CONDVARS_H_*/\r
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+#ifndef TEST_CONFIGURATION_H_\r
+#define TEST_CONFIGURATION_H_\r
+\r
+#include "ramlog.h"\r
+\r
+#ifndef OSE\r
+#define OSE\r
+#endif\r
+\r
+#define PRINT_SIG 1000\r
+#define TEST_SIG 1001\r
+\r
+/*\r
+ * author erth\r
+ *\r
+ * Macro to choose if all testcases should be printed when they success. \r
+ * The default are to not print them. There are no way provided to turn \r
+ * off the printing for a failiure. Choose one of the following defines\r
+ * for _printf(text). \r
+ */\r
+//#define _printf(text); //Use this to hide tests that succeeds.\r
+//#define _printf(text) printf(text); //Use this to see all tests.\r
+#define _printf(text) ramlog_printf(text); //This does printf to ramlog.\r
+\r
+#endif /*TEST_CONFIGURATION_H_*/\r
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+#include "ose.h"\r
+#include "frsh.h"\r
+#include "fosa.h"\r
+#include "stdio.h"\r
+#include "fosa_ose_types.h"\r
+#include "test_configuration.h"\r
+#include "fosa_ose_implementation_specific.h"\r
+\r
+extern void * test_function(char * text);\r
+extern fosa_ose_process_info_t* fosa_ose_processes;\r
+\r
+void test_fosa_execution_time_measurement()\r
+{\r
+ //Create thread attr to set priority to higher than this thread.\r
+ int ret_code = 0;\r
+ frsh_thread_attr_t attr;\r
+ ret_code += frsh_thread_attr_init(&attr);\r
+ ret_code += fosa_thread_attr_set_prio(&attr, 21);\r
+ \r
+ //Create new process with fosa_thread_create().\r
+ frsh_thread_id_t tid, tid2, tid3;\r
+ frsh_thread_code_t code = (void *) &test_function;\r
+ char arg[] = "Success by: Process to be timed, swaped in.";\r
+ OSTICK t1, t2;\r
+ OSTICK m1;\r
+ t1 = get_systime(&m1);\r
+ fosa_thread_create(&tid, &attr, code, &arg);\r
+ fosa_thread_create(&tid2, &attr, code, &arg);\r
+ fosa_thread_create(&tid3, &attr, code, &arg);\r
+ t2 = get_systime(&m1);\r
+ \r
+ //Test of function fosa execution time measurement().\r
+ fosa_ose_process_info_t* node = fosa_ose_processes;\r
+ while(node->pid != tid3) { //Find the right node.\r
+ //printf("Node pid: %x,searching for pid: %x \n", node->pid, tid);\r
+ node = node->NextProcess;\r
+ if (node == NULL) break;\r
+ }\r
+ signed long micros = node->nr_of_micros;\r
+ signed long ticks = node->nr_of_ticks;\r
+ if (((ticks > 0) && (ticks <= (t2-t1))) || \r
+ ((micros > 0) && (micros <= 2*system_tick()))) {\r
+ _printf("Sucess by: fosa execution time measurement()\n");\r
+ //printf("Sucess by: fosa execution time measurement()"\r
+ // ", ticks: %d, micros: %d.\n", ticks, micros);\r
+ } else {\r
+ printf("Failiure by: fosa execution time measurement(), ticks: %d"\r
+ ", micros: %d.\n", ticks, micros);\r
+ }\r
+ \r
+ frsh_thread_attr_destroy(&attr);\r
+ fosa_ose_process_list_node_remove(tid); \r
+ fosa_ose_process_list_node_remove(tid3); \r
+ fosa_ose_process_list_node_remove(tid2); \r
+}\r
+\r
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+#ifndef TEST_EXECUTION_TIME_MEASUREMENT_H_\r
+#define TEST_EXECUTION_TIME_MEASUREMENT_H_\r
+\r
+void test_fosa_execution_time_measurement();\r
+\r
+#endif /*TEST_EXECUTION_TIME_MEASUREMENT_H_*/\r
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+#include "frsh.h"\r
+#include "fosa.h"\r
+#include "ose.h"\r
+#include "stdio.h"\r
+#include "test_configuration.h"\r
+\r
+\r
+void test_fosa_mutexes(void) {\r
+ \r
+ //Test of function fosa_mutex_init().\r
+ frsh_mutex_t m1;\r
+ frsh_mutex_t m2;\r
+ int ret_code = fosa_mutex_init(&m1, 10);\r
+ int ret_code2 = fosa_mutex_init(&m2, 12);\r
+ int ret_code3 = 0;\r
+ \r
+ if ((ret_code == 0) && (ret_code2 == 0)) {\r
+ _printf("Sucess by: fosa_mutex_init() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_mutex_init() \n");\r
+ } \r
+ \r
+ \r
+ //Test of function fosa_mutex_set_prioceiling().\r
+ int old_prio = 0, new_prio = 5;\r
+ ret_code = fosa_mutex_set_prioceiling(&m1, new_prio, &old_prio);\r
+ ret_code += fosa_mutex_set_prioceiling(&m2, new_prio+3, &old_prio);\r
+ \r
+ if ((ret_code == 0) && (old_prio == 12)) {\r
+ _printf("Sucess by: fosa_mutex_set_prioceiling() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_mutex_set_prioceiling() \n");\r
+ } \r
+ \r
+ \r
+ //Test of function fosa_mutex_get_proiceiling().\r
+ int prio[] = {0,0};\r
+ ret_code = fosa_mutex_get_prioceiling(&m1, &prio[0]);\r
+ ret_code = fosa_mutex_get_prioceiling(&m2, &prio[1]);\r
+ \r
+ if ((ret_code == 0) && (prio[0] == new_prio) \r
+ && (prio[1] == (new_prio+3) )) {\r
+ _printf("Sucess by: fosa_mutex_get_proiceiling() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_mutex_get_proiceiling() \n \\r
+ prio1 %d, prio2 %d\n", prio[0], prio[1] );\r
+ } \r
+ \r
+ \r
+ //Test of function fosa_mutex_lock().\r
+ //First that error is given when trying to lock from a thread with a\r
+ //higher priority than the ceiling, then change the ceiling and check\r
+ //if sucess.\r
+ OSPRIORITY old_pri = get_pri(current_process());\r
+ ret_code = fosa_mutex_lock(&m1);\r
+ if (ret_code == FOSA_EINVAL) {\r
+ _printf("Sucess by: fosa_mutex_lock() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_mutex_lock() \n");\r
+ } \r
+ new_prio = 20; \r
+ ret_code = fosa_mutex_set_prioceiling(&m1, new_prio, &old_prio);\r
+ ret_code2 = fosa_mutex_lock(&m1);\r
+ OSPRIORITY changed_pri = get_pri(current_process());\r
+ if ((ret_code2 == 0) && (ret_code == 0)) {\r
+ _printf("Sucess by: fosa_mutex_lock() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_mutex_lock() \n");\r
+ } \r
+ \r
+ \r
+ //Test of function fosa_mutex_unlock().\r
+ ret_code = fosa_mutex_unlock(&m1);\r
+ if (ret_code == 0) {\r
+ _printf("Sucess by: fosa_mutex_unlock() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_mutex_unlock() \n");\r
+ } \r
+ OSPRIORITY resulting_pri = get_pri(current_process());\r
+ \r
+ \r
+ //Test priority change when locking mutex.\r
+ if ((old_pri == resulting_pri) && (changed_pri < old_pri)\r
+ && (changed_pri == 11)) {\r
+ _printf("Sucess by: priority change when locking mutex \n");\r
+ } else {\r
+ printf("Failiure by: priority change when locking mutex, \\r
+ old_pri %d, changed_pri %d, resulting_pri %d \n",\r
+ old_pri, changed_pri, resulting_pri);\r
+ } \r
+ \r
+ \r
+ //Test of function fosa_mutex_trylock().\r
+ //Additional test could be to test to lock when locked by other \r
+ //process, this is not tested by now!\r
+ fosa_mutex_lock( &m2);\r
+ ret_code = fosa_mutex_trylock(&m1); \r
+ fosa_mutex_unlock( &m2);\r
+ ret_code2 = fosa_mutex_trylock(&m2);\r
+ ret_code3 = fosa_mutex_unlock( &m2);\r
+ fosa_mutex_unlock( &m1);\r
+ if ((ret_code == 0) && (ret_code2 == 0)\r
+ && (ret_code3 == 0)) {\r
+ _printf("Sucess by: fosa_mutex_trylock() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_mutex_trylock() ret_code: %d, \\r
+ ret_code2: %d, ret_code3: %d \n", ret_code,ret_code2,ret_code3);\r
+ } \r
+}\r
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+#ifndef TEST_MUTEXES_H_\r
+#define TEST_MUTEXES_H_\r
+\r
+void test_fosa_mutexes(void);\r
+\r
+#endif /*TEST_MUTEXES_H_*/\r
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+#include "frsh.h"\r
+#include "fosa.h"\r
+#include "ose.h"\r
+#include "stdio.h"\r
+#include "test_configuration.h"\r
+#include "heapapi.h"\r
+#include "string.h"\r
+#include "fosa_ose_implementation_specific.h"\r
+\r
+void * test_function(char * text) {\r
+ printf(text);\r
+ return text;\r
+}\r
+\r
+int global_ptr[] = {20, 4000, 555};\r
+\r
+void test_fosa_threads_and_signals_from_moon(PROCESS moon_pid) {\r
+ //In new process context. Called also from bg process.\r
+ int* test_pointer;\r
+ \r
+ int ret_code = fosa_thread_get_specific_data(\r
+ 0, moon_pid, (void **) &test_pointer );\r
+ \r
+ if ((ret_code == 0) && (*test_pointer == global_ptr[2])) {\r
+ _printf("Sucess by: fosa_thread_get_specific_data() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_thread_get_specific_data(), " \\r
+ "from other process than the setting one. \n "\r
+ "when memory not allocated with heap_alloc_shared() "\r
+ "or global, ret_code %d, value: %d\n", \r
+ ret_code, *test_pointer);\r
+ }\r
+ \r
+ //Test of function fosa_thread_get_specific_data().\r
+ ret_code = fosa_thread_get_specific_data(\r
+ 1, moon_pid, (void **) &test_pointer );\r
+ int *a = (int*)test_pointer;\r
+ if ((ret_code == 0) &&\r
+ (*a == 20)) {\r
+ _printf("Sucess by: fosa_thread_get_specific_data() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_thread_get_specific_data() \n "\r
+ " from other process, uses heap_alloc_shared.\n");\r
+ } \r
+ \r
+ \r
+}\r
+\r
+void test_fosa_threads_and_signals(PROCESS world_pid, PROCESS moon_pid) {\r
+ \r
+ //Test of function fosa_get_priority_min/max().\r
+ int min = 0, max = 0;\r
+ min = fosa_get_priority_min();\r
+ max = fosa_get_priority_max();\r
+ if ((min == FRSH_LOWEST_THREAD_PRIORITY) &&\r
+ (max == FRSH_HIGHEST_THREAD_PRIORITY)) {\r
+ _printf("Sucess by: fosa_get_priority_min/max() \n"); \r
+ } else {\r
+ printf("Failiure by: fosa_get_priority_min/max() \n"); \r
+ } \r
+ \r
+ //Test of function fosa_thread_self(). \r
+ PROCESS hello_pid = current_process();\r
+ frsh_thread_id_t hello_pid_from_fosa;\r
+ hello_pid_from_fosa = fosa_thread_self();\r
+ if (hello_pid == hello_pid_from_fosa) {\r
+ _printf("Sucess by: fosa_thread_self() \n"); \r
+ } else {\r
+ printf("Failiure by: fosa_thread_self() \n"); \r
+ } \r
+\r
+\r
+ //Test of function fosa_thread_set/get_specific_data().\r
+ int ret_code = -1;\r
+ int test_number[] = {20, 4000, 555};\r
+ fosa_thread_set_specific_data(2, moon_pid, &test_number[0]);\r
+ ret_code = fosa_thread_set_specific_data(4, world_pid, &test_number[1]);\r
+ fosa_thread_set_specific_data(0, moon_pid, &global_ptr[2]);\r
+ if (ret_code == FOSA_EINVAL) {\r
+ _printf("Sucess by: fosa_thread_set_specific_data() \n"); \r
+ } else {\r
+ printf("Failiure by: fosa_thread_set_specific_data() \n");\r
+ }\r
+ \r
+ int *test_pointer;\r
+ ret_code = fosa_thread_get_specific_data(\r
+ 2, moon_pid, (void *) &test_pointer ); \r
+ if ((ret_code == 0) && (*test_pointer == test_number[0])) {\r
+ _printf("Sucess by: fosa_thread_get_specific_data() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_thread_get_specific_data() \n");\r
+ }\r
+ \r
+ ret_code = fosa_thread_get_specific_data(\r
+ 0, moon_pid, (void*) &test_pointer ); \r
+ if ((ret_code == 0) && (*test_pointer == test_number[2])) {\r
+ _printf("Sucess by: fosa_thread_get_specific_data() \n"); \r
+ } else {\r
+ printf("Failiure by: fosa_thread_get_specific_data() \n");\r
+ }\r
+ \r
+ //Test of function fosa_key_create().\r
+ ret_code = 0;\r
+ int key[] = {-1, -1, -1, -1};\r
+ ret_code += fosa_key_create(&key[0]);\r
+ ret_code += fosa_key_create(&key[1]);\r
+ ret_code += fosa_key_create(&key[2]);\r
+ if ((ret_code == 0) &&\r
+ (key[0] == 0) &&\r
+ (key[1] == 1) &&\r
+ (key[2] == 2)) {\r
+ _printf("Sucess by: fosa_key_create() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_key_create() keys: %d %d %d\n",\r
+ key[0], key[1], key[2]);\r
+ } \r
+\r
+ //Test of function fosa_key_destroy().\r
+ ret_code = fosa_key_destroy(key[1]);\r
+ key[1] = -1;\r
+ ret_code += fosa_key_create(&key[1]);\r
+ ret_code += fosa_key_create(&key[3]);\r
+ if ((ret_code == 0) &&\r
+ (key[1] == 1) &&\r
+ (key[3] == 3)) {\r
+ _printf("Sucess by: fosa_key_destroy() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_key_destroy() keys: %d %d\n", \r
+ key[1], key[3]);\r
+ }\r
+ fosa_key_destroy(key[0]);\r
+ fosa_key_destroy(key[1]);\r
+ fosa_key_destroy(key[2]);\r
+ fosa_key_destroy(key[3]);\r
+ \r
+ //Test of function fosa_thread_set/get_specific_data() \r
+ //from other process, uses heap_alloc_shared. Part of this test here,\r
+ //other part in other function.\r
+ int * test_ptr;\r
+ test_ptr = (int*) heap_alloc_shared(5, __FILE__, __LINE__);\r
+ memcpy(test_ptr, test_number, sizeof(test_number));\r
+ fosa_thread_set_specific_data(1, moon_pid, test_ptr);\r
+ \r
+ //Test of function fosa_thread_create().\r
+ ret_code = -1;\r
+ frsh_thread_id_t tid;\r
+ frsh_thread_code_t code = (void *) &test_function;\r
+ char arg[] = "Sucess by: part of fosa_thread_create(), ptr passing\n";\r
+ ret_code = fosa_thread_create(&tid, NULL, code, &arg);\r
+ if (ret_code == 0) {\r
+ _printf("Sucess by: fosa_thread_create() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_thread_create() \n");\r
+ }\r
+ fosa_ose_process_list_node_remove(tid);\r
+ \r
+ //Test of function fosa_thread_equal().\r
+ bool test[] = {false, false, false, false};\r
+ test[0] = fosa_thread_equal(moon_pid, world_pid);\r
+ test[1] = fosa_thread_equal(world_pid, moon_pid);\r
+ test[2] = fosa_thread_equal(moon_pid, moon_pid);\r
+ test[3] = fosa_thread_equal(world_pid, world_pid);\r
+ if (!test[0] && \r
+ !test[1] && \r
+ test[2] && \r
+ test[3] ) {\r
+ _printf("Sucess by: fosa_thread_equal() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_thread_equal() \n");\r
+ }\r
+}\r
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+#ifndef TEST_THREAD_AND_SIGNALS_H_\r
+#define TEST_THREAD_AND_SIGNALS_H_\r
+\r
+void * test_function(char * text);\r
+\r
+void test_fosa_threads_and_signals(PROCESS world_pid, PROCESS moon_pid);\r
+\r
+void test_fosa_threads_and_signals_from_moon(PROCESS moon_pid);\r
+\r
+#endif /*TEST_THREAD_AND_SIGNALS_H_*/\r
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+#include "frsh.h"\r
+#include "frsh_fosa.c"\r
+#include "fosa.h"\r
+#include "fosa_app_def_sched.h"\r
+\r
+#include "fosa_ose_implementation_specific.h"\r
+\r
+#include "stdio.h"\r
+#include "string.h"\r
+#include "malloc.h"\r
+#include "test_configuration.h"\r
+#include "test_thread_and_signals.h"\r
+\r
+void test_fosa_thread_attr(void) {\r
+ frsh_thread_attr_t attr;\r
+ int ret_code[] = {-1,-1};\r
+ \r
+ //Test of function frsh_thread_attr_init().\r
+ ret_code[0] = frsh_thread_attr_init(&attr);\r
+ if (ret_code[0] == 0) {\r
+ _printf("Sucess by: frsh_thread_attr_init() \n");\r
+ } else {\r
+ printf("Failiure by: frsh_thread_attr_init() \n");\r
+ } \r
+ \r
+ //Test of function fosa_thread_attr_set/get_prio(). \r
+ //Should test priorities outside the limits, too give error.\r
+ int initial_prio = 8;\r
+ size_t retreived_prio;\r
+ ret_code[0] = fosa_thread_attr_set_prio(&attr, initial_prio);\r
+ ret_code[1] = fosa_thread_attr_get_prio(&attr, &retreived_prio);\r
+ if ((retreived_prio == initial_prio) && (ret_code[0] == 0) \r
+ && (ret_code[1] == 0 )) {\r
+ _printf("Sucess by: fosa_thread_attr_set/get_prio() \n"); \r
+ } else {\r
+ printf("Failiure by: fosa_thread_attr_set/get_prio() \n"); \r
+ } \r
+ \r
+ //Test of function frsh_thread_attr_set/get_stacksize().\r
+ size_t stacksize = 1002; //Number of bytes.\r
+ size_t received_size = 0;\r
+ ret_code[0] = frsh_thread_attr_set_stacksize(&attr, stacksize);\r
+ ret_code[1] = frsh_thread_attr_get_stacksize(&attr, &received_size);\r
+ if ((ret_code[0] == 0) &&\r
+ (ret_code[1] == 0) &&\r
+ (received_size == stacksize)) {\r
+ _printf("Sucess by: frsh_thread_attr_set/get_stacksize() \n");\r
+ } else {\r
+ printf("Failiure by: frsh_thread_attr_set/get_stacksize() \n");\r
+ } \r
+ \r
+ //Test of function fosa_thread_attr_set/get_appscheduled().\r
+ ret_code[0] = -1, ret_code[1] = -1;\r
+ ret_code[0] = fosa_thread_attr_set_appscheduled(&attr, true);\r
+ bool b = false;\r
+ ret_code[1] = fosa_thread_attr_get_appscheduled(&attr, &b);\r
+ \r
+ if ((ret_code[0] == 0) && (b) && (ret_code[1] == 0)) {\r
+ _printf("Sucess by: fosa_thread_attr_set/get_appscheduled() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_thread_attr_set/get_appscheduled() \n");\r
+ }\r
+ \r
+ //Test of function fosa_thread_attr_set/get_appsched_params().\r
+ ret_code[0] = -1, ret_code[1] = -1;\r
+ char param[] = "Swedish: Karl är en långsam häst!\n";\r
+ ret_code[0] = fosa_thread_attr_set_appsched_params(&attr,\r
+ (void *)param, sizeof(param));\r
+ char *returned_param;\r
+ size_t returned_size;\r
+ \r
+ returned_param = (void *) malloc(sizeof(param)); \r
+ ret_code[1] = fosa_thread_attr_get_appsched_params(&attr,\r
+ returned_param, &returned_size);\r
+ if ((ret_code[0] == 0) && (ret_code[1] == 0) &&\r
+ (sizeof(param) == returned_size) &&\r
+ (memcmp( param,returned_param, sizeof(param)) == 0)) {\r
+ _printf("Sucess by: fosa_thread_attr_set/get_appsched_params()\n");\r
+ } else {\r
+ printf("Failiure by: fosa_thread_attr_set/get_appsched_params() \\r
+ \n");\r
+ }\r
+ free(returned_param);\r
+ \r
+ //Test of function frsh_thread_attr_destroy().\r
+ //Possible to check if memory are freed, not done here now.\r
+ ret_code[0] = frsh_thread_attr_init(&attr);\r
+ //char param[] = "Swedish: Karl är en långsam häst!\n";\r
+ ret_code[0] = fosa_thread_attr_set_appsched_params(&attr,\r
+ (void *)param, sizeof(param));\r
+ ret_code[1] = frsh_thread_attr_destroy(&attr);\r
+ if ((ret_code[0] == 0) &&\r
+ (ret_code[1] == 0)) {\r
+ _printf("Sucess by: frsh_thread_attr_destroy() \n");\r
+ } else {\r
+ printf("Failiure by: frsh_thread_attr_destroy() \n");\r
+ } \r
+\r
+ ret_code[0] = -1;\r
+ frsh_thread_id_t tid;\r
+ frsh_thread_code_t code = (void *) &test_function;\r
+ char arg[] = "Sucess by: part of fosa_thread_create(), ptr passing\n";\r
+ ret_code[0] = fosa_thread_create(&tid, NULL, code, &arg);\r
+ \r
+ \r
+ //Test of function fosa_ads_get_appscheduled().\r
+ bool set_bool = true;\r
+ bool got_bool = false;\r
+ ret_code[0] = fosa_ads_set_appscheduled(tid, set_bool);\r
+ ret_code[1] = fosa_ads_get_appscheduled(tid, &got_bool);\r
+ if ((ret_code[0] == 0) &&\r
+ (ret_code[1] == 0) &&\r
+ (got_bool == set_bool)) {\r
+ _printf("Sucess by: fosa_ads_set/get_appscheduled() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_ads_set/get_appscheduled() \n");\r
+ } \r
+ \r
+ //Test of function fosa_ads_get_appschedparam() before set.\r
+ void *empty = NULL;\r
+ size_t param_size = 0;\r
+ ret_code[0] = fosa_ads_get_appsched_params(tid, empty, ¶m_size);\r
+ if ((ret_code[0] == 0) &&\r
+ (empty == NULL) &&\r
+ (param_size == 0)) {\r
+ _printf("Sucess by: fosa_ads_get_appschedparam() before set \n");\r
+ } else {\r
+ printf("Failiure by: fosa_ads_get_appschedparam() before set \n");\r
+ } \r
+ \r
+ //Test of function fosa_ads_get/set_appsched_params().\r
+ char str[] = "Kalle kan springa\n";\r
+ ret_code[0] = fosa_ads_set_appsched_params(tid, str, sizeof(str));\r
+ ret_code[1] = fosa_ads_get_appsched_params(tid, param, ¶m_size);\r
+ if ((ret_code[0] == 0) &&\r
+ (ret_code[1] == 0) &&\r
+ (strncmp(param, str, param_size) == 0)) {\r
+ _printf("Sucess by: fosa_ads_get/set_appsched_params() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_ads_get/set_appsched_params() \n");\r
+ }\r
+ \r
+ //Test of function fosa_ose_process_list_node_remove().\r
+ ret_code[0] = fosa_ose_process_list_node_remove(tid);\r
+ fosa_ose_process_info_t* node = fosa_ose_process_get_node(tid);\r
+ if ((ret_code[0] == 0) &&\r
+ (node == NULL)) {\r
+ _printf("Sucess by: fosa_ose_process_list_node_remove() \n");\r
+ } else {\r
+ printf("Failiure by: fosa_ose_process_list_node_remove() \n");\r
+ }\r
+ \r
+}\r
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------\r
+#ifndef TEST_THREAD_ATTR_H_\r
+#define TEST_THREAD_ATTR_H_\r
+\r
+void test_fosa_thread_attr(void);\r
+\r
+#endif /*TEST_THREAD_ATTR_H_*/\r
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or
+// without modification, are permitted provided that the
+// following conditions are met:
+//
+// * Redistributions of source code must retain the above
+// copyright notice, this list of conditions and the
+// following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the
+// following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+// * Neither the name of FRESCOR nor the names of its
+// contributors may be used to endorse or promote products
+// derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+// -----------------------------------------------------------------------
+// frsh_fosa.h
+//========================================================================================
+// ******** ******* ******** ** ** ******** ****** ******** **********
+// **///// /**////** **////// /** /** **///// /** ** **////// /** /**
+// ** /** /** /** /** /** ** /** ** /** /** /**
+// ******* /******* /********* /********** ******* /** ** /********* /**********
+// **//// /**///** ////////** /**//////** **//// /** ** ////////** /**//////**
+// ** /** //** /** /** /** ** /** ** /** /** /**
+// ** /** //** ******** /** /** ** /** ** ******** /** /**
+// // // // //////// // // // /******/ //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh" FOSA(Frescor Oper System Adaptation layer)
+//========================================================================================
+
+
+/**
+ * @file frsh_fosa.c
+ **/
+
+
+/**
+ * @defgroup frshfosa FRSH FOSA public interfaces
+ *
+ * FOSA is an OS adaption layer that encapsulates all POSIX types and
+ * functions into neutral names so that FRSH can compile and be used in
+ * non-POSIX operating systems such as OSE.
+ *
+ * It is divided in two parts:
+ * - FRSH_FOSA: Types visibles to the application via FRSH_API
+ * (thread, signal, mutexes).
+ * - FOSA: Types and functions only used within FRSH.
+ *
+ * The former reside in the FRSH subversion directory and the latter
+ * have their own. They need to be separated because the application
+ * must not see FOSA itself.
+ *
+ * For simplicity, we have chosen to hide the operation function on
+ * signals and mutexes with the assumption that a direct mapping
+ * exists for frsh_signal_t, frsh_signal_info_t and frsh_mutext_t in
+ * the native OS.
+ *
+ * Since there are some parts which are platform dependent a define
+ * has been introduced for each platform. Currently the supported
+ * defines are:
+ *
+ * -DRT_LINUX
+ * -DOSE
+ * -DMARTE_OS
+ *
+ * This module contains the FOSA part exposed by the FRSH_API and
+ * visible for the application.
+ *
+ * On the other hand, there was another file in the API which was also
+ * OS-dependent: frsh_os_compatibility.h. However this dependency
+ * relates more to the implementation of FRSH and therefore it has
+ * been moved to the src directory. It may be integrated in FOSA
+ * during the implementation.
+ *
+ * @{
+ **/
+
+
+//////////////////////////////// OSE ////////////////////////////////////
+#if defined(OSE)
+
+#include "frsh_fosa.h"
+#include "frsh_configuration_parameters.h"
+
+#include "heapapi.h"
+
+/*************************
+ * Thread attributes
+ *************************/
+
+/**
+ * frsh_thread_attr_init()
+ *
+ * Initialize a thread attributes object
+ *
+ * This function initializes the object pointed to by attr to all
+ * the default values defined by FRSH
+ *
+ * @return 0 if successful; otherwise it returns \n
+ * FOSA_ENOMEM: insufficient memory exists to initialize the thread
+ * attributes object
+ **/
+int frsh_thread_attr_init(frsh_thread_attr_t *attr){
+ // The lowest(!) OSE priority is used.
+ attr->prio = FRSH_HIGHEST_THREAD_PRIORITY;
+ attr->stack_size = 1000;
+ attr->app_scheduled = false;
+ attr->appsched_param = NULL;
+ attr->appsched_param_size = 0;
+
+ return 0;
+}
+
+/**
+ * frsh_thread_attr_destroy()
+ *
+ * Destroy a thread attributes object
+ *
+ * This function is used to destroy the thread attributes object,
+ * pointed to by attr, and deallocate any system resources allocated for it
+ *
+ * Returns 0
+ */
+int frsh_thread_attr_destroy(frsh_thread_attr_t *attr) {
+ if(attr->appsched_param != NULL)
+ heap_free_shared(attr->appsched_param);
+ frsh_thread_attr_init(attr);
+ return 0;
+}
+
+/**
+ * frsh_thread_attr_set_stacksize()
+ *
+ * Set the thread minimum stack size in a thread attributes object
+ *
+ * This function sets the minimum stack size of the thread attributes
+ * object attr to the value given by stacksize, in bytes. This
+ * function has no runtime effect on the stack size, except when the
+ * attributes object is used to create a thread, when it will be
+ * created with the specified minimum stack size
+ *
+ * @return 0 if successful, or the following error code:
+ * FOSA_EINVAL: the specified stacksize value is not supported in
+ * this implementation
+ */
+int frsh_thread_attr_set_stacksize
+ (frsh_thread_attr_t *attr, size_t stacksize)
+{
+ //How to check if valid stack size? Possible?.........................
+ //if (??) return FOSA_EINVAL;
+
+ attr->stack_size = (unsigned long) stacksize;
+ return 0;
+}
+
+/**
+ * frsh_thread_attr_get_stacksize()
+ *
+ * Get the thread minimum stack size from a thread attributes object
+ *
+ * This function sets the variable pointed to by stacksize to the
+ * minimum stack size stored in the thread attributes object attr.
+ *
+ * @return 0
+ */
+int frsh_thread_attr_get_stacksize
+ (const frsh_thread_attr_t *attr, size_t *stacksize)
+{
+ *stacksize = attr->stack_size;
+ return 0;
+}
+
+/*@}*/
+
+#endif
+//////////////////////////// End of OSE /////////////////////////////////
--- /dev/null
+// -----------------------------------------------------------------------\r
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:\r
+//\r
+// Universidad de Cantabria, SPAIN\r
+// University of York, UK\r
+// Scuola Superiore Sant'Anna, ITALY\r
+// Kaiserslautern University, GERMANY\r
+// Univ. Politecnica Valencia, SPAIN\r
+// Czech Technical University in Prague, CZECH REPUBLIC\r
+// ENEA SWEDEN\r
+// Thales Communication S.A. FRANCE\r
+// Visual Tools S.A. SPAIN\r
+// Rapita Systems Ltd UK\r
+// Evidence ITALY\r
+//\r
+// See http://www.frescor.org\r
+//\r
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded\r
+// in part by the European Union Sixth Framework Programme\r
+// The European Union is not liable of any use that may be\r
+// made of this code.\r
+//\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or \r
+// without modification, are permitted provided that the \r
+// following conditions are met:\r
+//\r
+// * Redistributions of source code must retain the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer.\r
+// * Redistributions in binary form must reproduce the above \r
+// copyright notice, this list of conditions and the \r
+// following disclaimer in the documentation and/or other \r
+// materials provided with the distribution.\r
+// * Neither the name of FRESCOR nor the names of its \r
+// contributors may be used to endorse or promote products \r
+// derived from this software without specific prior \r
+// written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE \r
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \r
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF \r
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT \r
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
+// POSSIBILITY OF SUCH DAMAGE.\r
+// -----------------------------------------------------------------------
\ No newline at end of file
--- /dev/null
+include ../config.mk
+include ../rules.mk
+
+FOSA_MODULES=fosa_clocks_and_timers fosa_threads_and_signals fosa_app_def_sched fosa_mutexes_and_condvars fosa_misc fosa_long_jump fosa_time fosa_setjmp fosa_group_clocks
+FOSA_OBJS=$(addsuffix .o,$(FOSA_MODULES))
+
+LIBFOSA=libfosa_PARTIKLE.a
+
+all: $(LIBFOSA)
+$(LIBFOSA): $(FOSA_OBJS)
+ $(AR) -r $(LIBFOSA) $(FOSA_OBJS)
+ cp $(LIBFOSA) ../lib
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include <fosa_configuration_parameters.h>
+#include <fosa_app_def_sched.h>
+#include <fosa_threads_and_signals.h>
+#include <fosa_time.h>
+
+#include <sched.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#define REACHS(str) printf ("%s: %s: %d: %s\n", __FILE__, __FUNCTION__, __LINE__, str)
+
+static pthread_t fosa_scheduler_th; // Scheduler thread
+static fosa_ads_scheduler_ops_t fosa_scheduler_ops; // Scheduler operations
+static void * fosa_scheduler_data; // Scheduler parameters
+static size_t fosa_scheduler_data_size;
+static void * fosa_init_args; // Scheduler initialisation args
+static size_t fosa_init_args_size;
+static sigset_t fosa_handled_signals; // Signals handled by the scheduler
+
+// Reply info for 'fosa_ads_invoke_withdata ()'
+struct reply_info{
+ void * msg;
+ size_t * size_ptr;
+};
+static int fosa_reply_key;
+
+void clear_actions (fosa_ads_actions_t *act)
+{
+ posix_appsched_actions_destroy (&(act -> actions));
+ posix_appsched_actions_init (&(act -> actions));
+ act -> activated = false;
+ act -> suspended = false;
+ act -> rejected = false;
+ act -> timeout_ptr = NULL;
+}
+
+void *fosa_scheduler_main (void * args)
+{
+ fosa_ads_actions_t actions;
+ struct posix_appsched_event event;
+ struct timespec current_time;
+ posix_appsched_eventset_t accepted_events;
+
+ // accept events which have a callback associated
+ posix_appsched_fillset (&accepted_events);
+ if (fosa_scheduler_ops.new_thread)
+ posix_appsched_delset (&accepted_events,POSIX_APPSCHED_NEW);
+
+ if (fosa_scheduler_ops.thread_terminate)
+ posix_appsched_delset (&accepted_events,POSIX_APPSCHED_TERMINATE);
+
+ if (fosa_scheduler_ops.thread_ready)
+ posix_appsched_delset (&accepted_events,POSIX_APPSCHED_READY);
+
+ if (fosa_scheduler_ops.thread_block)
+ posix_appsched_delset (&accepted_events,POSIX_APPSCHED_BLOCK);
+
+ if (fosa_scheduler_ops.change_sched_param_thread)
+ posix_appsched_delset (&accepted_events, POSIX_APPSCHED_CHANGE_SCHED_PARAM);
+
+ if (fosa_scheduler_ops.explicit_call_with_data)
+ posix_appsched_delset (&accepted_events, POSIX_APPSCHED_EXPLICIT_CALL_WITH_DATA);
+
+// if (fosa_scheduler_ops.notification_for_thread)
+// posix_appsched_delset (&accepted_events,POSIX_APPSCHED_TASK_NOTIFICATION);
+
+ if (fosa_scheduler_ops.timeout)
+ posix_appsched_delset (&accepted_events,POSIX_APPSCHED_TIMEOUT);
+
+ if (fosa_scheduler_ops.signal)
+ posix_appsched_delset (&accepted_events,POSIX_APPSCHED_SIGNAL);
+
+ posix_appschedattr_seteventmask(&accepted_events);
+
+ // Set the clock (and its) flags used by the scheduler
+ posix_appschedattr_setclock (FOSA_CLOCK_REALTIME);
+ posix_appschedattr_setflags (POSIX_APPSCHED_ABSTIMEOUT);
+
+ // init scheduler
+ fosa_scheduler_ops.init (fosa_scheduler_data, fosa_init_args);
+ clear_actions (&actions);
+
+ while (1) { // scheduler loop
+ if (posix_appsched_execute_actions(&(actions.actions), &fosa_handled_signals, actions.timeout_ptr,
+ ¤t_time, &event))
+ {
+ fosa_scheduler_ops.appsched_error
+ (fosa_scheduler_data, 0x0, FOSA_ADS_THREAD_NOT_ATTACHED, &actions);
+ continue;
+ }
+
+ clear_actions (&actions);
+ switch (event.event_code) {
+ case POSIX_APPSCHED_NEW:
+ fosa_scheduler_ops.new_thread
+ (fosa_scheduler_data,
+ event.thread,
+ &actions,
+ ¤t_time);
+
+ if (!actions.rejected) {
+
+ clear_actions (&actions);
+
+ // alloc memory for reply info of 'fosa_ads_invoke_with_data ()'
+ struct reply_info *reply_mem = malloc (sizeof (struct reply_info));
+ if (!reply_mem) {
+ posix_appsched_actions_addreject (&actions.actions, event.thread);
+ } else {
+ posix_appsched_actions_addaccept (&actions.actions, event.thread);
+ pthread_setspecific_for (fosa_reply_key, event.thread, reply_mem);
+ }
+ }
+ break;
+ case POSIX_APPSCHED_TERMINATE:
+ fosa_scheduler_ops.thread_terminate
+ (fosa_scheduler_data,
+ event.thread,
+ &actions,
+ ¤t_time);
+ break;
+ case POSIX_APPSCHED_READY:
+ fosa_scheduler_ops.thread_ready
+ (fosa_scheduler_data,
+ event.thread,
+ &actions,
+ ¤t_time);
+ break;
+ case POSIX_APPSCHED_BLOCK:
+ fosa_scheduler_ops.thread_block
+ (fosa_scheduler_data,
+ event.thread,
+ &actions,
+ ¤t_time);
+ break;
+ case POSIX_APPSCHED_CHANGE_SCHED_PARAM:
+ fosa_scheduler_ops.change_sched_param_thread
+ (fosa_scheduler_data,
+ event.thread,
+ &actions,
+ ¤t_time);
+ break;
+ case POSIX_APPSCHED_EXPLICIT_CALL_WITH_DATA:
+ {
+ struct reply_info *fosa_reply;
+
+ // Get reply memory pointer
+ pthread_getspecific_from (fosa_reply_key, event.thread, (void **) &fosa_reply);
+ fosa_scheduler_ops.explicit_call_with_data
+ (fosa_scheduler_data,
+ event.thread,
+ event.event_info.info,
+ event.info_size,
+ fosa_reply -> msg,
+ fosa_reply -> size_ptr,
+ &actions,
+ ¤t_time);
+
+ // activate the thread unless suspended or already activated
+ if (!actions.suspended && !actions.activated) {
+ posix_appsched_actions_addactivate
+ (&actions.actions, event.thread);
+ }
+
+ } break;
+ case POSIX_APPSCHED_TIMEOUT:
+ fosa_scheduler_ops.timeout
+ (fosa_scheduler_data,
+ &actions,
+ ¤t_time);
+ break;
+ case POSIX_APPSCHED_SIGNAL:
+ fosa_scheduler_ops.signal
+ (fosa_scheduler_data,
+ event.event_info.siginfo.si_signo,
+ (fosa_signal_info_t)event.event_info.siginfo.si_value.sival_ptr,
+ &actions,
+ ¤t_time);
+ break;
+/* - NOT IMPLEMENTED
+
+ case POSIX_APPSCHED_THREAD_NOTIFICATION:
+ fosa_scheduler_ops.notification_for_thread
+ (fosa_scheduler_data,
+ event.thread,(fosa_clock_id_t) event.event_info.info,
+ &actions,
+ ¤t_time);
+ break;
+*/
+ default:
+ printf ("BUG: Unknown ADS event\n");
+ exit (-20);
+ break;
+ }
+ }
+}
+
+/********************************
+ * Application-defined scheduling
+ ********************************/
+int fosa_ads_scheduler_create
+ (const fosa_ads_scheduler_ops_t * scheduler_ops,
+ size_t scheduler_data_size,
+ void * init_args,
+ size_t init_args_size)
+{
+ pthread_attr_t attr;
+ struct sched_param sp;
+
+ if (!scheduler_ops)
+ return EINVAL;
+ fosa_scheduler_ops = *scheduler_ops;
+
+ // Alloc memory for init args and scheduler data
+ fosa_init_args_size = init_args_size;
+ fosa_init_args = malloc (init_args_size);
+ if (!init_args)
+ return EAGAIN;
+
+ memcpy (fosa_init_args, init_args, init_args_size);
+
+ fosa_scheduler_data_size = scheduler_data_size;
+ fosa_scheduler_data = malloc (scheduler_data_size);
+ if (!fosa_scheduler_data) {
+ free (init_args);
+ return EAGAIN;
+ }
+ memset (fosa_scheduler_data, 0, scheduler_data_size);
+
+ // Key for reply information index of 'fosa_reply' for each thread
+ pthread_key_create (&fosa_reply_key, NULL);
+
+ // Set scheduler thread parameters
+ pthread_attr_init (&attr);
+ sp.sched_priority = sched_get_priority_max (SCHED_FIFO) + FOSA_ADS_SCHEDULER_PRIO_DIFF;
+ pthread_attr_setschedparam (&attr, &sp);
+ pthread_attr_setschedpolicy (&attr, SCHED_FIFO);
+ pthread_attr_setappschedulerstate (&attr, PTHREAD_APPSCHEDULER);
+ pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
+ pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED);
+
+ if (pthread_create (&fosa_scheduler_th, &attr, fosa_scheduler_main, NULL))
+ return errno;
+ else
+ return 0;
+}
+
+int fosa_thread_attr_set_appscheduled
+ (fosa_thread_attr_t *attr,
+ bool appscheduled)
+{
+ int err;
+
+ err = pthread_attr_setappscheduler (attr, fosa_scheduler_th);
+ if (err)
+ return err;
+
+ if (appscheduled)
+ return pthread_attr_setschedpolicy (attr, SCHED_APP);
+ else
+ return pthread_attr_setschedpolicy (attr, SCHED_FIFO);
+}
+
+
+int fosa_thread_attr_get_appscheduled
+ (const fosa_thread_attr_t *attr,
+ bool *appscheduled)
+{
+ int policy, err;
+
+ err = pthread_attr_getschedpolicy (attr, &policy);
+ if (err)
+ return err;
+
+ *appscheduled = (policy == SCHED_APP);
+ return 0;
+}
+
+
+int fosa_thread_attr_set_appsched_params
+ (fosa_thread_attr_t *attr,
+ const void *param,
+ size_t paramsize)
+{
+#if FOSA_ADS_SCHEDPARAM_MAX > POSIX_APPSCHEDPARAM_MAX
+#error FOSA_ADS_SCHEDPARAM_MAX > POSIX_APPSCHEDPARAM_MAX
+#endif
+ if (paramsize > FOSA_ADS_SCHEDPARAM_MAX)
+ return FOSA_EINVAL;
+
+ return pthread_attr_setappschedparam (attr, param, paramsize);
+}
+
+
+int fosa_thread_attr_get_appsched_params
+ (const fosa_thread_attr_t *attr,
+ void *param,
+ size_t *paramsize)
+{
+ return pthread_attr_getappschedparam (attr, param, paramsize);
+}
+
+
+int fosa_ads_set_appscheduled
+ (fosa_thread_id_t thread,
+ bool appscheduled)
+{
+ struct sched_param sp;
+ int policy_old, policy_new, err;
+
+ err = pthread_getschedparam (thread, &policy_old, &sp);
+ if (err)
+ return err;
+
+ if (appscheduled) {
+ err = pthread_setappscheduler (thread, fosa_scheduler_th);
+ if (err)
+ return err;
+
+ policy_new = SCHED_APP;
+ } else {
+ policy_new = SCHED_FIFO;
+ }
+
+ if (policy_new != policy_old)
+ return pthread_setschedparam (thread, policy_new, &sp);
+
+ return 0;
+}
+
+
+int fosa_ads_get_appscheduled
+ (fosa_thread_id_t thread,
+ bool *appscheduled)
+{
+ struct sched_param sp;
+ int policy, err;
+
+ err = pthread_getschedparam (thread, &policy, &sp);
+ if (err)
+ return err;
+
+ *appscheduled = (policy == SCHED_APP);
+ return 0;
+}
+
+
+int fosa_ads_set_appsched_params
+ (fosa_thread_id_t thread,
+ const void *param,
+ size_t paramsize)
+{
+ return pthread_setappschedparam (thread, param, paramsize);
+}
+
+
+int fosa_ads_get_appsched_params
+ (fosa_thread_id_t thread,
+ void *param,
+ size_t *paramsize)
+{
+ return pthread_getappschedparam (thread, param, paramsize);
+}
+
+
+
+/*********************************
+ * ADS actions
+ *********************************/
+int fosa_adsactions_add_reject
+ (fosa_ads_actions_t *sched_actions,
+ fosa_thread_id_t thread)
+{
+ sched_actions -> rejected = true;
+ return posix_appsched_actions_addreject (&(sched_actions -> actions), thread);
+}
+
+extern inline int fosa2prtk (int prio, int urg);
+int fosa_adsactions_add_activate
+ (fosa_ads_actions_t *sched_actions,
+ fosa_thread_id_t thread,
+ fosa_ads_urgency_t urgency)
+{
+ sched_actions -> activated = true;
+
+#ifdef CONFIG_URGENCY
+ #error "Urgency not supported. Disable this feature in the Makefile"
+ int fosaprio, policy;
+ struct sched_param sp;
+
+ pthread_getschedparam (thread, &policy, &sp);
+ fosa_thread_get_prio (thread, &fosaprio);
+ sp.sched_priority = fosa2prtk (fosaprio, urgency);
+// printf ("policy=%d, prio=%d, urg=%d, new_prio=%d\n", policy);
+ pthread_setschedparam (thread, policy, &sp);
+#endif
+ return posix_appsched_actions_addactivate (&(sched_actions -> actions), thread);
+}
+
+int fosa_adsactions_add_suspend
+ (fosa_ads_actions_t *sched_actions,
+ fosa_thread_id_t thread)
+{
+ sched_actions -> suspended = true;
+ return posix_appsched_actions_addsuspend (&(sched_actions -> actions), thread);
+}
+
+int fosa_adsactions_add_timeout
+ (fosa_ads_actions_t *sched_actions,
+ fosa_clock_id_t clock_id,
+ const fosa_abs_time_t *at_time)
+{
+ sched_actions -> timeout = fosa_abs_time_to_timespec (*at_time);
+ sched_actions -> timeout_ptr = &(sched_actions -> timeout);
+ return 0;
+}
+
+int fosa_adsactions_add_thread_notification
+ (fosa_ads_actions_t *sched_actions,
+ fosa_thread_id_t thread,
+ fosa_clock_id_t clock_id,
+ const fosa_abs_time_t *at_time)
+{
+ printf ("BUG: fosa_adsactions_add_thread_notification: Not implemented\n");
+ exit (-21);
+ return 0;
+}
+
+
+int fosa_ads_set_handled_signal_set (fosa_signal_t set[], int size)
+{
+ int i;
+
+ if (!pthread_equal (pthread_self (), fosa_scheduler_th))
+ return EPOLICY;
+
+ sigemptyset (&fosa_handled_signals);
+ for (i = 0; i < size; i++) {
+ if (FOSA_SIGNAL_MIN > set [i] || set [i] > FOSA_SIGNAL_MAX)
+ return EINVAL;
+ sigaddset (&fosa_handled_signals, set[i]);
+ }
+ return fosa_set_accepted_signals (set, size);
+}
+
+
+int fosa_signal_queue_scheduler (fosa_signal_t signal, fosa_signal_info_t info)
+{
+ return fosa_signal_queue (signal, info, 0);
+}
+
+
+int fosa_ads_invoke_withdata
+ (const void *msg, size_t msg_size, void *reply, size_t *reply_size)
+{
+ struct reply_info *fosa_reply;
+
+#if FOSA_ADS_SCHEDINFO_MAX > POSIX_APPSCHEDINFO_MAX
+#error FOSA_ADS_SCHEDINFO_MAX > POSIX_APPSCHEDINFO_MAX
+#endif
+
+ if (msg_size > FOSA_ADS_SCHEDINFO_MAX)
+ return EINVAL;
+
+ fosa_reply = (struct reply_info *) pthread_getspecific (fosa_reply_key);
+ fosa_reply -> msg = reply;
+ fosa_reply -> size_ptr = reply_size;
+
+ return posix_appsched_invoke_withdata (msg, msg_size, NULL, NULL);
+}
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include <fosa_clocks_and_timers.h>
+#include <fosa_time.h>
+#include <stdlib.h>
+
+/*************************
+ * Timing: Clocks
+ *************************/
+int fosa_clock_get_time(fosa_clock_id_t clockid, fosa_abs_time_t *current_time)
+{
+ int err;
+ struct timespec now;
+
+ err = clock_gettime (clockid, &now);
+ *current_time = fosa_timespec_to_abs_time(now);
+
+ return 0;
+}
+
+
+int fosa_thread_get_cputime_clock(fosa_thread_id_t tid, fosa_clock_id_t *clockid)
+{
+ return pthread_getcpuclockid (tid, clockid);
+}
+
+
+
+
+/*************************
+ * Timing: Timers
+ *************************/
+int fosa_timer_create
+ (fosa_clock_id_t clockid, fosa_signal_t signal, fosa_signal_info_t info,
+ fosa_timer_id_t *timerid)
+ {
+ struct sigevent se;
+ struct sigaction act, oact;
+
+ sigaction (signal, NULL, &oact);
+ act = oact;
+ act.sa_flags = SA_SIGINFO; // accept signal queuing
+ sigaction (signal, &act, NULL);
+
+ se.sigev_notify = SIGEV_SIGNAL;
+ se.sigev_signo = signal;
+
+ se.sigev_value.sival_int = info.sival_int;
+ se.sigev_value.sival_ptr = info.sival_ptr;
+
+ return timer_create (clockid, &se, timerid);
+}
+
+
+int fosa_timer_create_with_receiver
+ (fosa_clock_id_t clockid, fosa_signal_t signal, fosa_signal_info_t info,
+ fosa_timer_id_t *timerid, fosa_thread_id_t receiver)
+{
+ return fosa_timer_create (clockid, signal, info, timerid);
+}
+
+int fosa_timer_delete(fosa_timer_id_t timerid)
+{
+ return timer_delete (timerid);
+}
+
+
+int fosa_rel_timer_arm (fosa_timer_id_t timerid, const fosa_rel_time_t *value)
+{
+ struct itimerspec tvalue;
+
+ tvalue.it_value = fosa_rel_time_to_timespec(*value);
+ tvalue.it_interval = (struct timespec) {0,0};
+
+ if (timer_settime (timerid, 0, &tvalue, NULL))
+ return FOSA_EINVAL;
+
+ return 0;
+}
+
+int fosa_abs_timer_arm (fosa_timer_id_t timerid, const fosa_abs_time_t *value)
+{
+ struct itimerspec tvalue;
+
+ tvalue.it_value = fosa_abs_time_to_timespec(*value);
+ tvalue.it_interval = (struct timespec) {0,0};
+
+ if (timer_settime (timerid, TIMER_ABSTIME, &tvalue, NULL))
+ return FOSA_EINVAL;
+
+ return 0;
+}
+
+
+int fosa_timer_get_remaining_time
+ (fosa_timer_id_t timerid, fosa_rel_time_t *remaining_time)
+{
+ struct itimerspec value;
+
+ if (timer_gettime (timerid, &value))
+ return FOSA_EINVAL;
+
+ *remaining_time = fosa_timespec_to_rel_time (value.it_value);
+ return 0;
+}
+
+
+int fosa_timer_disarm (fosa_timer_id_t timerid, fosa_rel_time_t *remaining_time)
+{
+ struct itimerspec null_timer, old;
+
+ // NULL timer -> disarm
+ null_timer = (struct itimerspec) {
+ .it_value = {0, 0},
+ .it_interval = {0, 0},
+ };
+
+ if (timer_settime (timerid, 0, &null_timer, &old))
+ return FOSA_EINVAL;
+
+ if (remaining_time)
+ *remaining_time = fosa_timespec_to_rel_time (old.it_value);
+
+ return 0;
+}
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_group_clocks.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include "fosa_group_clocks.h"
+
+/**
+ * fosa_thread_set_create()
+ *
+ * Create an empty thread set and return an identifier
+ *
+ * This function stores in the variable pointed to by set the
+ * identifier of a thread set that is created by the function.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EAGAIN: no resources are currently available to create the
+ * thread set
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_set_create(fosa_thread_set_id_t *set)
+{
+ return groupclock_create (set);
+}
+
+
+/**
+ * fosa_thread_set_destroy()
+ *
+ * Destroy a thread set
+ *
+ * This function destroys the thread set identified by set. The
+ * threads that were in the set are detached from the set. It is
+ * an error to use the identifier after this call. The effects of
+ * using a CPU-time clock associated with the destroyed thread are
+ * undefined.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: set is invalid
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_set_destroy(fosa_thread_set_id_t set)
+{
+ return groupclock_delete (set);
+}
+
+
+/**
+ * fosa_thread_set_add()
+ *
+ * Add a thread to a thread set
+ *
+ * This function adds the thread identified with thread_id to the
+ * thread set identified by set.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: set is invalid
+ * FOSA_ENOTSUP: thread already a member of some other set
+ * FOSA_EAGAIN: no resources available to add the new thread
+ * FOSA_ESRCH: thread_id doesn't identify a valid thread
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_set_add(fosa_thread_set_id_t set,
+ fosa_thread_id_t thread_id)
+{
+ return groupclock_add (set, thread_id);
+}
+
+
+
+/**
+ * fosa_thread_set_del()
+ *
+ * Delete a thread from a thread set
+ *
+ * This function deletes the thread identified with thread_id from
+ * the thread set identified by set.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: set is invalid
+ * FOSA_EINVAL: thread is not a member of the set
+ * FOSA_ESRCH: thread_id doesn't identify a valid thread
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_thread_set_del(fosa_thread_set_id_t set,
+ fosa_thread_id_t thread_id)
+{
+ return groupclock_remove (set, thread_id);
+}
+
+/**
+ * fosa_get_groupcpu_clock()
+ *
+ * Get the identifier of a cpu-time clock associated to a thread
+ * set
+ *
+ * This function stores in the variable pointed to by clockid the
+ * identifier of a cpu-time clock for the thread set specified
+ * by set.
+ *
+ * Returns 0 if successful; otherwise it returns an error code:
+ * FOSA_EINVAL: the set is invalid
+ * FOSA_EINVAL: clock_id is a null pointer
+ *
+ * Alternatively, in case of error the implementation is allowed to
+ * notify it to the system console and then terminate the FRSH
+ * implementation and dependant applications
+ **/
+int fosa_get_groupcpu_clock(const fosa_thread_set_id_t set,
+ fosa_clock_id_t *clock_id)
+{
+ return groupclock_getclockid (set, clock_id);
+}
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_long_jump.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#ifdef CONFIG_LONGJUMP
+
+#include <fosa_long_jump.h>
+#include <stdio.h>
+
+#define LONGJMP_MAGIC 0x01234567
+pthread_t jmp_used_signals [LONGJMP_NSIG] = {[0 ... (LONGJMP_NSIG - 1)] = NULL};
+pthread_mutex_t signal_pool_m = PTHREAD_MUTEX_INITIALIZER;
+
+extern void fosa_longjmp (fosa_long_jump_context_t ctx, unsigned long magic);
+
+int fosa_long_jump_was_performed
+ (const fosa_long_jump_context_t * context, int * jumped)
+{
+ if (!context && !jumped)
+ return FOSA_EINVAL;
+
+ *jumped = ((*(context))[6] == LONGJMP_MAGIC);
+ return 0;
+}
+
+
+void jmp_handler (int signo, siginfo_t *info, void *context)
+{
+ fosa_long_jump_context_t *jmp_info = (fosa_long_jump_context_t *) info -> si_value.sival_ptr;
+
+ sigset_t s;
+
+ // Restore the signal mask
+ s.sig = (*jmp_info)[7];
+ pthread_sigmask (SIG_SETMASK, &s, NULL);
+
+#ifdef CONFIG_LONGJUMP_FREE_SIGNAL
+ sigset_t set;
+
+ // Free this signal
+ sigemptyset (&set);
+ sigaddset (&set, signo);
+ pthread_sigmask (SIG_BLOCK, &sigmask, NULL);
+
+ pthread_mutex_lock (&signal_pool_m);
+ jmp_used_signals [signo] = NULL;
+ pthread_mutex_unlock (&signal_pool_m);
+#endif
+
+ // Restore the saved context
+ fosa_longjmp (*jmp_info, LONGJMP_MAGIC);
+ return;
+}
+
+
+int fosa_long_jump_install_handler
+ (fosa_signal_t *signal, fosa_thread_id_t *handler)
+{
+ int i;
+ struct sigaction sa;
+ sigset_t sigmask;
+
+ // Check if current thread has a handler associated
+ for (i = 0; i < LONGJMP_NSIG; i ++)
+ if (jmp_used_signals [i] == pthread_self ()) {
+ sigemptyset (&sigmask);
+ sigaddset (&sigmask, LONGJMP_FIRSTSIG + i);
+ pthread_sigmask (SIG_UNBLOCK, &sigmask, NULL);
+ return 0;
+ }
+
+ // Find the first usable signal
+ pthread_mutex_lock (&signal_pool_m);
+ for (i = 0; i < LONGJMP_NSIG && jmp_used_signals [i]; i++);
+ if (i >= LONGJMP_NSIG) {
+ pthread_mutex_unlock (&signal_pool_m);
+ return FOSA_ENOMEM;
+ }
+
+ jmp_used_signals [i] = pthread_self ();
+ pthread_mutex_unlock (&signal_pool_m);
+
+ *signal = LONGJMP_FIRSTSIG + i;
+ *handler = pthread_self ();
+
+ // intall the jump handler
+ sa.sa_flags = SA_SIGINFO;
+ sigfillset (&sa.sa_mask);
+ sa.sa_sigaction = jmp_handler;
+ sigaction (*signal, &sa, NULL);
+
+ // unmask the signal for the calling thread
+ sigemptyset (&sigmask);
+ sigaddset (&sigmask, *signal);
+ pthread_sigmask (SIG_UNBLOCK, &sigmask, NULL);
+
+ return 0;
+}
+
+#endif /* CONFIG_LONGJUMP */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include <time.h>
+
+
+unsigned int sleep(unsigned int seconds)
+{
+ struct timespec remain, t = {seconds, 0};
+ if (nanosleep (&t, &remain))
+ return remain.tv_sec;
+ else
+ return 0;
+}
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include <fosa_mutexes_and_condvars.h>
+#include <fosa_time.h>
+
+/*******************************************************
+ * Mutexes with priority ceiling
+ ******************************************************/
+int fosa_mutex_init(fosa_mutex_t *mutex, int prioceiling)
+{
+ pthread_mutexattr_t attr;
+ int err;
+
+ err = pthread_mutexattr_init (&attr);
+ if (err)
+ return err;
+
+ pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK);
+ pthread_mutexattr_setprotocol (&attr, PTHREAD_PRIO_PROTECT);
+ err = pthread_mutexattr_setprioceiling (&attr, prioceiling);
+ if (err)
+ return err;
+
+ return pthread_mutex_init (mutex, &attr);
+}
+
+int fosa_mutex_destroy(fosa_mutex_t *mutex)
+{
+ return pthread_mutex_destroy (mutex);
+}
+
+int fosa_mutex_set_prioceiling
+ (fosa_mutex_t *mutex, int new_ceiling, int *old_ceiling)
+{
+ return pthread_mutex_setprioceiling (mutex, new_ceiling, old_ceiling);
+}
+
+int fosa_mutex_get_prioceiling(const fosa_mutex_t *mutex, int *ceiling)
+{
+ return pthread_mutex_getprioceiling (mutex, ceiling);
+}
+
+int fosa_mutex_lock(fosa_mutex_t *mutex)
+{
+ return pthread_mutex_lock (mutex);
+}
+
+int fosa_mutex_trylock(fosa_mutex_t *mutex)
+{
+ return pthread_mutex_trylock (mutex);
+}
+
+int fosa_mutex_unlock(fosa_mutex_t *mutex)
+{
+ return pthread_mutex_unlock (mutex);
+}
+
+
+/**********************
+ * Condition variables
+ *********************/
+int fosa_cond_init(fosa_cond_t *cond)
+{
+ pthread_condattr_t attr;
+ int err;
+
+ err = pthread_condattr_init (&attr);
+ if (err)
+ return err;
+
+ return pthread_cond_init (cond, NULL);
+}
+
+int fosa_cond_destroy(fosa_cond_t *cond)
+{
+ return pthread_cond_destroy (cond);
+}
+
+int fosa_cond_signal(fosa_cond_t *cond)
+{
+ return pthread_cond_signal (cond);
+}
+
+int fosa_cond_broadcast(fosa_cond_t *cond)
+{
+ return pthread_cond_broadcast (cond);
+}
+
+int fosa_cond_wait(fosa_cond_t *cond, fosa_mutex_t *mutex)
+{
+ return pthread_cond_wait (cond, mutex);
+}
+
+int fosa_cond_timedwait (fosa_cond_t *cond, fosa_mutex_t *mutex,
+ const fosa_abs_time_t *abstime)
+{
+ int err;
+ struct timespec tout = fosa_abs_time_to_timespec (*abstime);
+
+ err = pthread_cond_timedwait (cond, mutex, &tout);
+ if (err == ETIMEDOUT)
+ return FOSA_ETIMEDOUT;
+
+ if (err)
+ return FOSA_EINVAL;
+
+ return 0;
+}
--- /dev/null
+/*
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FOSA (Frsh Operating System Abstraction)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+ //
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+*/
+/*
+ * $FILE: fosa_setjmp.S
+ *
+ * Setjmp and Longjmp healper functions
+ */
+
+.text
+
+.global fosa_long_jump_save_context, fosa_setjmp, fosa_longjmp
+.type fosa_long_jump_save_context,@function
+.type fosa_setjmp,@function
+.type fosa_longjmp,@function
+
+
+fosa_long_jump_save_context:
+ subl $44, %esp
+ cmpl $0, 48(%esp)
+ jne .L2
+ movl $22, 24(%esp)
+ jmp .L4
+.L2:
+ movl $0, 24(%esp)
+ movl 44(%esp), %ecx
+ leal 48(%esp), %edx
+ movl 48(%esp), %eax
+ movl %ebx, 0(%eax)
+ movl %esi, 4(%eax)
+ movl %edi, 8(%eax)
+ movl %ebp, 12(%eax)
+ movl %edx, 16(%eax)
+ movl %ecx, 20(%eax)
+ movl $0, 24(%eax)
+
+ leal 28(%eax), %eax
+ movl %eax, 8(%esp)
+ movl $0, 4(%esp)
+ movl $0, (%esp)
+ call pthread_sigmask
+
+.L4:
+ movl 24(%esp), %eax
+ addl $44, %esp
+ ret
+
+
+fosa_setjmp:
+ movl 0(%esp), %ecx
+ leal 4(%esp), %edx
+ movl (%edx), %eax
+ movl %ebx, 0(%eax)
+ movl %esi, 4(%eax)
+ movl %edi, 8(%eax)
+ movl %ebp, 12(%eax)
+ movl %edx, 16(%eax)
+ movl %ecx, 20(%eax)
+ movl $0, 24(%eax)
+ movl $0, %eax
+ ret
+
+fosa_longjmp:
+ movl 4(%esp), %ecx
+ movl 8(%esp), %eax
+ movl %eax, 24(%ecx)
+ movl 20(%ecx), %edx
+ movl 0(%ecx), %ebx
+ movl 4(%ecx), %esi
+ movl 8(%ecx), %edi
+ movl 12(%ecx), %ebp
+ movl 16(%ecx), %esp
+ movl $0, %eax
+ jmp *%edx
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include <fosa_configuration_parameters.h>
+#include <fosa_threads_and_signals.h>
+#include <fosa_time.h>
+#include <unistd.h>
+#include <signal.h>
+
+#define TRACE(str, args...) printf ("%d: %s: " str, __LINE__, __func__, ##args)
+
+/*************************
+ * Thread identification
+ *************************/
+bool fosa_thread_equal(fosa_thread_id_t t1, fosa_thread_id_t t2)
+{
+ return pthread_equal (t1, t2);
+}
+
+fosa_thread_id_t fosa_thread_self()
+{
+ return pthread_self();
+}
+
+/*************************
+ * Thread attributes
+ *************************/
+
+int fosa_thread_attr_init(fosa_thread_attr_t *attr)
+{
+ return pthread_attr_init (attr);
+}
+
+int fosa_thread_attr_destroy(fosa_thread_attr_t *attr)
+{
+ return pthread_attr_destroy (attr);
+}
+
+int fosa_thread_attr_set_stacksize(fosa_thread_attr_t *attr,
+ size_t stacksize)
+{
+ return pthread_attr_setstacksize (attr, stacksize);
+}
+
+
+int fosa_thread_attr_get_stacksize(const fosa_thread_attr_t *attr,
+ size_t *stacksize)
+{
+ return pthread_attr_getstacksize (attr, stacksize);
+}
+
+
+/*************************
+ * Thread creation and termination
+ *************************/
+ int fosa_thread_create
+ (fosa_thread_id_t *tid,
+ const fosa_thread_attr_t *attr,
+ fosa_thread_code_t code,
+ void * arg)
+{
+ return pthread_create (tid, attr, code, arg);
+}
+
+
+/**************************************************
+ * Thread-specific data
+ * (extended with access from a different thread)
+ **************************************************/
+int fosa_key_create(int *key)
+{
+ switch (pthread_key_create (key, NULL)) {
+ case 0:
+ break;
+ case ENOMEM:
+ return ENOMEM;
+ break;
+ case EAGAIN:
+ default:
+ return FOSA_EINVAL;
+ }
+
+ if (*key >= FOSA_MAX_KEYS + 1) {
+ pthread_key_delete (*key);
+ return FOSA_EINVAL;
+ }
+
+ return 0;
+}
+
+int fosa_key_destroy(int key)
+{
+ if (key < 0 || key >= FOSA_MAX_KEYS + 1)
+ return FOSA_EINVAL;
+
+ return pthread_key_delete (key);
+}
+
+ int fosa_thread_set_specific_data
+ (int key, fosa_thread_id_t tid, const void * value)
+{
+ if (key < 0 || key >= FOSA_MAX_KEYS + 1)
+ return FOSA_EINVAL;
+
+ return pthread_setspecific_for (key, tid, value);
+}
+
+int fosa_thread_get_specific_data(int key, fosa_thread_id_t tid,
+ void ** value)
+{
+ if (key < 0 || key >= FOSA_MAX_KEYS + 1)
+ return FOSA_EINVAL;
+
+ return pthread_getspecific_from (key, tid, value);
+}
+
+/**********************
+ * Thread scheduling
+ **********************/
+// PaRTiKle uses decreasing values for increasing priority (0 -> maxprio)
+
+inline int fosa2prtk (int prio, int urg)
+{
+ return ((prio & 0x3f) << 4) + (urg & 0xf);
+}
+
+static inline int prtk2fprio (int prio)
+{
+ return (prio >> 4) & 0x3f;
+}
+
+static inline int prtk2furg (int prio)
+{
+ return prio & 0xf;
+}
+
+
+int fosa_get_priority_max()
+{
+ return prtk2fprio (sched_get_priority_min (SCHED_FIFO));
+}
+
+int fosa_get_priority_min()
+{
+ return prtk2fprio (sched_get_priority_max (SCHED_FIFO));
+}
+
+int fosa_thread_attr_set_prio(fosa_thread_attr_t *attr, int prio)
+{
+ struct sched_param sp;
+
+ if (prio > fosa_get_priority_max () || prio < fosa_get_priority_min ())
+ return EINVAL;
+
+ sp.sched_priority = sched_get_priority_min (SCHED_FIFO) - fosa2prtk (prio, 0);
+
+ return pthread_attr_setschedparam (attr, &sp);
+}
+
+ int fosa_thread_attr_get_prio
+ (const fosa_thread_attr_t *attr, int *prio)
+{
+ struct sched_param sp;
+
+ pthread_attr_getschedparam (attr, &sp);
+
+ *prio = prtk2fprio (sched_get_priority_min (SCHED_FIFO) - sp.sched_priority);
+
+ return 0;
+}
+
+int fosa_thread_set_prio(fosa_thread_id_t tid, int prio)
+{
+ struct sched_param sp;
+ int policy;
+
+ if (prio > fosa_get_priority_max () || prio < fosa_get_priority_min ())
+ return EINVAL;
+
+ pthread_getschedparam (tid, &policy, &sp);
+ sp.sched_priority = sched_get_priority_min (SCHED_FIFO) - fosa2prtk (prio, 0);
+
+ return pthread_setschedparam (tid, policy, &sp);
+}
+
+int fosa_thread_get_prio (fosa_thread_id_t tid, int *prio)
+{
+ struct sched_param sp;
+ int policy;
+
+ pthread_getschedparam (tid, &policy, &sp);
+ *prio = sched_get_priority_min (SCHED_FIFO) - sp.sched_priority;
+
+ return 0;
+}
+
+
+/*************
+ * Signals
+ *************/
+int fosa_set_accepted_signals(fosa_signal_t set[], int size)
+{
+ int i;
+ sigset_t accept_set;
+ struct sigaction act;
+
+// printf ("%d: %s: limits=[%d, %d]\n", __LINE__, __FUNCTION__,
+// FOSA_SIGNAL_MIN, FOSA_SIGNAL_MAX);
+
+ if (size < 0)
+ return EINVAL;
+
+ sigemptyset (&accept_set);
+ act.sa_mask = accept_set;
+ act.sa_flags = SA_SIGINFO;
+ act.sa_handler = SIG_DFL;
+
+// printf ("%d: %s: add signals\n", __LINE__, __FUNCTION__);
+ for (i = 0; i < size; i ++) {
+// printf ("%d: %s: signal=%d \n", __LINE__, __FUNCTION__, set[i]);
+
+ if (FOSA_SIGNAL_MIN > set [i] || set [i] > FOSA_SIGNAL_MAX)
+ return EINVAL;
+
+// printf ("%d: %s: sigaction\n", __LINE__, __FUNCTION__);
+ sigaction (set [i], &act, NULL);
+ sigaddset (&accept_set, set [i]);
+ }
+
+// printf ("%d: %s: pthread_sigmask\n", __LINE__, __FUNCTION__);
+ assert (!pthread_sigmask (SIG_BLOCK, &accept_set, NULL));
+ return 0;
+}
+
+
+int fosa_signal_queue
+ (fosa_signal_t signal, fosa_signal_info_t info,
+ fosa_thread_id_t receiver)
+{
+ union sigval nfo = (union sigval) info.sival_ptr;
+
+ if (sigqueue (1, signal, nfo))
+ return errno;
+ else
+ return 0;
+}
+
+
+ int fosa_signal_wait
+ (fosa_signal_t set[], int size, fosa_signal_t *signal_received,
+ fosa_signal_info_t *info)
+{
+ return fosa_signal_timedwait (set, size, signal_received, info, NULL);
+}
+
+
+ int fosa_signal_timedwait
+ (fosa_signal_t set[], int size, fosa_signal_t *signal_received,
+ fosa_signal_info_t *info, const fosa_rel_time_t *timeout)
+{
+ int i, sig;
+ sigset_t wset;
+ siginfo_t nfo;
+
+ if (size < 0)
+ return EINVAL;
+
+ sigemptyset (&wset);
+ for (i = 0; i < size; i ++) {
+ if (FOSA_SIGNAL_MIN > set [i] || set [i] > FOSA_SIGNAL_MAX)
+ return EINVAL;
+ sigaddset (&wset, set [i]);
+ }
+
+ sig = sigtimedwait (&wset, &nfo, timeout);
+ if (sig == -1)
+ return errno;
+
+ if (info)
+ *info = (fosa_signal_info_t) nfo.si_value.sival_ptr;
+
+ if (signal_received)
+ *signal_received = sig;
+
+ return 0;
+}
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+// fosa_time.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include "fosa.h"
+
+/**
+ * fosa_eat()
+ *
+ * Eat some time using system clock facilities
+ **/
+void fosa_eat(const fosa_rel_time_t *cpu_time)
+{
+ fosa_clock_id_t clock_id;
+ fosa_abs_time_t current_time, time_to_go;
+
+ // NOTE: there should be a constant for the cpu_clock_id of the caller
+ // to avoid calling 'fosa_thread_get_cputime_clock'
+ fosa_thread_get_cputime_clock(fosa_thread_self(), &clock_id);
+ fosa_clock_get_time(clock_id, ¤t_time);
+
+ time_to_go = fosa_abs_time_incr(current_time, *cpu_time);
+
+ /* We also spread smaller_timespec */
+ while ( fosa_abs_time_smaller_or_equal(current_time, time_to_go) )
+ {
+ fosa_clock_get_time(clock_id, ¤t_time);
+ }
+}
+
+
+
--- /dev/null
+include ../../config.mk
+include ../../rules.mk
+
+SOURCES = $(wildcard *.c)
+NAMES = $(basename $(SOURCES))
+OBJECTS = $(addsuffix .o, $(NAMES))
+TARGETS = $(addsuffix .prtk, $(NAMES))
+
+LD=$(PRTK_PATH)/user/bin/ldkernel -f
+
+%.prtk: %.o libfosa
+ $(LD) -o $@ $< $(FOSA_PATH)/lib/libfosa_$(PLATFORM).a
+
+all: $(TARGETS)
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+/*
+ * Vicent Brocal <vibrotor@ai2.upv.es>:
+ * Minor modifications to adapt the code to test the implementation of
+ * group clocks for PaRTiKle.
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+
+#include <assert.h>
+#include <stdlib.h> // for exit in assert
+#include <string.h> // for memset
+
+#include "fosa.h"
+
+
+/*****************************/
+/* D E F I N I T I O N S */
+/*****************************/
+#define RT_ERROR_SIGWAIT -2
+#define RT_ERROR_TIMER -3
+
+#define SIGNAL_TIMER (FOSA_SIGNAL_MAX - 1)
+
+#define SIGNAL_A (FOSA_SIGNAL_MAX - 2)
+#define SIGNAL_KILL_A (FOSA_SIGNAL_MAX - 3)
+
+#define SIGNAL_B (FOSA_SIGNAL_MAX - 4)
+#define SIGNAL_KILL_B (FOSA_SIGNAL_MAX - 5)
+#define SIGNAL_C (FOSA_SIGNAL_MAX - 6)
+#define SIGNAL_KILL_C (FOSA_SIGNAL_MAX - 7)
+
+
+#define PRIO_MAIN 4
+#define PRIO_A 5
+#define PRIO_B 6
+#define PRIO_C 7
+#define PRIO_CATCHER 8
+
+
+typedef struct _my_signal_info_t
+{
+ fosa_rel_time_t eat_time;
+} my_signal_info_t;
+
+typedef struct _my_thread_arg_t
+{
+ char identifier[100];
+ fosa_signal_t signum;
+ fosa_signal_t sigkill;
+} my_thread_arg_t;
+
+
+
+
+/***************************/
+/* P R O T O T Y P E S */
+/***************************/
+static void *controlled_thread(void *thread_arg);
+static void *catcher_thread(void *arg);
+
+static void create_thread(fosa_thread_code_t thread_code,
+ void *arg,
+ int priority,
+ fosa_thread_id_t *tid);
+
+static void time_printf(const char *format, ...);
+
+
+/***************************/
+/* S T A T I C D A T A */
+/***************************/
+static fosa_abs_time_t start_time;
+static bool timer_expired;
+
+fosa_clock_id_t group_clock_id;
+
+int main ()
+{
+ int err = -1;
+
+ fosa_thread_id_t tid_A, tid_B, tid_C, tid_catcher;
+ my_thread_arg_t thread_arg_A, thread_arg_B, thread_arg_C;
+ fosa_rel_time_t eat_time_A, eat_time_B, eat_time_C, group_time;
+ fosa_signal_info_t siginfo_A, siginfo_B, siginfo_C, siginfo_timer;
+
+ fosa_thread_set_id_t thread_set_id;
+ fosa_timer_id_t group_timer;
+
+ /* Initialize base time and thread arguments */
+ /*********************************************/
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, &start_time);
+
+ strcpy(thread_arg_A.identifier, "THREAD A");
+ thread_arg_A.signum = SIGNAL_A;
+ thread_arg_A.sigkill = SIGNAL_KILL_A;
+ siginfo_A.sival_ptr = &eat_time_A;
+
+ strcpy(thread_arg_B.identifier, "THREAD B");
+ thread_arg_B.signum = SIGNAL_B;
+ thread_arg_B.sigkill = SIGNAL_KILL_B;
+ siginfo_B.sival_ptr = &eat_time_B;
+
+ strcpy(thread_arg_C.identifier, "THREAD C");
+ thread_arg_C.signum = SIGNAL_C;
+ thread_arg_C.sigkill = SIGNAL_KILL_C;
+ siginfo_C.sival_ptr = &eat_time_C;
+
+
+ /* We set our priority and create the threads. The threads */
+ /* will be blocked waiting for the signal. */
+ /************************************************************/
+ err = fosa_thread_set_prio(fosa_thread_self(), fosa_get_priority_min() + PRIO_MAIN);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d with setting main priority\n", err);
+ exit(1);
+ }
+
+ create_thread(controlled_thread, &thread_arg_A, PRIO_A, &tid_A);
+ create_thread(controlled_thread, &thread_arg_B, PRIO_B, &tid_B);
+ create_thread(controlled_thread, &thread_arg_C, PRIO_C, &tid_C);
+
+ create_thread(catcher_thread, NULL, PRIO_CATCHER, &tid_catcher);
+
+
+ /* We create the thread set, get its clock and create a timer */
+ /****************************************************************/
+ err = fosa_thread_set_create(&thread_set_id);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d creating thread_set\n", err);
+ exit(1);
+ }
+
+ err = fosa_get_groupcpu_clock(thread_set_id, &group_clock_id);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d obtaining group clock\n", err);
+ exit(1);
+ }
+
+ err = fosa_timer_create(group_clock_id, SIGNAL_TIMER, siginfo_timer, &group_timer);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d obtaining group CPU timer\n", err);
+ exit(1);
+ }
+
+ /* We add the 3 threads to the set */
+ /*************************************/
+ err = fosa_thread_set_add(thread_set_id, tid_A);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d adding thread to thread set\n", err);
+ exit(1);
+ }
+
+ err = fosa_thread_set_add(thread_set_id, tid_B);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d adding thread to thread set\n", err);
+ exit(1);
+ }
+
+ err = fosa_thread_set_add(thread_set_id, tid_C);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d adding thread to thread set\n", err);
+ exit(1);
+ }
+
+
+ /* First experiment: We arm the group CPU timer with 5 sec and */
+ /* make each thread execute two seconds each. */
+ /****************************************************************/
+ eat_time_A = fosa_msec_to_rel_time(2000);
+ eat_time_B = fosa_msec_to_rel_time(2000);
+ eat_time_C = fosa_msec_to_rel_time(2000);
+
+ group_time = fosa_msec_to_rel_time(5000);
+
+ timer_expired = false;
+ time_printf("MAIN: Arming group timer for 5 seconds\n");
+ err = fosa_rel_timer_arm(group_timer, &group_time);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d queueing signal\n", err);
+ exit(1);
+ }
+
+ err = fosa_signal_queue(SIGNAL_A, siginfo_A, (fosa_thread_id_t) 0);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d queueing signal\n", err);
+ exit(1);
+ }
+
+ err = fosa_signal_queue(SIGNAL_B, siginfo_B, (fosa_thread_id_t) 0);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d queueing signal\n", err);
+ exit(1);
+ }
+
+ err = fosa_signal_queue(SIGNAL_C, siginfo_C, (fosa_thread_id_t) 0);
+ if (err != 0)
+ {
+ printf("MAIN: Error %d queueing signal\n", err);
+ exit(1);
+ }
+
+ struct timespec t = {2,0};
+ nanosleep (&t, NULL);
+ time_printf("MAIN: Back after all threads\n");
+
+ assert(timer_expired);
+
+
+ return 0;
+}
+
+
+
+
+
+// ----------------------------------------------------------------
+
+/**
+ * This is a controlled thread. It stays waiting for a signal and
+ * then eats the requested time sent in the signal info.
+ **/
+static void *controlled_thread(void *arg)
+{
+
+ fosa_signal_t signal_set[2];
+ int err;
+
+ my_thread_arg_t *thread_arg = (my_thread_arg_t *) arg;
+
+ time_printf("%s: Initializing\n", thread_arg->identifier);
+
+ signal_set[0] = thread_arg->signum;
+ signal_set[1] = thread_arg->sigkill;
+ err = fosa_set_accepted_signals(signal_set, 2);
+ if (err !=0)
+ {
+ printf ("%s: Error %d while setting the signal mask\n", thread_arg->identifier, err);
+ exit (1);
+ }
+
+ while(1)
+ {
+ fosa_signal_t signal_received;
+ fosa_signal_info_t info_received;
+ my_signal_info_t *signal_info;
+
+ err = fosa_signal_wait(signal_set, 2, &signal_received, &info_received);
+ if ( err != 0)
+ {
+ printf("%s: Error %d while waiting for signal\n", thread_arg->identifier, err);
+ exit(1);
+ }
+
+ if (signal_received == thread_arg->sigkill)
+ {
+ time_printf("%s: Terminating\n", thread_arg->identifier);
+ break;
+ }
+
+ signal_info = (my_signal_info_t *) info_received.sival_ptr;
+
+ time_printf("%s: about to eat %ld msec\n", thread_arg->identifier, fosa_rel_time_to_msec(signal_info->eat_time) );
+
+ fosa_eat(&signal_info->eat_time);
+ }
+
+ return NULL;
+}
+
+// ------------------------------------------------------------------
+
+static void *catcher_thread(void *arg)
+{
+ int err = -1;
+ fosa_signal_t signal_set[1];
+
+ time_printf("CATCHER: Initializing\n");
+
+ signal_set[0] = SIGNAL_TIMER;
+ err = fosa_set_accepted_signals(signal_set, 1);
+ if (err !=0)
+ {
+ printf ("CATCHER: Error %d while setting the signal mask\n", err);
+ exit (1);
+ }
+
+ while(1)
+ {
+ fosa_signal_t signal_received;
+ fosa_signal_info_t info_received;
+
+ err = fosa_signal_wait(signal_set, 1, &signal_received, &info_received);
+ if ( err != 0)
+ {
+ printf("CATCHER: Error %d while waiting for signal\n", err);
+ exit(1);
+ }
+
+ time_printf("CATCHER: Group timer expired!!!\n");
+ timer_expired = true;
+ }
+
+ return NULL;
+}
+
+
+// ------------------------------------------------------------------------
+
+static void create_thread(fosa_thread_code_t thread_code,
+ void *arg,
+ int priority,
+ fosa_thread_id_t *tid)
+{
+ fosa_thread_attr_t attr;
+ int err;
+
+ err = fosa_thread_attr_init(&attr);
+ if (err != 0) {
+ printf("Error %d while initializing the attr\n", err);
+ exit(1);
+ }
+
+ err = fosa_thread_attr_set_prio(&attr, fosa_get_priority_min() + priority);
+ if (err != 0) {
+ printf("Error %d while setting priority\n", err);
+ exit(1);
+ }
+
+ err = fosa_thread_create(tid, &attr, thread_code, arg);
+ if (err) {
+ printf("Error %d in fosa_thread_create\n", err);
+ exit(1);
+ }
+}
+
+
+
+// ------------------------------------------------------------------------
+
+
+static void time_printf(const char *format, ...)
+{
+ va_list args;
+
+ fosa_abs_time_t current_time;
+ fosa_rel_time_t interval;
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time);
+ interval = fosa_abs_time_extract_interval(start_time, current_time);
+
+ printf("%ld:", fosa_rel_time_to_msec(interval));
+
+ va_start(args, format);
+ vprintf(format, args);
+ va_end(args);
+}
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include <fosa_long_jump.h>
+#include <fosa_threads_and_signals.h>
+#include <stdio.h>
+#include <assert.h>
+
+void f1 (void)
+{
+ fosa_long_jump_context_t ctx;
+ fosa_signal_t sig;
+ fosa_thread_id_t th;
+ int jmp;
+ fosa_signal_info_t ctx_info;
+ sigset_t s;
+
+ pthread_sigmask (SIG_SETMASK, NULL, &s);
+ printf (">>> Current signal mask = 0x%x\n", (unsigned int) s.sig);
+
+ assert (fosa_long_jump_save_context (NULL));
+
+ printf (">>> save context\n\n");
+ if (fosa_long_jump_save_context (&ctx)) {
+ printf ("fosa_long_jump_save_context");
+ exit (-1);
+ }
+
+ printf (">>> check jump performed\n\n");
+ if (fosa_long_jump_was_performed ((const fosa_long_jump_context_t *) &ctx, &jmp)) {
+ printf ("fosa_long_jump_was_performed");
+ exit (-2);
+ }
+
+ if (jmp) {
+ printf ("\t <<<< JUMPED\n\n");
+ pthread_sigmask (SIG_SETMASK, NULL, &s);
+ printf (">>> Current signal mask = 0x%x\n",(unsigned int) s.sig);
+ exit (10);
+ }
+
+ printf (">>> install handler\n\n");
+ if (fosa_long_jump_install_handler (&sig, &th)) {
+ printf ("fosa_long_jump_install_handler()");
+ exit (-3);
+ }
+
+ printf ("\t signal=%d, thread=0x%x (self=0x%x)\n", sig, (unsigned int) th, (unsigned int) fosa_thread_self());
+
+ printf (">>> trigger a long jump using a signal\n\n");
+ ctx_info.sival_ptr = &ctx;
+ if (fosa_signal_queue (sig, ctx_info, th)) {
+ printf ("fosa_signal_queue");
+ exit (-4);
+ }
+}
+
+
+int main (void)
+{
+ sigset_t s;
+
+ sigemptyset (&s);
+ sigaddset (&s, SIGRTMIN);
+ sigaddset (&s, SIGRTMAX);
+ pthread_sigmask (SIG_SETMASK, &s, NULL);
+
+ f1 ();
+ return 0;
+}
+
--- /dev/null
+RTLINUX_PATH=../../../rtlinux-3.2-rc1/trunk
+
+OBJS=fosa_app_def_sched.o fosa_mutexes_and_condvars.o fosa_clocks_and_timers.o fosa_threads_and_signals.o fosa_misc.o pow.o exp.o
+#fosa_app_def_sched.o fosa_mutexes_and_condvars.o fosa_clocks_and_timers.o fosa_threads_and_signals.o
+
+FOSA_INC=../include
+FRSH_INC=../../../frsh/trunk/include
+
+all: libfosa.a
+
+NAME=libfosa_RT_LINUX.a
+
+include $(RTLINUX_PATH)/rtl.mk
+
+CFLAGS+=-I$(FOSA_INC) -I$(FRSH_INC) -DRT_LINUX
+
+libfosa.a: $(OBJS)
+ $(AR) -r $(NAME) $(OBJS)
+ cp $(NAME) ../lib
+
+test_fosa_c.o: test_fosa.o
+ ld -r -o test_fosa_c.o test_fosa.o $(NAME)
+
+test_fosa.o: test_fosa.c
+
+clean:
+ $(RM) -f *.o *~ *.a
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_app_def_sched.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include <fosa.h>
+#include <rtl.h>
+//#include <rtl_sched.h>
+#include <rtl_malloc.h>
+
+/********************************
+ * Application-defined scheduling
+ ********************************/
+
+
+extern fosa_ads_scheduler_ops_t fosa_scheduler_operations; // See rtl_appsched.c
+extern void *fosa_scheduler_loop(void *arg); // See rtl_appsched.c
+extern void *fosa_scheduler_args;
+extern int fosa_scheduler_args_size;
+
+
+int fosa_ads_scheduler_create (const fosa_ads_scheduler_ops_t * scheduler_ops,
+ size_t scheduler_data_size,
+ void * init_args,
+ size_t init_args_size){
+ struct sched_param sched_param;
+ pthread_attr_t attr;
+ int ret;
+
+ // There will be only ONE single ADS scheduler facility in the system
+ fosa_scheduler_args_size=init_args_size;
+ fosa_scheduler_args=rtl_malloc(init_args_size);
+ if (!fosa_scheduler_args) {
+ rtl_printf("ERROR: fosa_ads_scheduler_create, rtl_mallox failed\n");
+ return -1;
+ }
+ memcpy((unsigned char *)fosa_scheduler_args,
+ (unsigned char *)init_args, init_args_size);
+
+ fosa_scheduler_operations = *scheduler_ops;
+
+ pthread_attr_init (&attr);
+ sched_param.sched_priority=100; // Only one priority will be
+ // used in the system.
+ pthread_attr_setappschedulerstate(&attr, PTHREAD_APPSCHEDULER);
+ pthread_attr_setschedparam (&attr, &sched_param);
+
+ ret=pthread_create(&fosa_scheduler_thread, &attr,
+ fosa_scheduler_loop, NULL);
+ return ret;
+}
+
+
+
+int fosa_thread_attr_set_appscheduled (frsh_thread_attr_t *attr,
+ bool appscheduled){
+ if (attr){
+ if (appscheduled)
+ attr->policy=SCHED_APP;
+ else
+ attr->policy=SCHED_FIFO;
+ return 0;
+ }
+ else return EINVAL;
+}
+
+int fosa_thread_attr_get_appscheduled (const frsh_thread_attr_t *attr,
+ bool *appscheduled){
+ if (attr){
+ if (attr->policy==SCHED_APP)
+ *appscheduled=true;
+ else
+ *appscheduled=false;
+ return 0;
+ }
+ else return EINVAL;
+}
+
+int fosa_thread_attr_set_appsched_params (frsh_thread_attr_t *attr,
+ const void *param,
+ size_t paramsize){
+ return pthread_attr_setappschedparam(attr, (void *)param, paramsize);
+}
+
+int fosa_thread_attr_get_appsched_params (const frsh_thread_attr_t *attr,
+ void *param,
+ size_t *paramsize){
+ return pthread_attr_getappschedparam((frsh_thread_attr_t *)attr, param, paramsize);
+}
+
+int fosa_ads_set_appscheduled (frsh_thread_id_t thread,
+ bool appscheduled){
+ pthread_t sched=(appscheduled)?fosa_scheduler_thread:0;
+
+ return (!pthread_setappscheduler(thread, sched))?0:EINVAL;
+}
+
+int fosa_ads_get_appscheduled (frsh_thread_id_t thread,
+ bool *appscheduled){
+ if (thread) {
+ *appscheduled=(appscheduler(thread))?1:0;
+ return 0;
+ }
+ return EINVAL;
+}
+
+int fosa_ads_set_appschedparam (frsh_thread_id_t thread,
+ const void *param,
+ size_t paramsize){
+ return (!pthread_setappschedparam(thread, (void *)param, paramsize))?0:EINVAL;
+}
+
+int fosa_ads_get_appsched_params (frsh_thread_id_t thread,
+ void *param,
+ size_t *paramsize){
+ return (!pthread_getappschedparam(thread, param, paramsize))?0:EINVAL;
+}
+
+int fosa_ads_set_appsched_params (frsh_thread_id_t thread,
+ const void *param,
+ size_t paramsize){
+ return (!pthread_setappschedparam(thread, (void *)param, paramsize))?0:EINVAL;
+}
+
+/*********************************
+ * ADS actions
+ *
+ * A scheduling actions object is used to specify a series of actions
+ * to be performed by the system at the end of a scheduler primitive
+ * operation. The order of the actions added to the object shall be
+ * preserved.
+ *
+ *********************************/
+
+int fosa_adsactions_add_reject(fosa_ads_actions_t *sched_actions,
+ frsh_thread_id_t thread){
+ return posix_appsched_actions_addreject(sched_actions, thread);
+}
+
+int fosa_adsactions_add_activate(fosa_ads_actions_t *sched_actions,
+ frsh_thread_id_t thread,
+ fosa_ads_urgency_t urgency){
+ RTL_PRIO(thread)=set_urgency(thread, urgency);
+ return posix_appsched_actions_addactivate(sched_actions, thread);
+}
+
+int fosa_adsactions_add_suspend(fosa_ads_actions_t *sched_actions,
+ frsh_thread_id_t thread){
+ return posix_appsched_actions_addsuspend (sched_actions, thread);
+}
+
+extern timer_t fosa_timeout_timer; // defined in rtl_fosa.c
+int fosa_adsactions_add_timeout(fosa_ads_actions_t *sched_actions,
+ fosa_clock_id_t clock_id,
+ const struct timespec *at_time){
+ struct sigevent signal;
+ struct itimerspec at_itimer= (struct itimerspec)
+ {.it_interval=(struct timespec){0,0},
+ .it_value=*at_time};
+
+ if (fosa_timeout_timer)
+ return EINVAL;
+
+ signal.sigev_signo=0;
+ signal.sigev_notify=SIGEV_NONE;
+
+ timer_create(clock_id, &signal, &fosa_timeout_timer);
+ timer_settime(fosa_timeout_timer, 0, &at_itimer, 0);
+ return 0;
+}
+
+
+int fosa_adsactions_add_thread_notification(fosa_ads_actions_t *sched_actions,
+ frsh_thread_id_t thread,
+ fosa_clock_id_t clock_id,
+ const struct timespec *at_time){
+ struct sigevent signal;
+ struct itimerspec at_itimer= (struct itimerspec)
+ {.it_interval=(struct timespec){0,0},
+ .it_value=*at_time};
+
+ if (fosa_timeout_timer)
+ return EINVAL;
+
+ signal.sigev_value.sival_ptr=(void *)clock_id;
+ signal.sigev_signo=(int)thread;
+ signal.sigev_notify=SIGEV_NONE;
+
+ timer_create(clock_id, &signal, &fosa_timeout_timer);
+ timer_settime(fosa_timeout_timer, 0, &at_itimer, 0);
+ return 0;
+}
+extern rtl_sigset_t fosa_scheduler_signal_bitmap; // as declared in rtl_fosa.c
+
+int fosa_ads_set_handled_signal_set(frsh_signal_t set[], int size){
+ int x;
+
+ rtl_sigemptyset(&fosa_scheduler_signal_bitmap);
+ for (x=0; x<size; x++)
+ rtl_sigaddset(&fosa_scheduler_signal_bitmap, set[x]);
+ return 0;
+}
+
+
+int fosa_ads_invoke_withdata (const void *msg, size_t msg_size,
+ void *reply, size_t *reply_size){
+ return posix_appsched_invoke_withdata((void *)msg, msg_size, reply, reply_size);
+}
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include <fosa.h>
+
+/*************************
+ * Timing: Clocks
+ *************************/
+
+int fosa_clock_get_time(fosa_clock_id_t clockid,
+ struct timespec *current_time){
+ return clock_gettime(clockid, current_time);
+}
+
+int fosa_thread_get_cputime_clock(frsh_thread_id_t tid,
+ fosa_clock_id_t *clockid){
+ return pthread_getcpuclockid(tid, clockid);
+}
+
+
+/*************************
+ * Timing: Timers
+ *************************/
+
+int fosa_timer_create(fosa_clock_id_t clockid,
+ frsh_signal_t signal,
+ frsh_signal_info_t info,
+ fosa_timer_id_t *timerid){
+ struct sigevent event;
+
+ event.sigev_notify = SIGEV_SIGNAL;
+ event.sigev_signo = signal;
+ // event.sigev_value = info;
+
+ return timer_create(clockid, &event, timerid);
+}
+
+
+int fosa_timer_delete(fosa_timer_id_t timerid){
+ timer_delete(timerid);
+ return 0;
+}
+
+
+int fosa_timer_arm (fosa_timer_id_t timerid,
+ bool abstime,
+ const struct timespec *value){
+
+ struct itimerspec when;
+
+ when.it_value = *value; // Just one shot.
+ when.it_interval.tv_sec = 0; // Not periodic behaviour.
+ when.it_interval.tv_nsec = 0;
+
+ return timer_settime(timerid, abstime , &when, NULL);
+}
+
+int fosa_timer_get_remaining_time(fosa_timer_id_t timerid, struct timespec *remaining_time) {
+
+ if (TIMER_ARMED(timerid)) {
+ (*remaining_time)=timespec_from_ns((long long)(timerid->expires.it_value - clock_gethrtime(timerid->clock_id)));
+ } else
+ return -1;
+
+ return 0;
+}
+
+int fosa_timer_disarm(fosa_timer_id_t timerid, struct timespec *remaining_time){
+ struct itimerspec when;
+
+ if (remaining_time && TIMER_ARMED(timerid)) {
+ (*remaining_time)=
+ timespec_from_ns((long long)(timerid->expires.it_value - clock_gethrtime(timerid->clock_id)));
+ }
+
+ when.it_value.tv_sec = 0;
+ when.it_value.tv_nsec = 0;
+ when.it_interval = when.it_value; // Not needed but safe.
+
+ return timer_settime(timerid, TIMER_ABSTIME , &when, NULL);
+}
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_misc.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+//#include <fosa.h>
+#include <stdarg.h>
+
+extern int vsprintf(char *str, const char *format, va_list ap);
+extern void rtl_printf(const char *format, ...);
+typedef int size_t;
+
+static char vsprintf_buffer[512];
+
+int vprintf(const char *fmt, va_list ap) {
+ int i=vsprintf(vsprintf_buffer, fmt, ap);
+ rtl_printf(vsprintf_buffer);
+ return i;
+}
+
+int printf(const char *fmt,...) {
+ int i;
+ va_list args;
+
+ va_start(args, fmt);
+ i=vsprintf(vsprintf_buffer, fmt, args);
+ va_end(args);
+ rtl_printf(vsprintf_buffer);
+ return i;
+}
+
+typedef unsigned long FILE;
+
+FILE stdout=2;
+
+int vfprintf(FILE *stream, const char *fmt, va_list ap) {
+ int i=vsprintf(vsprintf_buffer, fmt, ap);
+ rtl_printf(vsprintf_buffer);
+ return i;
+}
+
+static void *memccpy(void *dst, const void *src, int c, int count)
+{
+ char *a = dst;
+ const char *b = src;
+ while (count--)
+ {
+ *a++ = *b;
+ if (*b==c)
+ {
+ return (void *)a;
+ }
+ b++;
+ }
+ return 0;
+}
+
+char *strncpy(char *dest, const char *src, size_t n) {
+ memccpy(dest,src,0,n);
+ return dest;
+}
+
+int strncmp(const char *s1, const char *s2, size_t n) {
+ const unsigned char* a=(const unsigned char*)s1;
+ const unsigned char* b=(const unsigned char*)s2;
+ const unsigned char* fini=a+n;
+ while (a<fini) {
+ int res=*a-*b;
+ if (res) return res;
+ if (!*a) return 0;
+ ++a; ++b;
+ }
+ return 0;
+}
+
+int puts(const char *s) {
+ rtl_printf(s);
+ return 0;
+}
+
+typedef signed long time_t;
+extern long long gethrtime(void);
+time_t time(time_t *t) {
+ time_t sec;
+ long long nsec;
+
+ nsec=gethrtime();
+ sec=(time_t)(nsec/1000000000LL);
+ if (t)
+ *t=sec;
+ return sec;
+}
+
+#define NSECS 1000000000LL
+struct timespec {
+ time_t tv_sec; /* seconds */
+ long tv_nsec; /* nanoseconds */
+};
+
+extern int nanosleep(const struct timespec *req, struct timespec *rem);
+
+unsigned int sleep(unsigned int seg) {
+ struct timespec req={
+ .tv_sec=seg%NSECS,
+ .tv_nsec=seg/NSECS,
+ }, rem;
+ nanosleep(&req, &rem);
+ return rem.tv_sec;
+}
+
+void exit(int val) {
+ struct timespec req={
+ .tv_sec=1000,
+ .tv_nsec=1000000,
+ };
+ rtl_printf ("Application exited with %d\n", val);
+ while(1) {
+ nanosleep(&req, 0);
+ }
+}
+
+void __assert_fail (const char *assertion, const char *file,
+ unsigned int line, const char *function) {
+ rtl_printf("Assertion `%s` FILE: %s LINE: %d FUNCTION: %s failed.\n",
+ assertion, file, line, function);
+ exit(-1);
+}
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_mutexes_and_condvars.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include <fosa.h>
+
+// header files from rtlinux
+#include <rtl_mutex.h>
+
+
+/*******************************************************
+ * Mutexes with priority ceiling
+ ******************************************************/
+
+
+int fosa_mutex_init(frsh_mutex_t *mutex, int prioceiling){
+ pthread_mutexattr_t attr;
+ attr.prioceiling=prioceiling;
+ return pthread_mutex_init(mutex, &attr);
+}
+
+int fosa_mutex_destroy(frsh_mutex_t *mutex){
+ return pthread_mutex_destroy(mutex);
+}
+
+int fosa_mutex_set_prioceiling (frsh_mutex_t *mutex,
+ int new_ceiling,
+ int *old_ceiling){
+ return pthread_mutex_setprioceiling(mutex, new_ceiling, old_ceiling);
+}
+
+int fosa_mutex_get_prioceiling(const frsh_mutex_t *mutex, int *ceiling){
+ return pthread_mutex_getprioceiling(mutex, ceiling);
+}
+
+int fosa_mutex_lock(frsh_mutex_t *mutex){
+ return pthread_mutex_lock(mutex);
+}
+
+int fosa_mutex_trylock(frsh_mutex_t *mutex){
+ return pthread_mutex_trylock(mutex);
+}
+
+int fosa_mutex_unlock(frsh_mutex_t *mutex){
+ return pthread_mutex_unlock(mutex);
+}
+
+/**********************
+ * Condition variables
+ *********************/
+
+int fosa_cond_init(fosa_cond_t *cond){
+ return pthread_cond_init(cond, NULL);
+}
+
+int fosa_cond_destroy(fosa_cond_t *cond){
+ return pthread_cond_destroy(cond);
+}
+
+int fosa_cond_signal(fosa_cond_t *cond){
+ return pthread_cond_signal(cond);
+}
+
+int fosa_cond_broadcast(fosa_cond_t *cond){
+ return pthread_cond_broadcast(cond);
+}
+
+int fosa_cond_wait(fosa_cond_t *cond, frsh_mutex_t *mutex){
+ return pthread_cond_wait(cond, mutex);
+}
+
+int fosa_cond_timedwait(fosa_cond_t *cond,
+ frsh_mutex_t *mutex,
+ const struct timespec *abstime){
+ return pthread_cond_timedwait(cond, mutex, abstime);
+}
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include <fosa.h>
+#include <asm/bitops.h>
+
+/*************************
+ * Thread identification
+ *************************/
+
+bool fosa_thread_equal(frsh_thread_id_t t1, frsh_thread_id_t t2){
+ return pthread_equal(t1,t2);
+}
+
+frsh_thread_id_t fosa_thread_self(){
+ return pthread_self();
+}
+
+/*************************
+ * Thread creation and termination
+ *************************/
+
+int fosa_thread_create (frsh_thread_id_t *tid, const frsh_thread_attr_t *attr,
+ frsh_thread_code_t code, void * arg){
+ return pthread_create(tid,attr,code, arg);
+}
+
+int fosa_key_create(int *key) {
+ int idx=ffs(pthread_self()->tsd_bitmap);
+
+ if (idx<0)
+ return -FOSA_EINVAL;
+
+ pthread_self()->tsd_bitmap&=~(1<<idx);
+
+ *key=idx;
+ return 0;
+}
+
+int fosa_key_destroy(int key) {
+ pthread_self()->tsd_bitmap|=(1<<key);
+ return 0;
+}
+
+
+/**************************************************
+ * Thread-specific data
+ * (extended with access from a different thread)
+ *
+ * Several data items (pointers) may be associated with each thread
+ * Each item is identified through a key, an integer value between 0
+ * and FOSA_MAX_KEYS-1. The caller is responsible of allocating and
+ * deallocating the memory area pointed to by the pointer
+ **************************************************/
+
+int fosa_thread_set_specific_data (int key, frsh_thread_id_t tid,
+ const void * value){
+ if ((0<key) && (key<FOSA_MAX_KEYS-1)){
+ tid->tsd[key] = (void *) value;
+ return 0;
+ }
+ return EINVAL;
+}
+
+int fosa_thread_get_specific_data(int key, frsh_thread_id_t tid,
+ void ** value){
+ if ((0<key) && (key<FOSA_MAX_KEYS-1)){
+ //*value=pthread_remote_getspecific(key,tid);
+ *value=tid->tsd[key];
+ return 0;
+ }
+ return EINVAL;
+
+}
+
+
+/******************************************************************
+ * Thread scheduling
+ *
+ * This implementation of FRSH assumes an underlying fixed priority
+ * scheduler with priorities in a range, with a minimum and a
+ * maximumm, a number of priority levels with at least 31
+ * priorities. A larger number implies a larger priority. In systems
+ * in which the underlying scheduler uses the opposite convention, a
+ * mapping is automatically provided by the OS adaptation layer.
+ *******************************************************************/
+
+int fosa_get_priority_max() {
+ return sched_get_priority_max(0);
+}
+
+int fosa_get_priority_min(){
+ return sched_get_priority_min(0);
+}
+
+int fosa_thread_attr_set_prio(frsh_thread_attr_t *attr, int prio) {
+ if ((sched_get_priority_min(0)<=prio) || (prio<=sched_get_priority_min(0))){
+ attr->sched_param.sched_priority = prio;
+ return 0;
+ }
+ return EINVAL;
+}
+
+int fosa_thread_attr_get_prio (const frsh_thread_attr_t *attr, int *prio){
+ *prio = attr->sched_param.sched_priority;
+ return 0;
+}
+
+int fosa_thread_set_prio(frsh_thread_id_t tid, int prio){
+ if ((sched_get_priority_min(0)<=prio) || (prio<=sched_get_priority_min(0))){
+ pthread_setschedprio(tid,prio);
+ return 0;
+ }
+ return EINVAL;
+}
+
+int fosa_thread_get_prio (frsh_thread_id_t tid, int *prio){
+ *prio = tid->sched_param.sched_priority;
+ return 0;
+}
+
+
+
+/*******************************************************************
+ * Signals
+ *
+ * Signals represent events that may be notified by the system, or
+ * sent explicitly by the application, and for which a thread may
+ * synchronously wait. Signals carry an associated piece of
+ * information (an integer or a pointer) and are queued until they are
+ * accepted. Signals are identified by an integer signal number (of
+ * the type frsh_signal_t) in the range FOSA_SIGNAL_MIN,
+ * FOSA_SIGNAL_MAX. This range is required to have at least <tbd>
+ * values.
+ *******************************************************************/
+
+int fosa_set_accepted_signals(frsh_signal_t set[], int size) {
+ int x;
+ rtl_sigset_t bitset;
+
+ rtl_sigfillset(&bitset); // By default all signals will be blocked.
+ for (x=0; x<size; x++)
+ rtl_sigdelset(&bitset, set[x]); // Unblock the "set" of signals.
+
+ return pthread_sigmask(SIG_SETMASK, &bitset, NULL);
+}
+
+
+int fosa_signal_queue (frsh_signal_t signal, frsh_signal_info_t info,
+ frsh_thread_id_t receiver){
+ union sigval value;
+
+ value.sival_ptr=info.sival_ptr;
+ return sigqueue(0, signal, value);
+}
+
+int fosa_signal_queue_scheduler(frsh_signal_t signal, frsh_signal_info_t info) {
+ union posix_appsched_eventinfo eventinfo;
+ eventinfo.sig.signo=signal;
+ eventinfo.sig.siginfo= (siginfo_t){info.sival_int};
+ generate_event(pthread_self(), fosa_scheduler_thread,
+ POSIX_APPSCHED_SIGNAL, &eventinfo,
+ sizeof(union posix_appsched_eventinfo));
+ rtl_schedule();
+ return 0;
+}
+
+int fosa_signal_wait (frsh_signal_t set[], int size, frsh_signal_t *signal_received,
+ frsh_signal_info_t *info){
+ int x;
+ rtl_sigset_t bitset;
+ siginfo_t __info;
+
+ rtl_sigemptyset(&bitset); // No signals to wait for;
+ for (x=0; x<size; x++)
+ rtl_sigaddset(&bitset, set[x]); // Add to the set of signals to be waited for.
+ sigwaitinfo(&bitset, &__info);
+ *signal_received=__info.si_signo;
+ //*info = __info.si_value.sival_ptr;
+ return 0;
+}
+
+int fosa_signal_timedwait (frsh_signal_t set[], int size, frsh_signal_t *signal_received, frsh_signal_info_t *info, const struct timespec *timeout){
+
+
+ int x;
+ rtl_sigset_t bitset;
+ siginfo_t __info;
+
+ rtl_sigemptyset(&bitset); // No signals to wait for;
+ for (x=0; x<size; x++)
+ rtl_sigaddset(&bitset, set[x]); // Add to the set of signals to be waited for.
+ sigtimedwait(&bitset, &__info, timeout);
+
+ *signal_received=__info.si_signo;
+// *info = __info.si_value.sival_ptr;
+ return 0;
+}
+
+int frsh_thread_attr_init(frsh_thread_attr_t *attr) {
+ return pthread_attr_init(attr);
+}
+
+int frsh_thread_attr_destroy(frsh_thread_attr_t *attr) {
+ return pthread_attr_destroy(attr);
+}
+
+int frsh_thread_attr_set_stacksize(frsh_thread_attr_t *attr,
+ size_t stacksize) {
+ return pthread_attr_setstacksize(attr, stacksize);
+}
+
+int frsh_thread_attr_get_stacksize (const frsh_thread_attr_t *attr, size_t *stacksize) {
+ return pthread_attr_getstacksize(attr, stacksize);
+}
--- /dev/null
+#include "fosa_threads_and_signals.h"
+#include "fosa_clocks_and_timers.h"
+#include "fosa_mutexes_and_condvars.h"
+#include "fosa_app_def_sched.h"
+#include <rtl.h>
+//#include <unistd.h>
+//#include <stdio.h>
+//#include <time.h> // for nanosleep
+
+
+#define printf rtl_printf
+void * thread_code(void *arg) {
+ struct timespec req={.tv_sec=1, .tv_nsec=0};
+ printf("Thread executing\n");
+ nanosleep(&req, 0);
+ printf("Thread terminating\n");
+ return NULL;
+}
+
+/////////////////////////////////////////////////////////////
+// Simple test program for FOSA
+//
+// It just checks that the different functions can be called
+// and that they return appropriate values
+/////////////////////////////////////////////////////////////
+
+void *main_app(void *args) {
+ //////////////////////////////////
+ // Test clock functions
+ //////////////////////////////////
+
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FOSA (Frsh Operating System Adaption)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+ printf("test thread ids and thread creation\n");
+
+ int stsize, prio;
+ struct timespec req={.tv_sec=2, .tv_nsec=0};
+ frsh_thread_id_t tid1=fosa_thread_self();
+ frsh_thread_id_t tid2=fosa_thread_self();
+ printf("equal thread comparison=%d\n",fosa_thread_equal(tid1,tid2));
+
+ frsh_thread_attr_t th_attr;
+
+ err=frsh_thread_attr_init(&th_attr);
+ printf("thread attributes object initialized, err=%d\n",err);
+
+ err=frsh_thread_attr_set_stacksize(&th_attr,40000);
+ printf("thread attr set stack size to 40000, err=%d\n",err);
+
+ err=frsh_thread_attr_get_stacksize(&th_attr,&stsize);
+ printf("thread attr get stack size=%d, err=%d\n",stsize,err);
+
+ err=fosa_thread_attr_set_prio(&th_attr,27);
+ printf("thread attr set prio to 27, err=%d\n",err);
+
+ err=fosa_thread_attr_get_prio(&th_attr,&prio);
+ printf("thread attr get prio=%d, err=%d\n",prio,err);
+
+ err=fosa_thread_create (&tid2, &th_attr, thread_code, NULL);
+ printf("creating thread with default attributes err=%d\n",err);
+
+ nanosleep(&req,0);
+
+ err=frsh_thread_attr_destroy(&th_attr);
+ printf("thread attributes object destroyed, err=%d\n",err);
+
+ //////////////////////////////////
+ // Test signals
+ //////////////////////////////////
+
+ printf("--------------------------------------------------\n");
+ printf("test signals\n");
+
+ frsh_signal_t received;
+ frsh_signal_info_t sigvalue, value_received;
+ struct timespec timeout;
+ frsh_signal_t sig=FOSA_SIGNAL_MIN+1;
+ frsh_signal_t timer_sig=FOSA_SIGNAL_MIN+3;
+ frsh_signal_t siglist[2];
+
+ siglist[0]=sig;
+ siglist[1]=timer_sig;
+
+ timeout.tv_sec=1;
+ timeout.tv_nsec=0;
+
+ sigvalue.sival_int=55;
+
+ err=fosa_set_accepted_signals(siglist,2);
+ printf("two signals in set of accepted signals, err=%d\n",err);
+
+ err=fosa_signal_timedwait(siglist,1,&received,&value_received,&timeout);
+ printf("timed wait not implemented; timeoutcode=%d\n",err);
+
+ err=fosa_signal_queue(sig, sigvalue,fosa_thread_self());
+ printf("signal queued with value 55, err=%d\n",err);
+
+ err=fosa_signal_wait(siglist,1,&received, &value_received);
+ printf("timeoutcode=%d signal received=%d value=%d\n",
+ err,received,value_received.sival_int);
+
+
+ //////////////////////////////////
+ // Test timers and signals
+ //////////////////////////////////
+
+ printf("--------------------------------------------------\n");
+ printf("test timers and signals\n");
+
+ frsh_signal_info_t timer_info;
+ fosa_timer_id_t timerid;
+ struct timespec timerval, remaining_time;
+
+ timer_info.sival_int=88;
+ timerval.tv_sec=1;
+ timerval.tv_nsec=300000000;
+
+
+ err=fosa_timer_create
+ (FOSA_CLOCK_REALTIME, timer_sig, timer_info,&timerid);
+ printf("timer created, err=%d\n",err);
+
+ err=fosa_timer_arm(timerid,false,&timerval);
+ printf("timer armed for 1.3 secs, err=%d\n",err);
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time);
+ printf("current time sec=%d nsec=%d\n",
+ current_time.tv_sec, current_time.tv_nsec);
+ printf("wait for timer to expire...\n");
+
+ siglist[0]=timer_sig;
+ err=fosa_signal_wait(siglist,1,&received, &value_received);
+ printf("timeoutcode=%d signal received=%d value=%d\n",
+ err,received,value_received.sival_int);
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time);
+ printf("current time sec=%d nsec=%d\n",
+ current_time.tv_sec, current_time.tv_nsec);
+
+ timerval.tv_sec=6;
+ timerval.tv_nsec=0;
+ err=fosa_timer_arm(timerid,false,&timerval);
+ printf("timer armed for 6 secs, err=%d\n",err);
+
+ timerval.tv_sec=1;
+ printf("sleeping 1 second\n");
+ nanosleep(&timerval, NULL);
+
+ err=fosa_timer_get_remaining_time(timerid, &remaining_time);
+ printf("timer remaining time sec=%d nsec=%d, err=%d\n",
+ remaining_time.tv_sec, remaining_time.tv_nsec, err);
+
+ printf("sleeping 1 second\n");
+ nanosleep(&timerval, NULL);
+
+ err=fosa_timer_disarm(timerid,&remaining_time);
+ printf("timer disarmed, remaining time sec=%d nsec=%d, err=%d\n",
+ remaining_time.tv_sec, remaining_time.tv_nsec, err);
+
+ err=fosa_timer_get_remaining_time(timerid, &remaining_time);
+ printf("timer remaining time after disarm (0?) sec=%d nsec=%d, err=%d\n",
+ remaining_time.tv_sec, remaining_time.tv_nsec, err);
+
+ fosa_timer_delete(timerid);
+
+
+ //////////////////////////////////
+ // Test thread-specific data
+ //////////////////////////////////
+
+ printf("--------------------------------------------------\n");
+ printf("test thread-specific data\n");
+
+ int value=333;
+ int key;
+ frsh_thread_id_t tid=fosa_thread_self();
+
+ err=fosa_key_create(&key);
+ printf("key created=%d. err=%d\n",key,err);
+
+ fosa_thread_set_specific_data (key, tid, (void *) (&value));
+ printf("specific data set to 333. err=%d\n",err);
+
+ fosa_thread_get_specific_data (key, tid, &obtained);
+ printf("obtained thread specific data=%d\n",*((int *)obtained));
+
+
+ //////////////////////////////////
+ // Test Priorities
+ //////////////////////////////////
+
+ printf("--------------------------------------------------\n");
+ printf("test priorities\n");
+
+
+ err=fosa_thread_set_prio(fosa_thread_self(),14);
+ printf("priority set to 14. err=%d\n",err);
+
+ err=fosa_thread_get_prio(fosa_thread_self(),&prio);
+ printf("prio=%d. err=%d\n",prio,err);
+
+
+ //////////////////////////////////
+ // Test Mutexes
+ //////////////////////////////////
+
+ printf("--------------------------------------------------\n");
+ printf("test mutexes\n");
+
+ frsh_mutex_t lock;
+ int old;
+
+ err=fosa_mutex_init(&lock,24);
+ printf("mutex initialized with ceiling 24. err=%d\n",err);
+
+ err=fosa_mutex_set_prioceiling(&lock,24,&old);
+ printf("mutex priority ceiling changed to 24. old=%d. err=%d\n",old,err);
+
+ err=fosa_mutex_get_prioceiling(&lock,&old);
+ printf("mutex priority ceiling is=%d. err=%d\n",old,err);
+
+ err=fosa_mutex_lock(&lock);
+ printf("mutex locked. err=%d\n",err);
+
+ err=fosa_mutex_unlock(&lock);
+ printf("mutex unlocked. err=%d\n",err);
+
+ err=fosa_mutex_trylock(&lock);
+ printf("mutex try locked. err=%d\n",err);
+
+ err=fosa_mutex_unlock(&lock);
+ printf("mutex unlocked. err=%d\n",err);
+
+ //////////////////////////////////
+ // Test Condition variables
+ //////////////////////////////////
+
+ printf("--------------------------------------------------\n");
+ printf("test condition variables\n");
+
+ fosa_cond_t cond;
+
+ err=fosa_cond_init(&cond);
+ printf("condvar initialized. err=%d\n",err);
+
+ err=fosa_cond_signal(&cond);
+ printf("cond signalled. err=%d\n",err);
+
+ err=fosa_cond_broadcast(&cond);
+ printf("cond broadcast. err=%d\n",err);
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time);
+ printf("current time sec=%d nsec=%d\n",
+ current_time.tv_sec, current_time.tv_nsec);
+
+ current_time.tv_sec=current_time.tv_sec+2;
+
+ fosa_mutex_lock(&lock);
+ err=fosa_cond_timedwait(&cond,&lock,¤t_time);
+ fosa_mutex_unlock(&lock);
+ printf("cond timedwait with timeout=2 sec. err=%d\n",err);
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time);
+ printf("current time sec=%d nsec=%d\n",
+ current_time.tv_sec, current_time.tv_nsec);
+
+ err=fosa_mutex_destroy(&lock);
+ printf("mutex destroyed. err=%d\n",err);
+
+ err=fosa_cond_destroy(&cond);
+ printf("cond destroyed. err=%d\n",err);
+
+ ////////////////////////////////////////
+ // Test Application-defined scheduling
+ ///////////////////////////////////////
+ /*
+ printf("--------------------------------------------------\n");
+ printf("test application-defined scheduling\n");
+
+ frsh_thread_attr_t th1_attr;
+ bool is_appsched;
+
+ err=frsh_thread_attr_init(&th1_attr);
+ printf("thread attributes object initialized, err=%d\n",err);
+
+ err=fosa_thread_attr_set_appscheduled(&th1_attr,true);
+ printf("thread attr set appsched, err=%d\n",err);
+
+ err=fosa_thread_attr_get_appscheduled(&th1_attr,&is_appsched);
+ printf("thread attr get appsched=%d, err=%d\n",is_appsched,err);
+ */
+ return 0;
+
+}
+
+static pthread_t main_thread;
+
+int init_module (void) {
+ return pthread_create(&main_thread, 0, main_app, 0);
+}
+
+void cleanup_module(void) {
+ pthread_delete_np(main_thread);
+}
--- /dev/null
+;;; frsh-forb.el --- Helper functions for editing FRSH/FORB sources
+
+;; Copyright (C) 2010 Michal Sojka
+
+;; Author: Michal Sojka <sojkam1@fel.cvut.cz>
+;; Keywords: c, files, convenience
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(defun update-fres-error-c ()
+ "When called from fres_error.h it updates fres_error.c to match
+the list if defined errors"
+ (save-excursion
+ (beginning-of-buffer)
+ (let* ((beg (progn
+ (re-search-forward "^enum fres_error \{")
+ (beginning-of-line 2)
+ (point)))
+ (end (progn
+ (search-forward "}")
+ (beginning-of-line)
+ (point))))
+ (let ((errors))
+ (save-restriction
+ (narrow-to-region beg end)
+ (goto-char (point-min))
+ (while (re-search-forward "^[[:space:]]*FRES_ERR_" nil t)
+ (push (current-word) errors)))
+ (save-current-buffer
+ (set-buffer (find-file-noselect "fres_error.c"))
+ (beginning-of-buffer)
+ (search-forward "switch (e) {")
+ (kill-region (point) (save-excursion (search-forward "}") (backward-char) (point)))
+ (insert "\n")
+
+ (dolist (e errors)
+ (insert "\n")
+ (indent-according-to-mode)
+ (previous-line)
+ (insert (concat "MSG(" (replace-regexp-in-string "^FRES_ERR_" "" e) ");"))
+ (indent-according-to-mode)
+ (beginning-of-line)))))
+ (message "fres_error.c updated")))
+
+
+
+(provide 'frsh-forb)
+;;; frsh-forb.el ends here
--- /dev/null
+include_HEADERS := $(notdir $(wildcard $(SOURCES_DIR)/*.h))
+
+ifeq ($(CONFIG_FRSH_FORB),y)
+UNWANTED_HEADERS += frsh_opaque_types.h
+endif
+UNWANTED_HEADERS += frsh_configuration_parameters.h
+include_HEADERS := $(filter-out $(UNWANTED_HEADERS),$(include_HEADERS))
+
+default_CONFIG := $(shell grep '^\#define FRSH' $(SOURCES_DIR)/frsh_configuration_parameters.h|sed -e 's/\#define \([^ ]*\) *\(.*\)/\1=\2/' -e 's/ //g' -e 's|//.*||' -e 's|/\*.*\*/||g')
+
+config_include_HEADERS = frsh_configuration_parameters.h
+frsh_configuration_parameters_DEFINES := $(shell echo '$(default_CONFIG)' | sed -e 's/\([^=]*\)=[^ ]*/\1/g')
--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of DTM (Distributed Transaction Manager)
+//
+// DTM is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. DTM is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with DTM; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including DTM header files in a file,
+// instantiating DTM generics or templates, or linking other files
+// with DTM objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+/*!
+ * @file dtm.h
+ *
+ * @brief DTM API services
+ *
+ * This module contains the functions defined in the DTM API.
+ *
+ * @version 0.01
+ *
+ * @date 7-Sept-2007
+ *
+ * @author Michael Gonzalez Harbour <mgh@unican.es>
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
+ *
+ */
+
+#ifndef _DTM_H_
+#define _DTM_H_
+
+#include "frsh.h"
+
+typedef unsigned int trans_id_t; /* 0 .. MX_TRANS-1 */
+
+typedef enum {
+ TRANS_UNKNOWN = 0,
+ TRANS_IN_PROGRESS = 1,
+ TRANS_ACTIVE = 2,
+ TRANS_CANCELLED = 3,
+} trans_status_t;
+
+/**
+ * dtm_resources_set_processor_vres()
+ *
+ * Set the virtual resource that will be used in the local processor by the
+ * manager thread of the agent of the DTM. This must be a valid virtual
+ * resource obtained form the negotiation of a contract.
+ *
+ **/
+
+extern int dtm_resources_set_processor_vres(const frsh_vres_id_t vres);
+
+/**
+ * dtm_resources_set_network_vres()
+ *
+ * Set the virtual resource that will be used by the local DTM agent to send
+ * messages to the specified destination address. This must be a valid virtual
+ * resource obtained from the negotiation of a network contract, and must be
+ * compatible with the current system topology. Multiple calls to this
+ * operation may be needed, one for each processing node that is connected
+ * directly.
+ *
+ **/
+
+extern int dtm_resources_set_network_vres(const frsh_resource_id_t network,
+ const frsh_resource_id_t dest,
+ const frsh_vres_id_t vres);
+
+/**
+ * dtm_trans_init()
+ *
+ * Initialize a new transaction with the given name and maximum number of
+ * contracts. The newly created transaction will be initialized to contain
+ * no contracts.
+ *
+ **/
+
+extern int dtm_trans_init(const char *name,
+ const unsigned char num_contracts,
+ trans_id_t *trans);
+
+/**
+ * dtm_trans_add_contract()
+ *
+ * Add a reference to a contract to the given transaction together with
+ * the node in which that contract needs to be negotiated, and a boolean
+ * indicating whether or not the period needs to be synchronous with
+ * respect to other synchronous-period contracts in the transaction. Just
+ * the reference to the contract is copied, not the full contract information,
+ * and thus future changes to the contract may affect future negotiations
+ * or renegotiations.
+ *
+ **/
+
+extern int dtm_trans_add_contract(trans_id_t trans,
+ frsh_contract_t *contract,
+ frsh_resource_id_t node,
+ bool is_synch_period);
+
+/**
+ * dtm_trans_remove_contract()
+ *
+ * Remove a contract, identified by its label, from the transaction.
+ *
+ **/
+
+extern int dtm_trans_remove_contract(trans_id_t trans,
+ const char *contract_label);
+
+/**
+ * dtm_trans_destroy()
+ *
+ * Destroy a transaction freeing any memory that was allocated to it at
+ * its creation.
+ *
+ **/
+
+extern int dtm_trans_destroy(trans_id_t trans);
+
+/**
+ * dtm_trans_num_contracts()
+ *
+ * Return the current number of contracts in a transaction.
+ *
+ **/
+
+extern int dtm_trans_num_contracts(trans_id_t trans, unsigned char *num);
+
+/**
+ * dtm_trans_get_contract()
+ *
+ * Given an index, return a reference to the contract stored in that index.
+ * This operation is used to iterate over the contracts of a transaction.
+ *
+ **/
+
+extern int dtm_trans_get_contract(trans_id_t trans,
+ unsigned char index,
+ frsh_contract_t **contract);
+
+/**
+ * dtm_trans_negotiate()
+ *
+ * Negotiate a transaction. This is a blocking call that will not return
+ * until the negotiation has been completed.
+ *
+ **/
+
+extern int dtm_trans_negotiate(trans_id_t trans);
+
+/**
+ * dtm_trans_cancel()
+ *
+ * Cancel a transaction, by cancelling all the virtual resources that were
+ * associated with it. Cancellation has to be invoked from the same node
+ * where the transaction was negotiated.
+ *
+ **/
+
+extern int dtm_trans_cancel(trans_id_t trans);
+
+/**
+ * dtm_trans_renegotiate()
+ *
+ * Renegotiate a transaction. This is a blocking call that will not return
+ * until the negotiation has been completed.
+ *
+ **/
+
+extern int dtm_trans_renegotiate(trans_id_t trans);
+
+/**
+ * dtm_priv_trans_search()
+ *
+ * Internal function that searches a transaction by its name. It returns
+ * true if the transaction exists and sets the parameter to the transaction
+ * handle.
+ *
+ * When allocate_if_miss equals true, it tries to allocate a new transaction
+ * if the transaction was not found with 0 contracts.
+ *
+ **/
+
+extern bool dtm_priv_trans_search(const char *name,
+ trans_id_t *trans,
+ const bool allocate_if_miss);
+
+/**
+ * dtm_trans_get_status()
+ *
+ * Given a transaction name, get its status. This operation can be created
+ * in any node in the system. The status is an enumeration:
+ *
+ * - unknown: the current node has not yet been involved in the transaction
+ * - in_progress: the negotiation is in progress
+ * - active: the transaction was successfully negotiated and is active
+ * - cancelled: the transaction was cancelled
+ *
+ **/
+
+extern int dtm_trans_get_status(const char *name,
+ trans_status_t *status);
+
+/**
+ * dtm_trans_wait_active()
+ *
+ * Given a transaction name, wait until it gets active. A handle to the
+ * transaction is obtained. A timeout may be specified.
+ *
+ **/
+
+extern int dtm_trans_wait_active(const char *name,
+ const struct timespec *timeout,
+ trans_id_t *trans);
+
+/**
+ * dtm_trans_get_vres()
+ *
+ * Given a transaction handle and a contract label, get the virtual resource
+ * associated with that contract in the local processor.
+ *
+ **/
+
+extern int dtm_trans_get_vres(trans_id_t trans,
+ const char *contract_label,
+ frsh_vres_id_t *vres);
+
+/**
+ * dtm_trans_get_period()
+ *
+ * Get the current synchronous period of an active transaction, if any.
+ *
+ **/
+
+extern int dtm_trans_get_period(trans_id_t trans,
+ struct timespec *period);
+
+/**
+ * dtm_init()
+ *
+ * Initialize the distributed transaction manager in the local node.
+ * The stream Id to be used for DTM messages is specified as an argument.
+ * In first place, the operation creates all the necessary system resources
+ * (threads and communication endpoints) and binds them to the resources that
+ * were previously assigned locally to the DTM. Then, it performs the
+ * initialization process that synchronizes all the nodes, waiting until all
+ * of them are ready to work.
+ *
+ * TODO: The wait can be specified with a timeout,
+ * after which the operation would deallocate the allocated resources
+ * and return an error indication.
+ *
+ **/
+
+extern int dtm_init(frsh_stream_id_t stream);
+
+/**
+ * dtm_init_isdone()
+ *
+ * Query about whether the DTM has been initialized or not.
+ *
+ **/
+
+extern bool dtm_init_isdone(void);
+
+#endif // _DTM_H_
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef _FRSH_H_
+#define _FRSH_H_
+
+/**
+ * @file frsh.h
+ *
+ * Intended to be used by API clients to get the interface
+ * requirements.
+ *
+ * It is also used by the library files to enforce the interface
+ * headings.
+ *
+ * However it is NOT used by any of the FRSH include files to avoid
+ * having include deadlocks.
+ **/
+
+#include "fosa.h"
+
+#include "frsh_cpp_macros.h"
+
+#include "frsh_configuration_parameters.h"
+
+/* We include all the types because they are needed for the
+ frsh_contract_parameters_t */
+
+#include "frsh_core_types.h"
+#include "frsh_shared_objects_types.h"
+#include "frsh_spare_capacity_types.h"
+#include "frsh_hierarchical_types.h"
+#include "frsh_distributed_types.h"
+#include "frsh_implementation_specific_types.h"
+
+#include "frsh_core.h"
+#include "frsh_thread_attrs.h"
+#include "frsh_time.h"
+#include "frsh_implementation_specific.h"
+
+// Configure these modules by commenting out the appropiate lines
+
+#include "frsh_hierarchical.h" //
+#include "frsh_shared_objects.h"
+#include "frsh_dynamic_reclaiming.h" //
+#include "frsh_spare_capacity.h"
+#include "frsh_distributed.h" //
+#include "frsh_feedback_control.h"
+#include "frsh_memory_management.h"
+#include "frsh_energy_management.h"
+
+#include "frsh_debug_and_trace.h"
+
+#ifndef FRSH_HIERARCHICAL_MODULE_SUPPORTED
+ #define FRSH_HIERARCHICAL_MODULE_SUPPORTED 0
+
+#endif //FRSH_HIERARCHICAL_MODULE_SUPPORTED
+
+#ifndef FRSH_SHARED_OBJECTS_MODULE_SUPPORTED
+ #define FRSH_SHARED_OBJECTS_MODULE_SUPPORTED 0
+#endif //FRSH_SHARED_OBJECTS_MODULE_SUPPORTED
+
+#ifndef FRSH_DYNAMIC_RECLAIMING_MODULE_SUPPORTED
+ #define FRSH_DYNAMIC_RECLAIMING_MODULE_SUPPORTED 0
+#endif //FRSH_DYNAMIC_RECLAIMING_MODULE_SUPPORTED
+
+#ifndef FRSH_SPARE_CAPACITY_MODULE_SUPPORTED
+ #define FRSH_SPARE_CAPACITY_MODULE_SUPPORTED 0
+
+ //Return warnings if spare_capacity module is not included:
+
+ #define frsh_set_contract_reclamation_parameters \
+ (contract, budget_max, period_min, granularity,\
+ utilization_set, quality, importance) \
+ ( FRSH_WRN_MODULE_NOT SUPPORTED )
+
+ #define frsh_get_contract_reclamation_parameters \
+ (contract, budget_max, period_min, granularity,\
+ utilization_set, quality, importance) \
+ ( FRSH_WRN_MODULE_NOT SUPPORTED )
+
+ #define frsh_request_change_quality_and_importance\
+ (server, new_importance, new_quality) \
+ ( FRSH_WRN_MODULE_NOT SUPPORTED )
+
+ #define frsh_get_total_quality (server,total_quality)\
+ ( FRSH_WRN_MODULE_NOT SUPPORTED )
+
+#endif //FRSH_SPARE_CAPACITY_MODULE_SUPPORTED
+
+#include <frsh_transaction.h>
+
+#endif // _FRSH_H_
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_configuration_parameters.h
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef _FRSH_CONFIGURATION_PARAMETERS_H_
+#define _FRSH_CONFIGURATION_PARAMETERS_H_
+
+#include <unistd.h>
+#include <limits.h>
+#include <frsh_cpp_macros.h>
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_configuration_parameters.h
+ *
+ * This file contains parameters that govern the capabilities of the
+ * FRescor ScHeduler. They must be in concordance with the respective
+ * OS configuration.
+ **/
+
+
+/**
+ * @defgroup config Configuration Parameters
+ *
+ * Here we define global parameters that will have an important
+ * influence on FRSH behaviour. They must also be coherent with the
+ * respective values in the underlaying OS.
+ *
+ * @{
+ **/
+
+
+/**
+ * This symbol specifies whether the scheduler will make a
+ * schedulability test of the requested contract or not
+ **/
+#define FRSH_ADMISSION_TEST_IS_ENABLED true
+
+/**
+ * This symbol specifies whether the service thread will try to
+ * assign automatically the priorities of each vres
+ **/
+#define FRSH_AUTOMATIC_PRIO_ASSIGN_ENABLE true
+
+#ifdef ENABLE_FRSH_DISTRIBUTED_MODULE
+#define FRSH_DISTRIBUTED_MODULE_SUPPORTED true
+#else
+#define FRSH_DISTRIBUTED_MODULE_SUPPORTED false
+#endif
+
+/** This defines 1 resource_id value for systems that have only one
+ resource of a kind. **/
+#define FRSH_RESOURCE_ID_DEFAULT 0
+#define FRSH_CPU_ID_DEFAULT 0
+#define FRSH_NETWORK_ID_DEFAULT 0
+
+/**
+ * @defgroup internal Array size for memory optimization
+ * @ingroup config
+ *
+ * Tune these values for optimizing the amount of memory used by the
+ * implementation
+ *
+ * @{
+ **/
+
+/** Maximum number of accepted contracts (vres) **/
+#define FRSH_MAX_N_VRES 25
+
+/** Maximum number of threads that may be scheduled by the framework **/
+#define FRSH_MAX_N_THREADS 25
+
+/**
+ * Maximum number of critical sections that can be stored in a
+ * contract parameters object
+ **/
+#define FRSH_MAX_N_CRITICAL_SECTIONS 10
+
+/**
+ * Maximum number of memory areas that can be specified for a
+ * wite operation in a critical section
+ **/
+#define FRSH_MAX_N_MEMORY_AREAS 4
+
+/**
+ * Maximum number of utilization values (pairs of budget and period)
+ * that can be stored in a contract parameters object
+ **/
+#define FRSH_MAX_N_UTILIZATION_VALUES 5
+
+/** Number of importance levels for spare capacity allocation **/
+#define FRSH_N_IMPORTANCE_LEVELS 5
+
+/**
+ * Maximum number of synchronization objects
+ **/
+#define FRSH_MAX_N_SYNCH_OBJECTS 5
+
+/** Maximum number of shared objects **/
+#define FRSH_MAX_N_SHARED_OBJECTS 100
+
+/** Maximum number of send and receive endpoints in a single node **/
+#define FRSH_MAX_N_ENDPOINTS 10
+
+/** Maximum number of chars for a contract label **/
+#define FRSH_CONTRACT_LABEL_MAXLENGTH 15
+
+/*@}*/
+
+/**
+ * @defgroup schedandservice Scheduler and Service thread parameters
+ * @ingroup config
+ *
+ * The current implementation in MaRTE OS uses the Application-Defined
+ * Scheduling Interface (proposed to the POSIX standardization
+ * committee), to create a fixed-priority-based scheduler that
+ * operates under the rules of the FIRST scheduling framework.
+ *
+ * In this implementation there are two special threads:
+ * - The application scheduler thread, that
+ * implements the scheduler
+ *
+ * - The service thread, that is in charge of
+ * negotiating and renegotiating contracts
+ * concurrently with the application
+ *
+ * The following symbols are necessary to adapt the application to the
+ * underlying fixed priority scheduler
+ *
+ * @{
+ **/
+
+/**
+ * Priority assigned to the application scheduler; it should be above
+ * the priorities of the application threads and of the service
+ * thread, and it should be at least 1 level below the maximum of the
+ * system
+ **/
+#define FRSH_SCHEDULER_PRIORITY (fosa_get_priority_max() - FOSA_ADS_SCHEDULER_PRIO_DIFF)
+
+/**
+ * Real-time signal number reserved for the application scheduler to
+ * manage its timers.
+ **/
+#define FRSH_SCHEDULER_SIGNAL FRSH_SIGNAL_MIN
+
+
+
+/**
+ * The highest priority that can be assigned to an application thread,
+ * it should be defined as one level less than the
+ * FRSH_SCHEDULER_PRIORITY
+ **/
+#define FRSH_HIGHEST_THREAD_PRIORITY (FRSH_SCHEDULER_PRIORITY-1)
+
+
+/**
+ * The lowest priority that can be assigned to an application thread,
+ * it should be at least 1 level above the minimum of the system
+ **/
+#define FRSH_LOWEST_THREAD_PRIORITY ( fosa_get_priority_min() + 4)
+
+/**
+ * Each call to the functions that negotiate or renegotiate a contract
+ * or that change the quality and importance generates a request for
+ * the service thread that we call a service job. This job will be
+ * pending in a queue until executed by the service thread. The
+ * following symbol represents the maximum number of requests that can
+ * be simultaneously queued.
+ **/
+#define FRSH_MAX_N_SERVICE_JOBS (FRSH_MAX_N_VRES * 2)
+
+
+/**
+ * In order to bound the background activity of the scheduler (i.e.,
+ * the admission tests necessary for the negotiation and
+ * re-negotiation of contracts), a service thread has been defined. It
+ * runs at a given priority level and has a budget and period
+ * assigned.
+ *
+ **/
+
+/** Initial period of the service thread (timespec) **/
+#define FRSH_SERVICE_THREAD_PERIOD_USECS 500000 /* 500 msecs */
+
+/** Initial budget of the service thread (timespec) **/
+#define FRSH_SERVICE_THREAD_BUDGET_USECS 1000 /* 1 msec */
+
+/**
+ * Initial priority of the service thread, it has to be lower than the
+ * FRSH_SCHEDULER_PRIORITY, and is set according to its period and the
+ * expected response times for reconfiguration or tunning of the
+ * system.
+ *
+ * If set to zero and FRSH_ADMISSSION_TEST_ENABLE is set to true then
+ * the priority will be assigned according to DMA rules.
+ **/
+//#define FRSH_SERVICE_THREAD_PRIORITY (FRSH_LOWEST_THREAD_PRIORITY+1)
+#define FRSH_SERVICE_THREAD_PRIORITY 0
+
+
+/*@}*/
+
+
+/**
+ * @defgroup miscconfig Miscellaneous Config parameters
+ * @ingroup config
+ *
+ * @{
+ **/
+
+/**
+ * Maximum number of vres that can be simultaneusly waiting for
+ * being signaled in a synchronization object
+ **/
+#define FRSH_MAX_N_VRES_IN_SYNCH_OBJECT 4
+
+
+/**
+ * Maximum number of events that can be pending to be signaled in a
+ * synchronization object
+ **/
+#define FRSH_MAX_N_EVENTS_IN_SYNCH_OBJECT 100
+
+/**
+ * Maximum number of pending replenishments in each sporadic server
+ **/
+#define FRSH_MAX_N_PENDING_REPLENISHMENTS 25 //250
+
+
+/**
+ * Maximum number of target windows in a table driven schedule
+ **/
+#define FRSH_MAX_N_TARGET_WINDOWS 100
+
+/**
+ * The cpu time given by the round robin scheduler
+ * to the threads in the background (timespec)
+ **/
+#define FRSH_RR_SLICE_CPU_TIME_USECS 100000 // 0.1 sec
+
+/**
+ * This function must be supplied by the user to map the preemption
+ * level values given in the contracts for the vres, to priority
+ * values in the range that is allowed by the present implementation
+ * for application threads. The value returned by the function must
+ * fit in the interval defined by the constants:
+ * [FRSH_LOWEST_THREAD_PRIORITY, FRSH_HIGHEST_THREAD_PRIORITY]
+ **/
+int frsh_priority_map (unsigned long plevel);
+
+/**
+ * This symbol specifies the maximum number of chars that are stored
+ * of a given shared_object_id, so this is the maximum length used
+ * in comparisons
+ **/
+#define FRSH_MAX_SIZE_SHARED_OBJ_LABEL 15
+
+
+/** Maximum number of networks accesible from a node **/
+#define FRSH_MAX_N_NETWORK_IDS 1
+
+/**
+ * Maximum number of groups allocated at the same time
+ **/
+#define FRSH_MAX_N_GROUPS 3
+
+/**
+ * Maximum number of groups operations (neg, reneg, cancel) per group
+ **/
+#define FRSH_MAX_GROUP_OPS 25
+
+/**
+ * Default overheads of shared object protection mechanisms
+ * These values should be calibrated on each specific execution platform
+ */
+
+// fixed overhead for saving the environment and subsequently
+// aborting a critical section; units in nanoseconds
+
+#define FRSH_SO_FIXED_ABORT_OVHD 0
+
+
+// fixed overhead for copying a memory area, in nanoseconds
+
+#define FRSH_SO_FIXED_AREA_OVHD 0
+
+
+// variable overhead for copying a memory area; units in nanoseconds per kbyte
+
+#define FRSH_SO_NANOS_PER_KB 0
+
+
+/* Default memory pool's size in Kbytes */
+#define FRSH_DYNAMIC_MEMORY_POOL_SIZE 6670
+
+/**
+ * Maximum synchronized workload period number. After this value any
+ * increments will be set to zero.
+ **/
+#define FRSH_MAX_SYNCHRONIZED_PERIOD_NUMBER LONG_MAX
+
+
+/*@}*/
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif /* _FRSH_CONFIGURATION_PARAMETERS_H_ */
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef _FRSH_CORE_H_
+#define _FRSH_CORE_H_
+
+
+/**
+ * @file frsh_core.h
+ **/
+
+
+#include <time.h>
+#include <sys/types.h>
+
+#include "frsh_core_types.h"
+#include "frsh_spare_capacity.h"
+
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @defgroup core Core module
+ *
+ * This module includes the basic functions and services that are
+ * provided by any FRSH implementation. This module includes basic type
+ * definitions, and functions to
+ *
+ * - create a contract and initialize it
+ * - set/get the basic parameters of a contract
+ * - negotiate a service contract, obtaining a vres id
+ * - create and bind threads to vres
+ * - create/destroy a synchronization object
+ * - manage bounded workloads
+ *
+ **/
+
+
+//////////////////////////////////////////////////////////////////////
+// INITIALIZATION SERVICES
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup initialization Initialization services
+ * @ingroup core
+ *
+ * These functions need to be called before doing any FRSH operation
+ * (including contract initialization).
+ *
+ * @{
+ **/
+
+
+/**
+ * frsh_init()
+ *
+ * We cannot call any frsh functions before frsh_init. After calling
+ * frsh_init, the main will be executing in the background. Then, it
+ * can do the negotiations and create new threads if needed. The
+ * second time this function is called it fails.
+ *
+ * @return 0 if no error. \n
+ * FRSH_ERR_SYSTEM_ALREADY_INITIALIZED : if the function has already
+ * been called before\n
+ * .
+ * It may also return any of the errors that may be returned by the
+ * underlying operating system primitives required to perform the
+ * FRSH system start up
+ *
+ **/
+int frsh_init();
+
+/**
+ * frsh_destroy()
+ *
+ * Reverts the efect of frsh_init().
+ */
+void frsh_destroy();
+
+/*@}*/
+
+
+/////////////////////////////////////////////////////////////
+// CONTRACT PARAMETERS
+/////////////////////////////////////////////////////////////
+/**
+ * @defgroup contract Contract Creation and Initialization.
+ * @ingroup core
+ *
+ * These functions are used to create and initialize a contract, and
+ * set its parameters.
+ *
+ * @{
+ **/
+
+
+/**
+ * frsh_contract_init()
+ *
+ * The operation receives a pointer to a contract object
+ * and initializes it, setting it to the default values.
+ *
+ * The default values are:
+ *
+ * - resource_id => 0
+ * - ressource_type => FRSH_CRT_PROCESSOR
+ * - contract_label => ""
+ * - budget_min => {0,0};
+ * - period_max => {0,0};
+ * - budget_max => {0,0};
+ * - period_min => {0,0};
+ * - workload => FRSH_WT_INDETERMINATE
+ * - d_equals_t => true
+ * - contract_type => FRSH_CT_REGULAR;
+ * - deadline => {0,0};
+ * - budget_overrun_signal => 0; (signal number)
+ * - budget_overrun_siginfo => {0, NULL};
+ * - deadline_miss_signal => 0; (signal number)
+ * - deadline_miss_siginfo => {0, NULL};
+ *
+ * - granularity => DEFAULT_GRANULARITY;
+ * - utilization_set; => size = 0
+ * - quality => DEFAULT_QUALITY; (range 0..100)
+ * - importance => DEFAULT_IMPORTANCE; (range 1..5)
+ * - preemption_level => 0; (range 1..2**32-1)
+ * - critical_sections; => size = 0
+ *
+ * - sched_policy => DEFAULT_SCHED_POLICY (FRSH_NONE)
+ *
+ * @param contract the pointer to the contract variable.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : contract is NULL
+ *
+ **/
+int frsh_contract_init(frsh_contract_t *contract);
+
+
+/**
+ * frsh_contract_destroy()
+ *
+ * The operation deallocates all memory which might be allocated for
+ * the contract.
+ *
+ * @param contract the pointer to the contract variable.
+ **/
+void frsh_contract_destroy(frsh_contract_t *contract);
+
+
+/**
+ * frsh_contract_set_basic_params()
+ *
+ * The operation updates the specified contract parameters object by
+ * setting its budget, period, workload and type to the specified
+ * input parameters. (Note: the workload is a basic parameter because
+ * bounded tasks are triggered by the scheduler (see the
+ * frsh_timed_wait() and frsh_synchobj_wait* operations), while
+ * indeterminate tasks are not; therefore, their programming model is
+ * quite different).
+ *
+ * @param contract the pointer to the contract object
+ * @param[in] budget_min the minimum budget for the contract
+ * @param[in] period_max the maximum period for the contract
+ * @param[in] workload the kind of workload (can be FRSH_WT_BOUNDED,
+ * FRSH_WT_INDETERMINATE or FRSH_OVERHEAD)
+ * @param[in] contract_type can be FRSH_CT_REGULAR,
+ * FRSH_CT_BACKGROUND, FRSH_CT_DUMMY.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if any of the pointers is NULL
+ * or if only one of the time values is 0, and also if the
+ * workload or the contract type values are unknown in the
+ * enumerations.
+ **/
+int frsh_contract_set_basic_params
+ (frsh_contract_t *contract,
+ const frsh_rel_time_t *budget_min,
+ const frsh_rel_time_t *period_max,
+ const frsh_workload_t workload,
+ const frsh_contract_type_t contract_type);
+
+/**
+ * frsh_contract_get_basic_params()
+ *
+ * This operation obtains from the specified contract object its
+ * budget, period, and workload, and copies them to the places pointed
+ * to by the corresponding output parameters.
+ *
+ * @param[in] contract the pointer to the contract object
+ * @param[out] budget_min pointer to preallocated space
+ * @param[out] period_max pointer to preallocated space
+ * @param[out] workload pointer to preallocated space
+ * @param[out] contract_type pointer to preallocated space
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if one of the contract or
+ * pointers is NULL.
+ *
+ **/
+int frsh_contract_get_basic_params
+ (const frsh_contract_t *contract,
+ frsh_rel_time_t *budget_min,
+ frsh_rel_time_t *period_max,
+ frsh_workload_t *workload,
+ frsh_contract_type_t *contract_type);
+
+/**
+ * frsh_contract_set_resource_and_label()
+ *
+ * Specify resource_id and type, and the contract label. Otherwise
+ * default values will apply. If the contract label is too long it is truncated
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if the contract pointer is NULL.
+ **/
+int frsh_contract_set_resource_and_label
+ (frsh_contract_t *contract,
+ const frsh_resource_type_t resource_type,
+ const frsh_resource_id_t resource_id,
+ const char *contract_label);
+
+
+/**
+ * frsh_contract_get_resource_and_label()
+ *
+ * Obtain the resource_id and type, and the contract label.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if the contract or the contract_label
+ * pointer is NULL.
+ **/
+int frsh_contract_get_resource_and_label
+ (const frsh_contract_t *contract,
+ frsh_resource_type_t *resource_type,
+ frsh_resource_id_t *resource_id,
+ char *contract_label);
+
+
+/**
+ * frsh_contract_set_timing_reqs()
+ *
+ * The operation updates the specified contract object, specifying
+ * additional time-related requirements.
+ *
+ * @param contract The pointer to the contract object
+ *
+ * @param [in] d_equals_t It is a boolean value, set to true (1) if
+ * we want to specify a deadline different from
+ * the period for the contract.
+ * @param [in] deadline If the previous parameter is set to true,
+ * this parameter is ignored (the contract value
+ * will be NULL_DEADLINE internally). Otherwise, it
+ * contains the desired deadline value.
+ *
+ * @return 0 if successful\n
+ * FRSH_ERR_BAD_ARGUMENT : if contract is NULL \b or \n
+ * (d_equals_t is true and deadline is not FRSH_NULL_DEADLINE) \b or \n
+ * (budget_overrun_signal is not a valid signal) \b or \n
+ * (deadline_miss_signal is not a valid signal) \b or \n
+ * (d_equals_t is false but (deadline is FRSH_NULL_DEADLINE or its value
+ * is grater than the contract's maximum period))
+ *
+ **/
+int frsh_contract_set_timing_reqs
+ (frsh_contract_t *contract,
+ const bool d_equals_t,
+ const frsh_rel_time_t *deadline);
+
+/**
+ * frsh_contract_get_timing_reqs()
+ *
+ * The operation obtains the corresponding input parameters from the
+ * specified contract object. If d_equals_t is true, the deadline will
+ * be set to FRSH_NULL_DEADLINE.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if contract is NULL
+ *
+ **/
+int frsh_contract_get_timing_reqs
+ (const frsh_contract_t *contract,
+ bool *d_equals_t,
+ frsh_rel_time_t *deadline);
+
+
+/*@}*/
+
+//////////////////////////////////////////////////////////////////
+// SYNCHRONIZATION OBJECTS
+//////////////////////////////////////////////////////////////////
+/**
+ * @defgroup synch Synchronization objects
+ * @ingroup core
+ *
+ * Synchronisation objects provide an alternative to timers for
+ * bounded-workload vres to signal the end of their current job and
+ * return their remaining budget to FRSH.
+ *
+ * Instead of asking to be reactivated based on an absolute time, they
+ * queue themselves in a synchronisation object and will wait there
+ * until another vres (bounded-workload or indeterminate-workload)
+ * wakes them up with a signal call the earliest at the beginning of
+ * the next period.
+ *
+ * Indeterminate-workload vres cannot queue themselves here because
+ * they don't have any budget to return. However they can signal on
+ * the objects to activate a waiting workload vres.
+ *
+ * For classical signal/wait synchronisation paradigms the application
+ * must use whatever mechanism the underlying OS provides.
+ *
+ * In the future we may add a broadcast operation that would signal a
+ * group of synchronization objects. We have not included a broadcast
+ * service in this version because it can be easily created by the
+ * user by signalling individual synchronization objects inside a
+ * loop.
+ *
+ * Notice that for synchronization objects there is no naming service
+ * like in shared objects because tasks that use synchronization are
+ * not developed independently, as they are closely coupled.
+ *
+ * @{
+ **/
+
+
+/**
+ * frsh_synchobj_create()
+ *
+ * This operation creates and initializes a synchronization object
+ * variable managed by the scheduler, and returns a handle to it in
+ * the variable pointed to by synch_handle.
+ *
+ * @param[out] synch_handle pointer to the variable that will contain
+ * the handle to the newly created synchronization object
+ *
+ * @return 0 if the operation is succesful
+ * FRSH_ERR_TOO_MANY_SYNCH_OBJS if the number of synchronization
+ * objects in the system has already exceeded the maximum
+ *
+ * FRSH_ERR_TOO_MANY_SYNCH_OBJS : if the number of synchronization
+ * objects in the system has already exceeded the maximum\n
+ * .
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH\n
+ * .
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
+ *
+ **/
+int frsh_synchobj_create
+ (frsh_synchobj_handle_t *synch_handle);
+
+
+/**
+ * frsh_synchobj_destroy()
+ *
+ * This operation destroys the synchronization object (created by a
+ * previous call to frsh_synchobj_create) that is referenced by the
+ * synch_handle variable. After calling this operation, the
+ * synch_handle variable can not be used until it is initialized again
+ * by a call to frsh_synchobj_create.
+ *
+ * @param synch_handle the handle to the synchronization object
+ * to be destroyed
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if synch_handle is 0\n
+ * FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE if the handle is not valid\n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running
+ *
+ * @sa frsh_synchobj_create
+ **/
+int frsh_synchobj_destroy
+ (const frsh_synchobj_handle_t synchobj_handle);
+
+/**
+ * frsh_synchobj_wait()
+ *
+ * This operation is invoked by threads associated with bounded
+ * workload vres to indicate that a job has been completed (and
+ * that the scheduler may reassign the unused capacity of the current
+ * job to other vres).
+ *
+ * As a difference with frsh_timed_wait(), here the vres
+ * specifies to be awakened by the arrival of a signal operation
+ * instead of at a precise point of time.
+ *
+ * This function can also be called to schedule the first job of a
+ * recently created vres and make it start when a signal operation
+ * has been sent from another thread.
+ *
+ * The vres' budget will be made zero for the remainder of the vres'
+ * period, and FRSH will not replenish it until an event has been
+ * notified to the synchronisation object by another vres.
+ *
+ * It can happen that the synchronisation object has notification
+ * events queued from the past, in this case one of the events is
+ * dequeued immediately and the vres won't have to wait for another
+ * one.
+ *
+ * At the time of reception of a notification event (wether in the
+ * future or in the past), all pending budget replenishments (if any)
+ * are made effective. Once the vres has a positive budget and the
+ * scheduler schedules the calling thread again, the call returns and
+ * the vres continues executing.
+ *
+ * If the synchronisation object is destroyed while the vres was
+ * waiting on it, the vres will be awaken and the function will
+ * return with a code FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE
+ *
+ * Except for those parameters equal to NULL pointers, the system
+ * reports the current period and budget for the current job, it informs
+ * if the deadline of the previous job was missed or not, and whether the
+ * budget of the previous job was overrun or not.
+ *
+ * In a system with hierarchical scheduling, since this call makes the
+ * budget of the current period zero, the other threads in the same
+ * vres are not run. As mentioned above, only when the call finishes
+ * the budget may be replenished.
+ *
+ * @param synch_handle Synchronisation object upon which the vres
+ * will be waiting.
+ * @param next_budget[out] Upon return of this function, the variable
+ * pointed by this function will be equal to
+ * the current vres budget. If this parameter is
+ * set to NULL, no action is taken
+ * @param next_period[out] The vres period upon return (ignored if NULL).
+ * @param was_deadline_missed Upon return whether the deadline was
+ * missed in the previous period.
+ * @param was_budget_overran
+ *
+ *
+ * @return 0 if success \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
+ * main scheduler \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled
+ * under FRSH \n
+ * FRSH_ERR_NOT_BOUND : if the calling thread does not have a valid
+ * vres bound to it \n
+ * FRSH_ERR_BAD_ARGUMENT : if synch_handle is 0 \n
+ * FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE if the synch_handle is not
+ * valid or was destroyed while the vres was waiting on it. \n
+ * FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload of the vres
+ * is not FRSH_BOUNDED
+ *
+ **/
+int frsh_synchobj_wait
+ (const frsh_synchobj_handle_t synch_handle,
+ frsh_rel_time_t *next_budget,
+ frsh_rel_time_t *next_period,
+ bool *was_deadline_missed,
+ bool *was_budget_overran);
+
+
+/**
+ * frsh_synchobj_wait_with_timeout()
+ *
+ * This call is the same as frsh_synchobj_wait() but with an extra
+ * absolute timeout. The timed_out argument, indicates whether the
+ * function returned because of the expiration of the timeout or not.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE if the synch_handle is not
+ * valid \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
+ * main scheduler \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled
+ * under FRSH \n
+ * FRSH_ERR_NOT_BOUND : if the calling thread does not have a valid
+ * vres bound to it \n
+ * FRSH_ERR_BAD_ARGUMENT : if the synch_handle given is not valid or the
+ * abs_timeout argument is NULL or its value is in the past\n
+ * FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload of the vres
+ * is not FRSH_BOUNDED
+ *
+ **/
+int frsh_synchobj_wait_with_timeout
+ (const frsh_synchobj_handle_t synch_handle,
+ const frsh_abs_time_t *abs_timeout,
+ bool *timed_out,
+ frsh_rel_time_t *next_budget,
+ frsh_rel_time_t *next_period,
+ bool *was_deadline_missed,
+ bool *was_budget_overran);
+
+/**
+ * frsh_synchobj_signal()
+ *
+ * This function sends a notification event to the synchronization object
+ * specified as parameter. If there is at least one vres waiting on
+ * the synchronization object, it is awaken. If more than one vres
+ * are waiting, just one of them is awaken. However, which one is
+ * awaken is implementation dependent. If no vres is waiting on the
+ * synchronization object, the notification event is queued.
+ *
+ * @param [in] synch_handle the handle of the synchronization object to
+ * notify.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if synch_handle is 0 \n
+ * FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE if the handle is not valid \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_TOO_MANY_EVENTS_IN_SYNCH_OBJ : if the number of events stored
+ * in the synchronization object reaches the maximum defined in the
+ * configuration parameter header file
+ *
+ * @sa frsh_synchobj_wait, frsh_synchobj_wait_with_timeout
+ **/
+int frsh_synchobj_signal
+ (const frsh_synchobj_handle_t synch_handle);
+
+/**
+ * frsh_timed_wait()
+ *
+ * This operation is invoked by threads associated with bounded
+ * workload vres to indicate that a job has been completed (and
+ * that the scheduler may reassign the unused capacity of the current
+ * job to other vres). It is also invoked when the first job of
+ * such threads has to be scheduled.
+ *
+ * As an effect, the system will make the current vres's budget zero
+ * for the remainder of the vres's period, and will not replenish
+ * the budget until the specified absolute time. At that time, all
+ * pending budget replenishments (if any) are made effective. Once the
+ * vres has a positive budget and the scheduler schedules the
+ * calling thread again, the call returns and at that time, except for
+ * those parameters equal to NULL pointers, the system reports the
+ * current period and budget for the current job, whether the deadline
+ * of the previous job was missed or not, and whether the budget of
+ * the previous job was overrun or not.
+ *
+ * In a system with hierarchical scheduling, since this call makes the
+ * budget zero, the other threads in the same vres are not run. As
+ * mentioned abobe, only when the call finishes the budget may be
+ * replenished.
+ *
+ * @param [in] abs_time absolute time at which the budget will be
+ * replenished
+ *
+ * @param [out] next_budget upon return of this function, the variable
+ * pointed by this function will be equal to
+ * the current vres budget. If this parameter is
+ * set to NULL, no action is taken.
+ *
+ * @param [out] next_period upon return of this function, the variable
+ * pointed by this function will be equal to
+ * the current vres period. If this parameter is
+ * set to NULL, no action is taken.
+ *
+ * @param [out] was_deadline_missed upon return of this function, the
+ * variable pointed by this function will be
+ * equal to true if the previous vres deadline
+ * was missed, to false otherwise. If this
+ * parameter is set to NULL, no action is
+ * taken.
+ *
+ * @param [out] was_budget_overrun upon return of this function, the
+ * variable pointed by this function will be
+ * equal to true if the previous vres budget was
+ * overrun, to false otherwise. If this
+ * parameter is set to NULL, no action is
+ * taken.
+ *
+ * @return 0 if the operation is successful \n
+ * FRSH_ERR_TIME_SPEC_IN_THE_PAST if the absolute time specification
+ * is in the past. \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong
+ * or not running \n
+ * FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
+ * main scheduler \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling
+ * thread is not scheduled under FRSH \n
+ * FRSH_ERR_NOT_BOUND : if the calling thread does not have a valid
+ * vres bound to it \n
+ * FRSH_ERR_BAD_ARGUMENT : if abs_time is NULL \n
+ * FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload of the vres
+ * is not FRSH_BOUNDED
+ *
+ *
+ * @sa frsh_synchobj_wait, frsh_synchobj_wait_with_timeout
+ **/
+int frsh_timed_wait
+ (const frsh_abs_time_t *abs_time,
+ frsh_rel_time_t *next_budget,
+ frsh_rel_time_t *next_period,
+ bool *was_deadline_missed,
+ bool *was_budget_overran);
+
+
+
+/**
+ * frsh_vresperiod_wait()
+ *
+ * Suspend the calling thread until the start of the specified virtual
+ * resource period of a vres_id, for a synchronized workload.
+ *
+ * Virtual resource periods are numbered. The number of the current
+ * period can be obtained through the frsh_vres_get_period_number()
+ * operation.
+ **/
+int frsh_vresperiod_wait(unsigned long period_num,
+ frsh_rel_time_t *next_budget,
+ frsh_rel_time_t *next_period,
+ bool *was_deadline_missed,
+ bool *was_budget_overran);
+
+
+/**
+ * frsh_vres_get_period()
+ *
+ * Return the current period number, for a virtual resource of
+ * synchronized workload.
+ **/
+int frsh_vres_get_period_number
+ (const frsh_vres_id_t vres,
+ long *period_num);
+
+
+
+
+/*@}*/
+
+///////////////////////////////////////////////////////////////////
+// CONTRACT NEGOCIATION OPERATIONS
+///////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup negotiate Negotiate contract functions
+ * @ingroup core
+ *
+ * The following functions are used to negotiate contracts and thus
+ * creating vres which are the execution image of a contract.
+ * Besides, these functions allow to assign and unassign threads to
+ * vres.
+ *
+ * In the case of more than one thread per vres please refer to the
+ * hierarchical module.
+ *
+ * @{
+ **/
+
+
+
+/**
+ * frsh_contract_negotiate()
+ *
+ * The operation negotiates a contract and if accepted it will return
+ * a vres_id. It will also check that the given contract_label is unique
+ * within the node.
+ *
+ * If the on-line admission test is enabled, it determines whether the
+ * contract can be admitted or not based on the current contracts
+ * established in the system. Then it creates the vres and
+ * recalculates all necessary parameters for the contracts already
+ * present in the system.
+ *
+ * This is a potentially blocking operation, it returns when the
+ * system has either rejected the contract, or admitted it and made it
+ * effective. No thread is bound to the newly created vres, which
+ * will be idle until a thread is bound to it via frsh_thread_bind()
+ * or frsh_thread_create_and_bind().
+ *
+ * This operation can only be executed by threads that are already
+ * bound to an active vres and therefore are being scheduled by the
+ * frsh scheduler.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_CONTRACT_REJECTED: The contract is not accepted.\n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
+ * main scheduler \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled
+ * under FRSH scheduler \n
+ * FRSH_ERR_BAD_ARGUMENT : if the contract or vres arguments are NULL \n
+ * FRSH_ERR_TOO_MANY_VRES : if there is no space for more vres
+ * (the maximum number of them is already reached) \n
+ * FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS : contract_label is not unique.
+ *
+ **/
+int frsh_contract_negotiate
+ (const frsh_contract_t *contract,
+ frsh_vres_id_t *vres);
+
+/**
+ * frsh_thread_create_and_bind()
+ *
+ * This operation creates a thread and binds it to an existing vres.
+ *
+ * This is the preferred way to add threads to the application because
+ * we make sure that the thread won't become unbound.
+ *
+ * The vres must not have any thread binded to it. If you want to
+ * bind more than one thread to the vres you must use the
+ * hierarchical module.
+ *
+ * The frsh_thread_attr_t parameter is overwritten as necessary to
+ * introduce the adequate scheduling policy and priority, according
+ * to the preemption level given in the contract and the
+ * frsh_priority_map() function defined by the user.
+ *
+ * @param[in] vres_id vres with which the thread will be bound.
+ * @param[out] thread frsh_thread_id returned by the system.
+ * @param attr pthread_attr taken and maybe corrected
+ * by the system. Ignored if NULL
+ * @param[in] thread_code Thread function (void func(void *) )
+ * that will constitute the main of the
+ * thread.
+ * @param[in] arg Argument for data to be passed at the
+ * thread. Set to NUL if you don't want
+ * to do anything like this.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT : if the contract or vres arguments are
+ * NULL \n
+ * FRSH_ERR_CONTRACT_REJECTED : if the contract is rejected. \n
+ * .
+ * It may also return all the errors that may be returned by the
+ * fosa_thread_create() function call
+ *
+ **/
+int frsh_thread_create_and_bind
+ (const frsh_vres_id_t vres,
+ frsh_thread_id_t *thread,
+ frsh_thread_attr_t *attr,
+ frsh_thread_code_t thread_code,
+ void *arg);
+
+
+/**
+ * frsh_thread_create_in_background()
+ *
+ * This function creates a "background contract" that does not need to
+ * be negotiated, creates a threads and binds to the new vres.
+ *
+ * This method is suggested as a way to initate components and
+ * plugins. The event that triggers the component activation should
+ * arrive to an application thread that could use this function to
+ * create a thread used in its initialisation.
+ *
+ * The attribute parameter is overwritten as necessary to introduce
+ * the adequate scheduling policy and priority.
+ *
+ * @param[in] thread_code Function to be executed by the new
+ * thread.
+ * @param[in] thread_arg General pointer that will be passed to
+ * the new thread as initialisation data.
+ * @param attr Pthread attribute with thread params
+ * @param[in] contract_label Contract label for the new vres.
+ * @param[out] thread_id Id of the new thread.
+ * @param[out] vres_id vres_id of the new vres.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT : Any problems with the argument \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is
+ * not scheduled under FRSH \n
+ * FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS : contract_label is not unique \n
+ * FRSH_ERR_TOO_MANY_VRES : if there is no space for more vres
+ * (the maximum number of them is already reached)
+ *
+ **/
+int frsh_thread_create_in_background
+ (frsh_thread_code_t thread_code,
+ const void *thread_arg,
+ const char *contract_label,
+ frsh_thread_attr_t *attr,
+ frsh_thread_id_t *thread_id,
+ frsh_vres_id_t *vres_id);
+
+
+
+/**
+ * frsh_thread_join_in_background()
+ *
+ * This function is aimed for external threads to join FRSH in the
+ * least disturbing possible mode.
+ *
+ * Upon calling this function by a thread which has been created
+ * natively in the OS, it joins the framework and gets inmediately
+ * bound to an on-the-fly generated background contract.
+ *
+ * In order to gain a higher priority then it can renegotiate a
+ * contract for its vres with the needed parameters.
+ *
+ * @param[in] resource_id: Resource (CPU) in which the vres will
+ * be associated.
+ *
+ * @param[in] resource_type: Resource type (should be CPU) for the
+ * contract.
+ *
+ * @param[in] label: Label to be added to the contract.
+ *
+ * @param[out] vres_id: Resulting vres_id from the on-the-fly
+ * generated background contract.
+ *
+ * @return 0 if successful\n
+ * FRSH_ERR_NOT_CONTRACTED_VRES if the thread is already
+ * bound to a vres.
+ **/
+int frsh_thread_join_in_background(frsh_resource_id_t resource_id,
+ frsh_resource_type_t resource_type,
+ const char *label,
+ frsh_vres_id_t *vres_id);
+
+
+
+/**
+ * frsh_thread_bind()
+ *
+ * This operation associates a thread with a vres, which means that
+ * it starts consuming the vres's budget and is executed according
+ * to the contract established for that vres. If the thread is
+ * already bound to another vres, it is effectively unbound from it
+ * and bound to the specified one.
+ *
+ * It fails if the vres's policy is different than FRSH_NONE, or if
+ * there is already a thread bound to this vres. In order to bind
+ * more than one vres to the same thread you must use the
+ * hierarchical module.
+ *
+ * Implementation dependent issue: In order to allow the usage of
+ * application defined schedulers, the given thread must not have the
+ * scheduling policy SCHED_APP and at the same time be attached to an
+ * application scheduler different than the frsh scheduler.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
+ * main scheduler \n
+ * FRSH_ERR_UNKNOWN_APPSCHEDULED_THREAD : if the thread is attached to
+ * an application defined scheduler different than the frsh
+ * scheduler \n
+ * FRSH_ERR_BAD_ARGUMENT : if the vres value does not complain with the
+ * expected format or valid range or the given thread does not
+ * exist \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the referenced vres is not
+ * valid \n
+ * FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload
+ * of the vres is FRSH_OVERHEAD \n
+ * FRSH_ERR_ALREADY_BOUND : if the given vres has a thread already
+ * bound
+ *
+ **/
+int frsh_thread_bind
+ (const frsh_vres_id_t vres,
+ const frsh_thread_id_t thread);
+
+
+/**
+ * frsh_thread_unbind()
+ *
+ * This operation unbinds a thread from a vres. Since threads with
+ * no vres associated are not allowed to execute, they remain in a
+ * dormant state until they are either eliminated or bound again.
+ *
+ * If the thread is inside a critical section the effects of this call
+ * are deferred until the critical section is ended
+ *
+ * Implementation dependent issue: in the implementation with an
+ * application scheduler, the thread is still attached to the frsh
+ * scheduler, but suspended.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
+ * main scheduler \n
+ * FRSH_ERR_BAD_ARGUMENT : if the given thread does not exist \n
+ * FRSH_ERR_NOT_SCHEDULED_THREAD : if the given thread is not scheduled
+ * under FRSH \n
+ * FRSH_ERR_UNKNOWN_APPSCHEDULED_THREAD : if the thread is attached to
+ * an application defined scheduler different than the frsh
+ * scheduler \n
+ * FRSH_ERR_NOT_BOUND : if the given thread does not have a valid
+ * vres bound to it
+ **/
+int frsh_thread_unbind(const frsh_thread_id_t thread);
+
+/**
+ * frsh_vres_set_notification()
+ *
+ * This function setups notification signals for CPU vres. It is
+ * necessary to call this function before bounding the thread to the
+ * vres.
+ *
+ * @param [in] budget_overrun_signal contains the number of the signal
+ * that must be raised if the budget of the vres is
+ * overrun by the thread.
+ * If the value of this parameter is FRSH_NULL_SIGNAL, no signal will
+ * be raised.
+ * @param [in] budget_overrun_siginfo contains the value that will be
+ * passed to the signal "catcher" when the signal is raised.
+ * This parameters is not used if the budget_overrun_signal
+ * parameter is set to FRSH_NULL_SIGNAL.
+ * @param [in] deadline_miss_signal contains the number of the
+ * signal that must be raised if the deadline of the
+ * vres is missed. If the value of this parameter is
+ * FRSH_NULL_SIGNAL, no signal is raised.
+ * @param [in] deadline_miss_siginfo contains the value that will be
+ * passed to the signal "catcher" when the signal is
+ * raised. This parameter is not used if the
+ * deadline_signal parameter is set to NULL_SIGNAL
+ **/
+int frsh_vres_set_notification(
+ frsh_vres_id_t vres,
+ const frsh_signal_t budget_overrun_signal,
+ const frsh_signal_info_t budget_overrun_siginfo,
+ const frsh_signal_t deadline_miss_signal,
+ const frsh_signal_info_t deadline_miss_siginfo);
+
+/**
+ * frsh_thread_get_vres_id()
+ *
+ * This operation stores the Id of the vres associated with the
+ * specified thread in the variable pointed to by vres. It returns
+ * an error if the thread does not exist, it is not under the control
+ * of the scheduling framework, or is not bound.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_NOT_SCHEDULED_THREAD : if the given thread is not scheduled
+ * under FRSH \n
+ * FRSH_ERR_NOT_BOUND : if the given thread does not have a valid
+ * vres bound to it \n
+ * FRSH_ERR_BAD_ARGUMENT : if the given thread does not exist or the
+ * vres argument is NULL
+ *
+ **/
+int frsh_thread_get_vres_id(const frsh_thread_id_t thread,
+ frsh_vres_id_t *vres_id);
+
+/**
+ * frsh_vres_get_priority()
+ *
+ * This operation stores the priority currently associated
+ * with the specified vres in the variable pointed to by
+ * priority. It returns an error if the vres_id is not recognised.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if the contract argument is NULL or the value
+ * of the vres argument is not in range \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES: if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_vres_get_priority
+ (frsh_vres_id_t vres_id,
+ int *priority);
+
+/**
+ * frsh_vres_get_contract()
+ *
+ * This operation stores the contract parameters currently associated
+ * with the specified vres in the variable pointed to by
+ * contract. It returns an error if the vres_id is not recognised.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if the contract argument is NULL or the value
+ * of the vres argument is not in range \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES: if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_vres_get_contract
+ (const frsh_vres_id_t vres,
+ frsh_contract_t *contract);
+
+/**
+ * frsh_resource_get_vres_from_label()
+ *
+ * This operation retrieves the vres_id whose contract_label
+ * corresponds to the parameter in the resource_id and resource_type
+ * specified.
+ *
+ * The contract label must refer to a contract negotiated
+ * in the same processing node in which the call is being
+ * made. Otherwise an error is returned.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if the contract argument is NULL or the
+ * contract_label is NULL \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_CONTRACT_LABEL_UNKNOWN: if the contract_label is not known
+ **/
+int frsh_resource_get_vres_from_label
+ (const char *contract_label,
+ const frsh_resource_type_t resource_type,
+ const frsh_resource_id_t resource_id,
+ frsh_vres_id_t *vres);
+
+
+
+/**
+ * frsh_contract_cancel()
+ *
+ * The operation eliminates the specified vres
+ * and recalculates all necessary parameters for the contracts
+ * remaining in the system. This is a potentially blocking operation;
+ * it returns when the system has made the changes effective.
+ *
+ * Note that the thread is not eliminated. We leave the application
+ * the option to either freeze it for a later use or bind it to
+ * another vres.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT : if the value of vres is not in range \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_contract_cancel (const frsh_vres_id_t vres);
+
+
+/**
+ * frsh_contract_renegotiate_sync()
+ *
+ * The operation renegotiates a contract for an existing vres. If
+ * the on-line admission test is enabled it determines whether the
+ * contract can be admitted or not based on the current contracts
+ * established in the system. If it cannot be admitted, the old
+ * contract remains in effect and an error is returned. If it can be
+ * admitted, it recalculates all necessary parameters for the
+ * contracts already present in the system and returns zero. This is a
+ * potentially blocking operation; it returns when the system has
+ * either rejected the new contract, or admitted it and made it
+ * effective.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT : if the new_contract argument is NULL or the
+ * value of the vres argument is not in range \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid \n
+ * FRSH_ERR_CONTRACT_REJECTED : if the renegotiation fails
+ *
+ **/
+int frsh_contract_renegotiate_sync
+ (const frsh_contract_t *new_contract,
+ const frsh_vres_id_t vres);
+
+
+/**
+ * frsh_contract_renegotiate_async()
+ *
+ * The operation enqueues a renegotiate operation for an existing
+ * vres, and returns immediately. The renegotiate operation is
+ * performed asynchronously, as soon as it is practical; meanwhile the
+ * system operation will continue normally. When the renegotiation is
+ * made, if the on-line admission test is enabled it determines
+ * whether the contract can be admitted or not based on the current
+ * contracts established in the system. If it cannot be admitted, the
+ * old contract remains in effect. If it can be admitted, it
+ * recalculates all necessary parameters for the contracts already
+ * present in the system.
+ *
+ * When the operation is completed, notification is made to the
+ * caller, if requested, via a signal. The status of the operation (in
+ * progress, admitted, rejected) can be checked with the
+ * frsh_vres_get_renegotiation_status() operation. The argument
+ * sig_notify can be FRSH_NULL_SIGNAL (no notification), or any FRSH
+ * signal value and in this case signal_info is to be sent with the signal.
+ *
+ * @param[in] new_contract New contract parameters for the new
+ * situation if approved.
+ * @param[in] vres vres_id on which to do the renegotiation.
+ * @param[in] signal_to_notify Signal number to use to notify vres of
+ * the negotiation result. If
+ * FRSH_NULL_SIGNAL, no signal will be raised.
+ * @param[in] signal_info: Associated info that will come with the
+ * signal. This parameter will be ignored
+ * if signal_to_notify == FRSH_NULL_SIGNAL.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if the new_contract argument is NULL, the
+ * value of the vres argument is not in range or sig_notify is
+ * neither NULL nor a valid POSIX signal \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_contract_renegotiate_async
+ (const frsh_contract_t *new_contract,
+ const frsh_vres_id_t vres,
+ const frsh_signal_t signal_to_notify,
+ const frsh_signal_info_t signal_info);
+
+
+/**
+ * frsh_vres_get_renegotiation_status()
+ *
+ * The operation reports on the status of the last renegotiation
+ * operation enqueued for the specified vres. It is callable even
+ * after notification of the completion of such operation, if
+ * requested.
+ *
+ * If the vres is not and has not been involved in any of the
+ * frsh_contract_renegotiate_async() or frsh_group_change_mode_async()
+ * operations, the status returned is FRSH_RS_NOT_REQUESTED
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if the renegotiation_status argument is
+ * NULL or the value of the vres argument is not in range \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_vres_get_renegotiation_status
+ (const frsh_vres_id_t vres,
+ frsh_renegotiation_status_t *renegotiation_status);
+
+/*@}*/
+
+////////////////////////////////////////////////////////////////////////
+// CHANGE OF MODE: GROUPS OF CONTRACTS
+////////////////////////////////////////////////////////////////////////
+/**
+ * @defgroup groupofcontracts Group of contracts
+ * @ingroup core
+ *
+ * The following functions are used to negotiate atomically more than
+ * one contract. This allows to build complex applications by
+ * splitting them in individual contracts that are negotiated
+ * simultaneously and atomically.
+ *
+ * @{
+ **/
+
+/**
+ * frsh_group_change_mode_sync()
+ *
+ * This function performs a set of negotiation operations which can
+ * include: adding new contracts (neg), modifying existing vres (reneg)
+ * or cancelling existing vres (cancel).
+ *
+ * If one of the group operations has a NULL value, unless it causes an
+ * inconsistency the system will suppose that no operation of that
+ * type (neg, reneg or cancel) should be done.
+ *
+ * The virtual resources resulting from negotiations of new contracts are
+ * returned in the parameter 'new_vres' which must be provided by the user.
+ *
+ * If the on-line admission test is enabled, FRSH analizes the
+ * schedulability of the context that would result in the new
+ * contract situation with removed, changed and added contracts.
+ *
+ * A successful return code will mean that all contracts have been
+ * accepted and all required operations (creation, cancellation or
+ * update of vres) have been carried out to reach the new running
+ * context.
+ *
+ * If any of the contracts is not accepted a corresponding error shall be
+ * returned and no changes will be made to the previously running context.
+ *
+ * This call is a synchronous, potentially blocking operation. It
+ * returns when the system has rejected the contracts or accepted
+ * and made them effective.
+ *
+ * @param[in] contracts_to_neg List of new contracts to negotiate
+ * @param[in] contracts_to_reneg List of contracts to renegotiate
+ * @param[in] vres_to_reneg List of vres to renegotiate
+ * @param[in] vres_to_cancel List of vres to cancel
+ * @param[out] new_vres List of vres of new contracts.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT Invalid pointer or group identifier. \n
+ * FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS contract_label not unique. \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES: One of the provided vres_ids
+ * is not recognised. \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD The calling thread
+ * is not scheduled under FRSH. \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY: The scheduler is wrong or
+ * not running. \n
+ * FRSH_ERR_INTERNAL_ERROR: Erroneous binding or malfunction of
+ * FRSH main scheduler. \n
+ * FRSH_ERR_REJECTED_CONTRACT: The negotiation of one of the
+ * proposed contracts has failed.
+ **/
+int frsh_group_change_mode_sync
+ (const frsh_contracts_group_t *contracts_to_neg,
+ const frsh_contracts_group_t *contracts_to_reneg,
+ const frsh_vres_group_t *vres_to_reneg,
+ const frsh_vres_group_t *vres_to_cancel,
+ frsh_vres_group_t *new_vres);
+
+/**
+ * frsh_group_change_mode_async()
+ *
+ * This is an asynchronous (non-blocking) version of the previous function,
+ * frsh_group_change_mode_sync() and thus, it returns inmediately.
+ *
+ * The status of the change of mode and the identifiers for new virtual
+ * resources must be requested with the function 'frsh_group_get_status'
+ * by using the return parameter 'group'.
+ *
+ * As in the asynchronous renegotiations, when the operation is completed,
+ * the user is notified with a signal so he can check the final result with
+ * 'frsh_group_get_status'. In case that FRSH_NULL_SIGNAL is used, no
+ * signal will be sent to the user.
+ *
+ * @param[in] contracts_to_neg List of new contracts to negotiate
+ * @param[in] contracts_to_reneg List of contracts to renegotiate
+ * @param[in] vres_to_reneg List of vres to renegotiate
+ * @param[in] vres_to_cancel List of vres to cancel
+ * @param[in] signal Signal number to notify completion of
+ * the change of mode. If FRSH_NULL_SIGNAL,
+ * no signal will be raised.
+ * @param[in] signal_info Data associated to the signal
+ * @param[out] group The group identifier to get the status
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT Invalid pointer, signal or group identifier. \n
+ * FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS contract_label not unique. \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES: One of the provided vres_ids
+ * is not recognised. \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD The calling thread
+ * is not scheduled under FRSH. \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY: The scheduler is wrong or
+ * not running. \n
+ * FRSH_ERR_INTERNAL_ERROR: Erroneous binding or malfunction of
+ * FRSH main scheduler.
+ **/
+int frsh_group_change_mode_async
+ (const frsh_contracts_group_t *contracts_to_neg,
+ const frsh_contracts_group_t *contracts_to_reneg,
+ const frsh_vres_group_t *vres_to_reneg,
+ const frsh_vres_group_t *vres_to_cancel,
+ const frsh_signal_t signal,
+ const frsh_signal_info_t signal_info,
+ frsh_group_id_t *group);
+
+/**
+ * frsh_group_get_status()
+ *
+ * This function is similar to 'frsh_vres_get_renegotiation_status' but it
+ * is intented for group negotiations (changes of mode).
+ *
+ * The operation reports on the status of the last negotiation
+ * operation enqueued for the specified group identifier.
+ *
+ * The status value can be one of the following values:
+ *
+ * - FRSH_RS_IN_PROGRESS: the change of mode is in progress
+ * - FRSH_RS_REJECTED: the change of mode was not accepted
+ * - FRSH_RS_ADMITTED: the change of mode was accepted
+ * - FRSH_RS_NOT_REQUESTED: no change of mode has been requested yet
+ *
+ * When status returns 'FRSH_RS_ADMITTED', the array 'new_vres' contains
+ * the values for the new virtual resources (if there was any).
+ *
+ * This function frees the group identifier when status returns something
+ * different than FRSH_RS_IN_PROGRESS so further calls to this function may
+ * return inconsistent values.
+ *
+ * @param[in] group The group identifier
+ * @param[out] status The status of the change of mode
+ * @param[out] new_vres List of vres for the negotiation of new contracts.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT Invalid pointer, signal or group identifier. \n
+ * FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS contract_label not unique. \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES: One of the provided vres_ids
+ * is not recognised. \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD The calling thread
+ * is not scheduled under FRSH. \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY: The scheduler is wrong or
+ * not running. \n
+ * FRSH_ERR_INTERNAL_ERROR: Erroneous binding or malfunction of
+ * FRSH main scheduler.
+ **/
+int frsh_group_get_status(const frsh_group_id_t group,
+ frsh_renegotiation_status_t *status,
+ frsh_vres_group_t *new_vres);
+
+
+/*@}*/
+
+
+////////////////////////////////////////////////////
+// OBTAINING INFORMATION FROM THE SCHEDULER
+////////////////////////////////////////////////////
+
+/**
+ * @defgroup getschedinfo Obtaining information from the scheduler
+ *
+ * @ingroup core
+ *
+ * The following functions are used to obtain available budget and
+ * resource usage in the system. They can be used to adapt the
+ * execution of threads according to the load of the system.
+ *
+ * @{
+ **/
+
+
+/**
+ * frsh_config_is_admission_test_enabled()
+ *
+ * Returns true if the system is
+ * configured with the on-line admission test enabled, or false
+ * otherwise. This situation can only be changed at compile time.
+ **/
+bool frsh_config_is_admission_test_enabled();
+
+/**
+ * frsh_vres_get_usage()
+ *
+ * This function stores the current execution time spent by the
+ * threads bound to the specified vres in the variable pointed to by
+ * cpu_time.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or
+ * cpu_time is NULL \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRESR : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_vres_get_usage
+ (const frsh_vres_id_t vres,
+ frsh_rel_time_t *spent);
+
+
+/**
+ * frsh_vres_get_job_usage()
+ *
+ * Get the execution time of the current job of the specified virtual
+ * resource for a bounded or synchronized workload.
+ **/
+int frsh_vres_get_job_usage
+ (const frsh_vres_id_t vres,
+ frsh_rel_time_t *spent);
+
+
+/**
+ * frsh_vres_get_remaining_budget()
+ *
+ * This function stores in the variable pointed to by budget the
+ * remaining execution-time budget associated with the specified
+ * vres.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or
+ * budget is NULL \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_vres_get_remaining_budget
+ (const frsh_vres_id_t vres,
+ frsh_rel_time_t *budget);
+
+
+/**
+ * frsh_vres_get_budget_and_period()
+ *
+ * This function stores in the variables
+ * pointed to by budget and period, the execution-time budget and the
+ * period respectively associated with the specified vres. If any of
+ * these pointers is NULL, the corresponding information is not stored.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range,
+ * or budget and period are both NULL \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_vres_get_budget_and_period
+ (const frsh_vres_id_t vres,
+ frsh_rel_time_t *budget,
+ frsh_rel_time_t *period);
+
+/*@}*/
+
+/////////////////////////////////////////////////////////////////////
+// SERVICE THREAD TUNING
+/////////////////////////////////////////////////////////////////////
+/**
+ * @defgroup servthtuning Service thread tuning
+ *
+ * @ingroup core
+ *
+ * The following functions are used to obtain available budget and
+ * resource usage in the system. They can be used to adapt the
+ * execution of threads to the load of the system.
+ *
+ * @{
+ **/
+
+/**
+ * frsh_service_thread_set_data()
+ *
+ * This function allows the application to change the period and
+ * budget of the service thread that makes the
+ * negotiations. Increasing the utilization of this thread makes the
+ * negotiations faster, but introduces additional load in the system
+ * that may decrease the bandwidth available for the vres. For this
+ * call, the system will make a schedulability analysis to determine
+ * if the new situation is acceptable or not. This is reported back in
+ * the variable pointed to by accepted. If the new service thread data
+ * is accepted, the system will reassign budgets and periods to the
+ * vres according to the new bandwidth available, in the same way
+ * as it does for a regular contract negotiation.
+ *
+ * When its budget is exhausted, the service thread may run in the
+ * background
+ *
+ * The service thread starts with a default budget and period that are
+ * configurable
+ *
+ * Implementation dependency: in the fixed priority implementtaion of
+ * frsh, the default priority is lower than the priority of any vres,
+ * but higher than the background. According to the
+ * implementation-dependent module the priority is adjustable by means
+ * of a function that changes its preemption level
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT : if any of the pointer arguments is NULL or
+ * the budget value is greater than the period value \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_service_thread_set_data (const frsh_rel_time_t *budget,
+ const frsh_rel_time_t *period,
+ bool *accepted);
+
+/**
+ * frsh_service_thread_get_data()
+ *
+ * this function returns in the variables pointed by budget and
+ * period, respectively, the current budget and period of the service
+ * thread.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT : if any of the pointer arguments is NULL \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_service_thread_get_data
+ (frsh_rel_time_t *budget,
+ frsh_rel_time_t *period);
+
+
+/*@}*/
+
+
+////////////////////////////////////////////////////////////////////////
+// BACKGROUND MANAGEMENT
+////////////////////////////////////////////////////////////////////////
+
+//A round-robin background scheduling policy is available for those
+//threads that do not have real-time requirements. Because some of
+//these threads may require sharing information with other threads run
+//by regular vres. Special background contracts may be created for
+//specifying the synchronization requirements.
+
+//The way of specifying a background contract is by setting
+//contract_type to FRSH_CT_BACKGROUND. Negotiation may fail if the contract uses
+//shared_objects. If the contract has no shared_objects the returned
+//vres id represents the background and may be used to bind more
+//than one thread. If the contract has shared objects a vres is
+//created to keep track of them, but the associated threads are
+//executed in the background, together with the other background
+//threads
+
+
+////////////////////////////////////////////////////////////////////////
+// OTHER
+////////////////////////////////////////////////////////////////////////
+
+/**
+ * Returns resource id of local CPU.
+ *
+ * The ID is determined from environment variable FRSH_CPU_ID or, if
+ * that is not defined, the compile time default (defined in
+ * config.target/omk).
+ */
+frsh_resource_id_t frsh_get_local_cpu_id(void);
+
+FRSH_CPP_END_DECLS
+
+#endif // _FRSH_CORE_H_
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_core_types.h
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+
+#ifndef FRSH_CORE_TYPES_H_
+#define FRSH_CORE_TYPES_H_
+
+#include <stdbool.h>
+#include "frsh_time_types.h"
+#include "frsh_configuration_parameters.h"
+#include "frsh_opaque_types.h"
+#include "frsh_shared_objects_types.h"
+#include "frsh_spare_capacity_types.h"
+
+#include "frsh_implementation_specific_types.h"
+#include "frsh_hierarchical_types.h"
+#include "frsh_distributed_types.h"
+#include "frsh_error.h"
+
+#include "fosa.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_core_types.h
+ **/
+
+
+/**
+ * \addtogroup core
+ **/
+/*@{*/
+
+
+/** identifier of a frsh thread **/
+typedef fosa_thread_id_t frsh_thread_id_t;
+
+
+/** thread attributes object **/
+typedef fosa_thread_attr_t frsh_thread_attr_t;
+
+/**
+ * The type references a function that may become a thread's
+ * code
+ **/
+typedef fosa_thread_code_t frsh_thread_code_t;
+
+
+/** signal number; it is an integer type **/
+typedef fosa_signal_t frsh_signal_t;
+
+#define FRSH_NULL_SIGNAL FOSA_NULL_SIGNAL
+
+
+#define FRSH_SIGNAL_MIN FOSA_SIGNAL_MIN
+#define FRSH_SIGNAL_MAX FOSA_SIGNAL_MAX
+
+
+typedef fosa_signal_info_t frsh_signal_info_t;
+
+
+/** Kind of workload expected in vres: bounded or indeterminate **/
+typedef enum {
+ FRSH_WT_BOUNDED = 0,
+ FRSH_WT_INDETERMINATE = 1,
+ FRSH_WT_SYNCHRONIZED = 2
+} frsh_workload_t;
+/**
+ * In the synchronized workload the virtual resource hosts one or more
+ * threads that synchronize the execution of their jobs with the start
+ * of the virtual resource's period. In this kind of workload, once
+ * the threads that were activated at the beginning of the period
+ * finish their current job, the virtual resource may return any
+ * unused capacity to the system. This kind of workload can be
+ * scheduled using a regular periodic server that has the properties
+ * of being simple, having less overhead, and being able to increase
+ * the schedulability of periodic synchronized threads
+ **/
+
+#define FRSH_NULL_DEADLINE (frsh_rel_time_t *)NULL
+// #define FRSH_NULL_SIGNAL 0 /* Defined at frsh_adaption.h */
+
+/** Negotiation status: In_progress, rejected, admitted, not_requested **/
+typedef enum {FRSH_RS_IN_PROGRESS,
+ FRSH_RS_REJECTED,
+ FRSH_RS_ADMITTED,
+ FRSH_RS_NOT_REQUESTED} frsh_renegotiation_status_t;
+
+/**
+ * Vres Id type, that identifies a vres created to manage a given
+ * contract
+ **/
+typedef FRSH_VRES_ID_T_OPAQUE frsh_vres_id_t; // => 0
+
+/** Contract ressource type: processor, network, memory **/
+typedef enum {
+ FRSH_RT_PROCESSOR = 0,
+ FRSH_RT_NETWORK = 1,
+ FRSH_RT_MEMORY = 2,
+ FRSH_RT_DISK = 3,
+ FRSH_RT_FPGA = 4,
+ FRSH_RT_LCD = 5
+} frsh_resource_type_t;
+
+/** Ressource Id: processor_id or network_id **/
+/**********************************************/
+typedef fosa_resource_id_t frsh_resource_id_t;
+
+/** Kind of contract: regular, background or dummy **/
+typedef enum {
+ FRSH_CT_REGULAR = 0,
+ FRSH_CT_BACKGROUND = 1,
+ FRSH_CT_DUMMY = 2
+} frsh_contract_type_t;
+
+// The name of this constant has been updated to have the FRSH_ prefix
+typedef char frsh_contract_label_t[FRSH_CONTRACT_LABEL_MAXLENGTH + 1];
+
+/**
+ * Contract parameters type; it is an opaque type (i.e. the internal
+ * structure of this data type is implementation dependent). The user
+ * can access and modify the parameters of a contract only with the
+ * proper functions, and should never access the data directly.
+ **/
+typedef FRSH_CONTRACT_T_OPAQUE frsh_contract_t;
+
+
+/** List of vres **/
+typedef struct {
+ int size;
+ frsh_vres_id_t vres[FRSH_MAX_GROUP_OPS];
+} frsh_vres_group_t;
+
+/** List of contracts to negotiate **/
+typedef struct {
+ int size;
+ frsh_contract_t contracts[FRSH_MAX_GROUP_OPS];
+} frsh_contracts_group_t;
+
+typedef FRSH_GROUP_ID_T_OPAQUE frsh_group_id_t;
+
+/**
+ * An abstract synchronization object is defined by the application.
+ * This object can be used by an application to wait for an event to
+ * arrive by invoking the frsh_sychobj_wait() operation. It
+ * can also be used to signal the event either causing a waiting
+ * vres to wake up, or the event to be queued if no vres is
+ * waiting for it.
+ **/
+typedef FRSH_SYNCHOBJ_HANDLE_T_OPAQUE frsh_synchobj_handle_t;
+
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif /* !FRSH_CORE_TYPES_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+#ifndef _FRSH_CPP_MACROS_H_
+#define _FRSH_CPP_MACROS_H_
+
+#if defined(__cplusplus)
+#define FRSH_CPP_BEGIN_DECLS extern "C" {
+#else
+#define FRSH_CPP_BEGIN_DECLS
+#endif
+
+#if defined(__cplusplus)
+#define FRSH_CPP_END_DECLS }
+#else
+#define FRSH_CPP_END_DECLS
+#endif
+
+#endif // _FRSH_CPP_MACROS_H_
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+//
+// 23-Jul-2007 SANGORRIN: create this file for debugging functions
+// 31-Jul-2007 TELLERIA: Change "debug" for "trace"
+// -----------------------------------------------------------------------
+#ifndef FRSH_DEBUG_H
+#define FRSH_DEBUG_H
+
+#include <stdio.h> // for vprintf
+#include <stdbool.h> // for bool
+#include <stdarg.h> // for va_list, va_start and va_end
+#include "fosa.h"
+#include "frsh_debug_and_trace_types.h"
+#include "fosa_configuration_parameters.h" /* FOSA_CLOCK_REALTIME */
+#include "fosa_clocks_and_timers.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+// Tune the following FLAGS to select the debugging messages to be generated
+#define FRSH_TRACE_CALLBACKS false
+#define FRSH_TRACE_SERVICE_TH false
+#define FRSH_TRACE_WATCHDOG false
+#define FRSH_TRACE_SPORADIC_SERVER false
+#define FRSH_TRACE_REPLENISHMENTS false
+#define FRSH_TRACE_ROUND_ROBIN false
+#define FRSH_TRACE_BOUNDED_JOB false
+#define FRSH_TRACE_SYNCHRONIZE_WORKLOAD false
+#define FRSH_TRACE_ADMISSION_TEST false
+#define FRSH_TRACE_ADMISSION_RESULT false
+
+#define FRSH_TRACE_THREAD_INDEX false
+#define FRSH_TRACE_VRES_INDEX false
+
+#define FRSH_TRACE_DISTRIBUTED false
+
+#define QUICK_AND_DIRTY_FIX_JLDEMO true
+
+
+/**
+ * frsh_trace_point_insert()
+ *
+ * Insert an application-defined trace-point identifier together with
+ * a timestamp into the trace log, if tracing is enabled; the
+ * identifier is an integer that must be between two configurable
+ * values defined in the FRSH API as constants; if tracing is not
+ * enabled, this function has no effect.
+ */
+int frsh_trace_point_insert(frsh_trace_point_id_t ipoint);
+
+/** If FRSH_TRACE_TS_MSECS is defined, each trace line is prefixed
+ with a msec counter **/
+#define FRSH_TRACE_TS_MSECS
+
+/* These variables live defined in frsh_error.c */
+/************************************************/
+extern fosa_abs_time_t frsh_trace_init_timespec;
+extern long frsh_trace_init_timemsec;
+
+extern int global_error_condition; /* Used to propagate error
+ * conditions in debugging */
+
+static inline long int FRSH_GET_TIMESTAMP_MSECS()
+{
+ int terror = -1;
+ fosa_abs_time_t current_time;
+ long int current_time_msec = -1;
+ long int result = -1;
+
+ PRW( fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time) );
+ current_time_msec = fosa_abs_time_to_msec(current_time);
+
+ result = current_time_msec - frsh_trace_init_timemsec;
+
+ return result;
+}
+
+static inline long int FRSH_TIMESTAMP_TO_RELATIVE_MSECS(const fosa_abs_time_t *timestamp)
+{
+ long int time_msecs = -1;
+
+ time_msecs = fosa_abs_time_to_msec(*timestamp);
+
+ return time_msecs - frsh_trace_init_timemsec;
+}
+
+/**
+ * FRSH_TRACE()
+ *
+ * If the boolean value is true, print the format line optionally
+ * preceded by a timestamp in ms relative to the start of the
+ * program.
+ *
+ * Due to the "..." argument passing, this function cannot be
+ * inlined.
+ **/
+void FRSH_TRACE(bool is_active, const char *format, ...);
+
+FRSH_CPP_END_DECLS
+
+#endif
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+//
+// 23-Jul-2007 SANGORRIN: create this file for debugging functions
+// 31-Jul-2007 TELLERIA: Change "debug" for "trace"
+// -----------------------------------------------------------------------
+#ifndef FRSH_DEBUG_AND_TRACE_TYPES_H_
+#define FRSH_DEBUG_AND_TRACE_TYPES_H_
+
+FRSH_CPP_BEGIN_DECLS
+
+/** identifier of a trace point **/
+typedef int frsh_trace_point_id_t;
+
+/** constants that describe the valid range of trace point identifiers **/
+#define FRSH_TRACE_POINT_ID_MIN 0
+#define FRSH_TRACE_POINT_ID_MAX 10
+
+FRSH_CPP_END_DECLS
+
+#endif /* !FRSH_DEBUG_AND_TRACE_TYPES_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_distributed.h
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef _FRSH_DISTRIBUTED_H_
+#define _FRSH_DISTRIBUTED_H_
+
+
+/**
+ * @file frsh_distributed.h
+ **/
+
+
+#include "frsh_distributed_types.h"
+#include "frsh_core_types.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+// this global variable is assigned by frsh_distributed_init()
+extern frsh_resource_id_t THE_FRSH_CPU_ID;
+
+typedef enum {
+ FRSH_NETPF_FRESCAN = 0,
+ FRSH_NETPF_RTEP = 1,
+ FRSH_NETPF_UNIX = 2,
+ FRSH_NETPF_FWP = 3,
+ FRSH_NETPF_CLUSTER_TREE = 4,
+ FRSH_NETPF_ITEM = 5,
+} frsh_netpf_t;
+
+/**
+ * @defgroup distributed Distributed module
+ *
+ * This module defines the functions and typedefs for use in
+ * distributed applications.
+ *
+ * Each network is identified by its resource_id and FRSH hides its
+ * characteristics completely. The type of network is implied with
+ * its ID via a configuration table defined at compile time.
+ *
+ * FRSH uses the "message" as the atomic unit for every exchange.
+ * Queue sizes are measured in number of pending messages.
+ *
+ * FRSH provides a function to calculate the transmision time needed
+ * for a certain message size in a network as well as the maximum
+ * message size that can admit.
+ *
+ * Note also that package delivery guarantee is protocol dependent.
+ * For protocols in which the order is no guaranteed, the application
+ * needs to add extra info to detect possible package disorder.
+ *
+ * Summary of typical steps.
+ *
+ * 1. Map (internally in FRSH implementation)
+ * - node--> network_addresses
+ * - network --> resource_id's
+ * - unidirectional communication channel --> stream_id
+ * - other config --> protocol_info.
+ *
+ * 2. In a sending node:
+ * 2.1. Negotiates a "network contract" per communication channel
+ * that is used in the application. In the contract it is
+ * specified:
+ * - frsh_resource_type = FRSH_RT_NETWORK.
+ * - frsh_resource_id = <network id #>
+ * - budget: Time needed to send the required data per period.
+ * (you can use frsh_netinfo_*() functions for this).
+ * - period: Period of sendings.
+ * - Queueing info: How will sends be queued at sendEndpoint.
+ * - Other protocol dependent function in protocol_contract_info.
+ * 2.2. Create a send_endpoint per any unidirectional stream that will
+ * be used in sending
+ * resource_id --> the network through which the stream will
+ * flow (this is extra info needed for coherency
+ * with the bind).
+ * destinator --> network_address of the destination.
+ * stream_id --> the unidirectional communication channel.
+ * 2.3. Bind the send_endpoint to the network contract negotiated
+ * above.
+ * 2.4. The (processor) sending vres invokes frsh_send_(a)sync() to
+ * send the data through the corresponding stream.
+ *
+ * 3. In a receiving node:
+ * 3.1. Create a receive_endpoint per any unidirectional stream
+ * that will be used in receiving.
+ * 3.2. The processor expecting a reception of message invokes
+ * frsh_receive_(a)sync() to read the incoming data.
+ *
+ * 4. When all comunication is finished and the channel is no longer
+ * needed the nodes will destroy the send and receive endpoints
+ * and the network contract will be canceled.
+ **/
+
+/**
+ * frsh_distributed_init(void)
+ *
+ * This operation initializes all the installed networks and the structures
+ * that are necessary for the distributed module. Currently it is called by
+ * frsh_init so it is not necessary that the user calls it again.
+ *
+ * 0: No error \n
+ * FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ *
+ **/
+int frsh_distributed_init(void);
+
+//////////////////////////////////////////////////////////////////////
+// CONTRACT ASPECTS
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup distcontract Contract Info for Distributed Systems
+ * @ingroup distributed
+ *
+ * These functions help you calculate the needed budget for network
+ * contracts and also to include protocol dependent info in contract
+ * parameters.
+ *
+ * @{
+ **/
+
+/**
+ * frsh_network_get_max_message_size()
+ *
+ * This operation gives the maximum number of bytes that can be sent
+ * at a time through the send function when using the network designated by
+ * 'resource_id' and sending it to 'destination'.
+ *
+ * If the application needs to send bigger messages it will have to
+ * split them.
+ *
+ * Some protocols, like IP, are capable of sending large messages
+ * (and use fragmentation internally) but other protocols don't.
+ *
+ * @param[in] resource_id The network we want the tx time from.
+ * @param[in] destination The destination address
+ * @param[out] max_size The maximum number of bytes for each message
+ *
+ * @return
+ * FRSH_NO_ERROR \n
+ * FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FRSH_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
+ * invalid \n
+ *
+ **/
+int frsh_network_get_max_message_size
+ (const frsh_resource_id_t resource_id,
+ const frsh_network_address_t destination,
+ size_t *max_size);
+
+/**
+ * frsh_network_bytes_to_budget()
+ *
+ * This operation converts a number of bytes into a temporal budget for
+ * a specific network. Network overheads are not included here but are
+ * considered internally when negotiating a specific contract.
+ *
+ * @param[in] resource_id The network
+ * @param[in] nbytes Number of bytes
+ * @param[out] budget The network budget for nbytes
+ *
+ * @return
+ * FRSH_NO_ERROR \n
+ * FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FRSH_ERR_BAD_ARGUMENT: if pointers are NULL or nbytes is less
+ * than zero \n
+ *
+ **/
+int frsh_network_bytes_to_budget
+ (const frsh_resource_id_t resource_id,
+ const size_t nbytes,
+ frsh_rel_time_t *budget);
+
+/**
+ * frsh_network_budget_to_bytes()
+ *
+ * This operation converts a temporal budget into a number of bytes for
+ * a specific network. Network overheads are not included.
+ *
+ * @param[in] resource_id The network
+ * @param[in] budget The network budget for nbytes
+ * @param[out] nbytes Number of bytes
+ *
+ * @return
+ * FRSH_NO_ERROR \n
+ * FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FRSH_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
+ * an invalid time value \n
+ *
+ **/
+int frsh_network_budget_to_bytes
+ (const frsh_resource_id_t resource_id,
+ const frsh_rel_time_t *budget,
+ size_t *nbytes);
+
+/**
+ * frsh_network_get_min_effective_budget()
+ *
+ * This operation gets the minimum effective budget for a network. Each message
+ * consumes a contracted budget in "chunks" (i.e: packets) that we call
+ * minimum effective budget.
+ *
+ * A negotiated contract, for N bytes in a period T, means that there is a
+ * virtual resource that reserves for the user:
+ *
+ * Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
+ *
+ * Note that if the user decides not to send these N bytes at once but, say,
+ * one byte at a time, it will consume one "CHUNK" at a time and the reserved
+ * budget will become exhausted before sending all the bytes.
+ *
+ * @param[in] resource_id The network
+ * @param[out] budget The network budget
+ *
+ * @return
+ * FRSH_NO_ERROR \n
+ * FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FRSH_ERR_BAD_ARGUMENT: if pointers are NULL \n
+ *
+ **/
+int frsh_network_get_min_effective_budget
+ (const frsh_resource_id_t resource_id,
+ frsh_rel_time_t *budget);
+
+/**
+ * frsh_contract_set_queueing_info()
+ *
+ * This function adds queueing parameters that will be used in the
+ * sendEndpoint when the sendEndpoint is bound to the vres.
+ **/
+int frsh_contract_set_queueing_info(frsh_endpoint_queueing_info_t queueing_info,
+ frsh_contract_t *contract);
+
+/**
+ * frsh_contract_get_queueing_info()
+ *
+ * This function gets the queueing parameters that were specified in
+ * the network contract.
+ **/
+int frsh_contract_get_queueing_info(const frsh_contract_t *contract,
+ frsh_endpoint_queueing_info_t *queueing_info);
+
+/**
+ * frsh_contract_set_protocol_info
+ *
+ * We add protocol info to the contract
+ **/
+int frsh_contract_set_protocol_info(frsh_protocol_info_t protocol_info,
+ frsh_contract_t *contract);
+
+/**
+ * frsh_contract_get_protocol_info
+ *
+ * We get protocol info from the contract
+ **/
+int frsh_contract_get_protocol_info(frsh_contract_t *contract,
+ frsh_protocol_info_t *protocol_info);
+
+/**
+ * frsh_contract_marshal
+ *
+ * Convert a contract to a sequence of bytes of minimum size so it can
+ * be sent through the network with the minimum amount of bytes.
+ *
+ **/
+
+int frsh_contract_marshal(const frsh_contract_t *contract,
+ unsigned char *buffer,
+ const size_t buffer_size,
+ size_t *size);
+
+/**
+ * frsh_contract_unmarshal
+ *
+ * Convert a sequence of bytes generated by frsh_contract_marshal to a contract
+ *
+ **/
+
+int frsh_contract_unmarshal(frsh_contract_t *contract,
+ const unsigned char *marshal_bytes,
+ const size_t size);
+
+/*@}*/
+//////////////////////////////////////////////////////////////////////
+// TWO STEP NEGOTIATION
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup twostepnego Two Step Negotiation
+ * @ingroup distributed
+ *
+ * Using the core services of FRSH, contracts may be negotiated in a
+ * single step.
+ *
+ * An alternative two-step negotiation process is introduced in the
+ * distribution module: the first step involves the reservation of the
+ * resources, but without the right to use them, and the second step
+ * is the commitment to use those resources.
+ *
+ * The rationale behind this approach is that in distributed systems,
+ * when a distributed transaction is being negotiated the system
+ * should only commit the virtual resources that were negotiated with
+ * various nodes in the system if the results of all negotiations
+ * match together. This approach enhances the efficiency since the
+ * actual temporal values of the virtual resources on distributed
+ * nodes are only changed if the initiator of the distributed
+ * transaction is satisfied with the results of the negotiations.
+ *
+ * After the reservation, it is not necessary to change the actual
+ * virtual resource attributes (and modifying the schedule) on each
+ * node before the initiator of the distributed transaction knows the
+ * amount of available virtual resources. A renegotiation of a
+ * reserved virtual resource is possible, to harmonize for the
+ * available virtual resources in other parts of the system, before a
+ * final commitment is made.
+ *
+ * @{
+ **/
+
+
+/**
+ * frsh_contract_negotiate_reservation()
+ *
+ * Negotiate a service contract, obtaining a virtual resource id that
+ * represents a reservation of resources, but without the right to use
+ * those resources until the reservation is committed via
+ * frsh_vres_commit_reservation. In particular, this virtual resource
+ * cannot be bound until committed, but renegotiations are allowed for
+ * it.
+ */
+int frsh_contract_negotiate_reservation
+ (const frsh_contract_t *contract,
+ frsh_vres_id_t *vres);
+
+/**
+ * frsh_vres_commit_reservation()
+ *
+ * Commit the resources reserved for a virtual resource through a
+ * frsh_contract_negotiate_reservation operation. The effects of
+ * subsequent calls to frsh_contract_negotiate_reservation and
+ * frsh_vres_commit_reservation are equivalent to a single call to
+ * frsh_contract_negotiate.
+ */
+int frsh_vres_commit_reservation
+ (const frsh_vres_id_t vres);
+
+/* @} */
+
+
+
+//////////////////////////////////////////////////////////////////////
+// TRANSMISSION SERVICES
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * @defgroup txservices Transmission services
+ * @ingroup distributed
+ *
+ * These functions allow to create and manage endpoints for sending
+ * and receiving and to perform send and receive operations both
+ * synchronously (blocking) and asynchronously (non-blocking).
+ *
+ * @{
+ **/
+
+
+/**
+ * frsh_send_endpoint_create()
+ *
+ * This operation creates a unidirectional stream input endpoint
+ * through which, after the corresponding binding, it is possible to
+ * send data to a unicast or multicast destination.
+ *
+ * @param[in] resource_id Identifier of the network referred in the
+ * network contract as a resource_id.
+ * @param[in] destination FRSH abstraction of the protocol address for the
+ * destinator node.
+ * @param[in] stream_id Identifier of the communication channel between
+ * the nodes. Multiplexing is achieved by using
+ * different streams between the same nodes and the
+ * same network.
+ * @param[in] queueing_info Queueing params of the endpoint (size and
+ * policy).
+ * @param[in] protocol_info Optional protocol-dependent info.
+ * @param[out] endpoint Placeholder for the endpoint object.
+ **/
+int frsh_send_endpoint_create
+ (frsh_resource_id_t resource_id,
+ frsh_network_address_t destination,
+ frsh_stream_id_t stream_id,
+ frsh_send_endpoint_protocol_info_t protocol_info,
+ frsh_send_endpoint_t *endpoint);
+
+/**
+ * frsh_send_endpoint_get_params()
+ *
+ * This operation returns in the variables associated to the
+ * endpoint at creation time.
+ **/
+int frsh_send_endpoint_get_params
+ (const frsh_send_endpoint_t endpoint,
+ frsh_resource_id_t *resource_id,
+ frsh_network_address_t *destination,
+ frsh_stream_id_t *stream,
+ frsh_send_endpoint_protocol_info_t *protocol_info);
+
+/**
+ * frsh_send_endpoint_destroy()
+ *
+ * This operation eliminates any resources reserved for the referenced
+ * endpoint. Pending messages will be discarded and processor-vres
+ * waiting in a synchronous operation will be awoken with an error
+ * code.
+ **/
+int frsh_send_endpoint_destroy
+ (frsh_send_endpoint_t endpoint);
+
+/**
+ * frsh_send_endpoint_bind()
+ *
+ * This operation associates a send endpoint with a network vres,
+ * which means that messages sent through this endpoint will consume
+ * the vres's reserved bandwidth and its packets will be sent
+ * according to the contract established for that vres.
+ *
+ * If the endpoint is already bound to another vres, it is effectively
+ * unbound from it and bound to the specified one. However if a vres
+ * is already bound to another endpoint an error is returned.
+ *
+ * A consistency check is done in which the resource_id specified at
+ * endpoint creation must correspond to the resource_id of the vres
+ * contract.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT if the endpoint or the vres are not
+ * valid \n
+ * FRSH_ERR_ALREADY_BOUND if the vres is already bound to some
+ * other send endpoint \n
+ * FRSH_ERR_WRONG_NETWORK if the vres network id is not the same
+ * as the one in the endpoint \n
+ **/
+int frsh_send_endpoint_bind
+ (frsh_vres_id_t vres,
+ frsh_send_endpoint_t endpoint);
+
+/**
+ * frsh_send_endpoint_unbind()
+ *
+ * This operation unbinds a send endpoint from a vres. Endpoints with
+ * no vres associated cannot be used to send data, and they stay in
+ * that state until they are either eliminated or bound again.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_NOT_BOUND if the endpoint was not bound \n
+ **/
+int frsh_send_endpoint_unbind
+ (frsh_send_endpoint_t endpoint);
+
+/**
+ * frsh_send_endpoint_get_vres_id()
+ *
+ * This operation copies the id of the vres that is bound to the
+ * specified send endpoint into the variable pointed to by vres.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_NOT_BOUND if the endpoint was not bound \n
+ * FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid or vres
+ * is NULL \n
+ **/
+int frsh_send_endpoint_get_vres_id
+ (const frsh_send_endpoint_t endpoint,
+ frsh_vres_id_t *vres);
+
+/**
+ * frsh_send_async()
+ *
+ * This operation sends a message stored in msg and of length size
+ * through the given endpoint. The operation is non-blocking and
+ * returns immediately.
+ *
+ * An internal frsh service will schedule the sending of messages and
+ * implement the communications sporadic vres corresponding to the
+ * network vres bound to the given endpoint.
+ *
+ * @returns 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT if endpoint is not valid \n
+ * FRSH_ERR_NOT_BOUND if endpoint is not bound to a valid vres \n
+ * FRSH_ERR_TOO_LARGE if the message is too large for the
+ * network protocol \n
+ * FRSH_ERR_BUFFER_FULL if the message has been discarded
+ * because the queue is full (and does not
+ * have the policy FRSH_QP_OLDEST \n
+ **/
+int frsh_send_async
+ (const frsh_send_endpoint_t endpoint,
+ const void *msg,
+ const size_t size);
+
+/**
+ * frsh_send_sync()
+ *
+ * Similar to previous function but now the sending vres gets blocked
+ * until the message is processed.
+ **/
+int frsh_send_sync
+ (const frsh_send_endpoint_t endpoint,
+ const void *msg,
+ size_t size);
+
+/**
+ * frsh_send_endpoint_get_status()
+ *
+ * This function tells the number of messages still pending in the
+ * endpoint queue, whether the network is up or down with some
+ * optional information which is protocol_dependent.
+ **/
+int frsh_send_endpoint_get_status
+ (const frsh_send_endpoint_t endpoint,
+ int *number_pending_msg,
+ frsh_endpoint_network_status_t *network_status,
+ frsh_protocol_status_t *protocol_status);
+
+/**
+ * frsh_receive_endpoint_create()
+ *
+ * This operation creates a receive endpoint associated with a
+ * undirectional stream within a network interface of the node.
+ *
+ * Receiving endpoints are not bound to any network vres, this is
+ * because don't originate any traffic.
+ *
+ * Note that the protocol address is not needed for reception because
+ * it can be determined internally by FRSH based on the resource_id.
+ *
+ * Note also that messages may come from diferent originators.
+ *
+ * @param[in] resource_id Id of the network from which we listen.
+ * @param[in] stream_id Id of the stream within the network.
+ * @param[in] queueing_info Buffering information(queue size and
+ * policy).
+ * @param[in] protocol_info Extra protocol info opaque for the
+ * application.
+ * @param[in] endpoin Placeholder for the endpoint object.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT if the stream or the network id are not
+ * valid \n
+ **/
+int frsh_receive_endpoint_create
+ (frsh_resource_id_t resource_id,
+ frsh_stream_id_t stream_id,
+ frsh_endpoint_queueing_info_t queueing_info,
+ frsh_receive_endpoint_protocol_info_t protocol_info,
+ frsh_receive_endpoint_t *endpoint);
+
+/**
+ * frsh_receive_endpoint_get_params()
+ *
+ * This operation returns in the variables associated to the
+ * endpoint at creation time.
+ **/
+int frsh_receive_endpoint_get_params
+ (const frsh_receive_endpoint_t endpoint,
+ frsh_resource_id_t *resource_id,
+ frsh_stream_id_t *stream,
+ frsh_endpoint_queueing_info_t *queueing_info,
+ frsh_receive_endpoint_protocol_info_t *protocol_info);
+
+/**
+ * frsh_receive_endpoint_destroy()
+ *
+ * This operation eliminates any resources reserved for the referenced
+ * endpoint. Pending messages will be discarded and processor-vres
+ * waiting in a synchronous operation will be awoken with an error
+ * code.
+ **/
+int frsh_receive_endpoint_destroy
+ (frsh_receive_endpoint_t endpoint);
+
+
+/**
+ * frsh_receive_sync()
+ *
+ * If there are no messages available in the specified receive endpoint
+ * this operation blocks the calling thread waiting for a message to be
+ * received.
+ *
+ * When a message is available, if its size is less than or
+ * equal to the buffer_size, the function stores it in the variable
+ * pointed to by buffer and puts the number of bytes received in the
+ * variable pointed to by message size.
+ *
+ * The function fails with FRSH_ERR_NO_SPACE if the buffersize is
+ * too small for the message received. In this case the message is
+ * lost.
+ *
+ * Messages arriving at a destination buffer that is full will be
+ * silently discarded (details in the queueing policy of the
+ * endpoint). The application is responsible of reading the receive
+ * endpoints with appropriate regularity, or of using a sequence
+ * number or some other mechanism to detect any lost messages.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid, or if
+ * buffer or message_size are NULL.\n
+ * FRSH_ERR_NO_SPACE if the message size is bigger than the
+ * provided buffer \n
+ **/
+int frsh_receive_sync
+ (const frsh_receive_endpoint_t endpoint,
+ void *buffer,
+ size_t buffer_size,
+ size_t *message_size,
+ frsh_network_address_t *from);
+
+/**
+ * frsh_receive_async()
+ *
+ * This operation is similar to the previous one but it works in a non
+ * blocking (asynchronous) fashion. If no message is available it
+ * returns with error FRSH_NO_MESSAGE.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid, or if
+ * buffer or message_size are NULL \n
+ * FRSH_NO_MESSAGE if no messages are available in the queue \n
+ * FRSH_ERR_NO_SPACE if the message size is bigger than the
+ * provided buffer \n
+ **/
+int frsh_receive_async
+ (const frsh_receive_endpoint_t endpoint,
+ void *buffer,
+ size_t buffer_size,
+ size_t *message_size,
+ frsh_network_address_t *from);
+
+
+/**
+ * frsh_receive_endpoint_get_status
+ *
+ * This function tells the number of messages still pending in the
+ * endpoint queue, whether the network is up or down and some optional
+ * information which is protocol dependent.
+ **/
+int frsh_receive_endpoint_get_status
+ (const frsh_receive_endpoint_t endpoint,
+ int *number_pending_messages,
+ frsh_endpoint_network_status_t *network_status,
+ frsh_protocol_status_t *protocol_status);
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif // _FRSH_DISTRIBUTED_H_
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef FRSH_DISTRIBUTED_TYPES_H_
+#define FRSH_DISTRIBUTED_TYPES_H_
+
+/**
+ * @file frsh_distributed_types.h
+ **/
+
+#include "frsh_opaque_types.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @addtogroup distributed
+ *
+ * @{
+ **/
+
+//opaque types for frsh endpoints
+typedef FRSH_SEND_ENDPOINT_T_OPAQUE frsh_send_endpoint_t;
+typedef FRSH_RECEIVE_ENDPOINT_T_OPAQUE frsh_receive_endpoint_t;
+
+/**
+ * The network_address type specifies the node or multicast address in
+ * a communication-protocol-independent way. The actual address is
+ * obtained via a configuration dependent mapping function
+ **/
+typedef unsigned int frsh_network_address_t;
+
+/**
+ * The port type specifies the information that is
+ * necessary to get in contact with the thread in the
+ * receiving node, in a protocol-independent way.
+ * The actual port number is obtained via a configuration
+ * dependent mapping function
+ **/
+typedef unsigned int frsh_stream_id_t;
+
+/**
+ * Extra information protocol dependent opaque for the application.
+ * It can be used in different places: contract negotiation, extra
+ * endpoint info, extra status info...
+ **/
+typedef struct {
+ void *body;
+ int size;
+} frsh_protocol_info_t;
+
+/**
+ * Protocol dependent information about the status of an endpoint
+ **/
+typedef struct {
+ void *body;
+ int size;
+} frsh_protocol_status_t;
+
+/**
+ * Protocol dependent information about extra parameters for
+ * send_endpoint definition.
+ **/
+typedef struct {
+ void *body;
+ int size;
+} frsh_send_endpoint_protocol_info_t;
+
+/**
+ * Protocol dependent information about extra parameters for
+ * receive_endpoint definition.
+ **/
+typedef struct {
+ void *body;
+ int size;
+} frsh_receive_endpoint_protocol_info_t;
+
+/**
+ * Algorithm used when the queue is full to choose the message to reject
+ **/
+typedef enum {
+ /** A new message is admitted rejecting the oldest message in the
+ queue to make room for the newcomer **/
+ FRSH_QRP_OLDEST,
+
+ /** Incoming messages are rejected if the queue is full **/
+ FRSH_QRP_NEWCOMER
+} frsh_queue_rejection_policy_t;
+
+/**
+ * Queing information for endpoints
+ **/
+typedef struct {
+ int queue_size; /** Size 0 means that there is no queue **/
+ frsh_queue_rejection_policy_t queue_policy;
+} frsh_endpoint_queueing_info_t;
+
+
+typedef enum {
+ /** Network works OK **/
+ FRSH_ENS_UP,
+
+ /** Network is down **/
+ FRSH_ENS_DOWN
+} frsh_endpoint_network_status_t;
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif /* !FRSH_DISTRIBUTED_TYPES_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_dynamic_reclaiming.h
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef _FRSH_DYNAMIC_RECLAIMING_H_
+#define _FRSH_DYNAMIC_RECLAIMING_H_
+
+#include "frsh_core.h"
+
+/**
+ * @file frsh_dynamic_reclaiming.h
+ *
+ * If this define is activated, dynamic reclaimation will be used
+ * after spare capacity allocation.
+ **/
+
+
+#define FRSH_DYNAMIC_RECLAIMING_MODULE_SUPPORTED 1
+
+
+#endif // _FRSH_DYNAMIC_RECLAIMING_H_
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_energy_management.h
+
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef _FRSH_ENERGY_MANAGEMENT_H_
+#define _FRSH_ENERGY_MANAGEMENT_H_
+
+#include <time.h>
+
+#include "frsh_energy_management_types.h"
+#include "frsh_core_types.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+#define FRSH_ENERGY_MANAGEMENT_MODULE_SUPPORTED 1
+
+/**
+ * @file frsh_energy_management.h
+ **/
+
+/**
+ * @defgroup energymgmnt Energy Management Module
+ *
+ * This module provides the ability to specify different budgets for
+ * different power levels.
+ *
+ * We model the situation by specifying budget values per power
+ * level. Thus switching in the power-level would be done by changing
+ * the budget of the vres. In all cases the period remains the same.
+ *
+ * All global FRSH contract operations (those done with the core
+ * module without specifying the power level) are considered to be
+ * applied to the higest power level, corresponding to a power_level_t
+ * value of 0.
+ *
+ * @note
+ * For all functions that operate on a contract, the resource is
+ * implicitly identified by the contract core parameters resource_type
+ * and resource_id that are either set through the
+ * frsh_contract_set_resource_and_label() function, or implicitly
+ * defined if no such call is made.
+ *
+ * @note
+ * For the power level management operations, only
+ * implementation for resource_type = FRSH_RT_PROCESSOR is mandatory,
+ * if the energy management module is present.
+ *
+ * @{
+ *
+ **/
+
+
+
+//////////////////////////////////////////////////////////////////////
+// CONTRACT SERVICES
+//////////////////////////////////////////////////////////////////////
+
+
+/**
+ * frsh_contract_set_min_expiration()
+ *
+ * This function sets the minimum battery expiration time that the
+ * system must be able to sustain without finishing battery power. A
+ * value of (0,0) would mean that the application does not have such
+ * requirement (this is the default if this parameter is not explicitly
+ * set).
+ **/
+int frsh_contract_set_min_expiration(frsh_contract_t *contract,
+ frsh_rel_time_t min_expiration);
+
+/**
+ * frsh_contract_get_min_expiration()
+ *
+ * Get version of the previous function.
+ **/
+int frsh_contract_get_min_expiration(const frsh_contract_t *contract,
+ frsh_rel_time_t *min_expiration);
+
+/**
+ * frsh_contract_set_min_budget_pow()
+ *
+ * Here we specify the minimum budget value corresponding to a single
+ * power level.
+ *
+ * @param contract The affected contract.
+ * @param power_level The power level for which we are specifying the minimum budget.
+ * @param pow_min_budget The minimum budget requested for the power level.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT if power_level is greater than or equal to the value
+ * returned by frsh_get_power_levels budget value is not correct.
+ *
+ * @note
+ * If the minimum budget relative to one or more power levels has not been specified, then
+ * the framework may attempt to perform interpolation of the supplied values in
+ * order to infer them, if an accurate model for such operation is available.
+ * Otherwise, the contract is rejected at frsh_negotiate() time.
+ **/
+int frsh_contract_set_min_budget_pow(frsh_contract_t *contract,
+ frsh_power_level_t power_level,
+ const frsh_rel_time_t *pow_min_budget);
+
+/**
+ * frsh_contract_get_min_budget_pow()
+ *
+ * Get version of the previous function.
+ **/
+int frsh_contract_get_min_budget_pow(const frsh_contract_t *contract,
+ frsh_power_level_t power_level,
+ frsh_rel_time_t *pow_min_budget);
+
+/**
+ * frsh_contract_set_max_budget_pow()
+ *
+ * Here we specify the maximum budget for a single power level.
+ *
+ * @param contract The affected contract object.
+ * @param power_level The power level for which we are specifying the maximum budget.
+ * @param pow_max_budget The maximum budget requested for the power level.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT if any of the pointers is NULL or the
+ * budget values don't go in ascending order.
+ *
+ **/
+int frsh_contract_set_max_budget_pow(frsh_contract_t *contract,
+ frsh_power_level_t power_level,
+ const frsh_rel_time_t *pow_max_budget);
+
+/**
+ * frsh_contract_get_max_budget_pow()
+ *
+ * Get version of the previous function.
+ **/
+int frsh_contract_get_max_budget_pow(const frsh_contract_t *contract,
+ frsh_power_level_t power_level,
+ frsh_rel_time_t *pow_max_budget);
+
+
+/**
+ * frsh_contract_set_utilization_pow()
+ *
+ * This function should be used for contracts with a period of
+ * discrete granularity. Here we specify, for each allowed period,
+ * the budget to be used for each power level.
+ *
+ * @param contract The affected contract object.
+ * @param power_level The power level for which we specify budget and period.
+ * @param budget The budget to be used for the supplied power level and period.
+ * @param period One of the allowed periods (from the discrete set).
+ * @param period The deadline used with the associated period (from the discrete set).
+ **/
+int frsh_contract_set_utilization_pow(frsh_contract_t *contract,
+ frsh_power_level_t power_level,
+ const frsh_rel_time_t *budget,
+ const frsh_rel_time_t *period,
+ const frsh_rel_time_t *deadline);
+
+/**
+ * frsh_contract_get_utilization_pow()
+ *
+ * Get version of the previous function.
+ **/
+int frsh_contract_get_utilization_pow(const frsh_contract_t *contract,
+ frsh_power_level_t power_level,
+ frsh_rel_time_t *budget,
+ frsh_rel_time_t *period,
+ frsh_rel_time_t *deadline);
+
+
+//////////////////////////////////////////////////////////////////////
+// MANAGING THE POWER LEVEL
+//////////////////////////////////////////////////////////////////////
+
+/**
+ * frsh_resource_set_power_level()
+ *
+ * Set the power level of the resource identified by the supplied type and id.
+ *
+ * @note
+ * Only implementation for resource_type = FRSH_RT_PROCESSOR is mandatory,
+ * if the energy management module is present.
+ **/
+int frsh_resource_set_power_level(frsh_resource_type_t resource_type,
+ frsh_resource_id_t resource_id,
+ frsh_power_level_t power_level);
+
+/**
+ * frsh_resource_get_power_level()
+ *
+ * Get version of the previous function.
+ **/
+int frsh_resource_get_power_level(frsh_resource_type_t resource_type,
+ frsh_resource_id_t resource_id,
+ frsh_power_level_t *power_level);
+
+/**
+ * frsh_resource_get_speed()
+ *
+ * Get in speed_ratio representative value for the speed of the specified
+ * resource, with respect to the maximum possible speed for such resource.
+ *
+ * @note
+ * Only implementation for resource_type = FRSH_RT_PROCESSOR is mandatory,
+ * if the energy management module is present.
+ **/
+int frsh_resource_get_speed(frsh_resource_type_t resource_type,
+ frsh_resource_id_t resource_id,
+ frsh_power_level_t power_level,
+ double *speed_ratio);
+
+/**
+ * frsh_resource_get_num_power_levels()
+ *
+ * Get the number of power levels available for the resource identified
+ * by the supplied type and id.
+ *
+ * @note
+ * The power levels that may be used, for the identified resource,
+ * in other functions through a power_level_t type, range from 0
+ * to the value returned by this function minus 1.
+ *
+ * @note
+ * The power level 0 identifies the configuration with the maximum
+ * performance (and energy consumption) for the resource.
+ *
+ * @note
+ * Only implementation for resource_type = FRSH_RT_PROCESSOR is mandatory,
+ * if the energy management module is present.
+ */
+int frsh_resource_get_num_power_levels(frsh_resource_type_t resource_type,
+ frsh_resource_id_t resource_id,
+ int *num_power_levels);
+
+//////////////////////////////////////////////////////////////////////
+// BATTERY EXPIRATION AND MANAGING POWER LEVELS
+//////////////////////////////////////////////////////////////////////
+
+/* /\** IS THIS NEEDED AT ALL ? I GUESS NOT - COMMENTED */
+/* * frsh_resource_get_battery_expiration() */
+/* * */
+/* * Get the foreseen expiration time of the battery for the resource */
+/* * identified by the supplied type and id. */
+/* * */
+/* int frsh_battery_get_expiration(frsh_resource_type_t resource_type, */
+/* frsh_resource_id_t resource_id, */
+/* frsh_rel_time_t *expiration); */
+
+/**
+ * frsh_battery_get_expiration()
+ *
+ * Get the foreseen expiration time of the system battery(ies).
+ **/
+int frsh_battery_get_expiration(frsh_abs_time_t *expiration);
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif /* _FRSH_ENERGY_MANAGEMENT_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_energy_management_types.h
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef FRSH_ENERGY_MANAGEMENT_TYPES_H_
+#define FRSH_ENERGY_MANAGEMENT_TYPES_H_
+
+#include <time.h>
+#include "frsh_core_types.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_energy_management_types.h
+ **/
+
+/**
+ * @addtogroup energymgmnt
+ *
+ * @{
+ **/
+
+
+
+
+/**
+ * Here we define the different power levels. They will be
+ * used as index to the budget arrays in energy management.
+ **/
+typedef enum {
+ FRSH_PLT_HIGH = 0,
+ FRSH_PLT_MEDIUM = 1,
+ FRSH_PLT_LOW = 2
+} frsh_power_level_t;
+
+
+/**
+ * Here we define a capacity specification for all power levels.
+ **/
+typedef struct {
+ frsh_rel_time_t budget[3];
+ frsh_rel_time_t period;
+} frsh_utilization_line_pow_t;
+
+/**
+ * Here we define the utilization set for different power levels
+ **/
+typedef struct {
+ int size;
+ frsh_utilization_line_pow_t utilizations[FRSH_MAX_N_UTILIZATION_VALUES];
+} frsh_utilization_set_pow_t;
+
+FRSH_CPP_END_DECLS
+
+#endif /* !FRSH_ENERGY_MANAGEMENT_TYPES_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_error.h
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef FRSH_ERROR_H_
+#define FRSH_ERROR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file frsh_error.h
+ **/
+
+/**
+ * addtogroup core
+ *
+ * @{
+ **/
+
+/* Error codes */
+#define FRSH_NO_ERROR 0
+
+#define FRSH_ERR_BASE_VALUE 0x02004000
+
+#define FRSH_ERR_TOO_MANY_TASKS 0x02004001
+#define FRSH_ERR_BAD_ARGUMENT 0x02004002
+#define FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE 0x02004003
+#define FRSH_ERR_NO_RENEGOTIATION_REQUESTED 0x02004004
+#define FRSH_ERR_CONTRACT_REJECTED 0x02004005
+#define FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD 0x02004006
+#define FRSH_ERR_NOT_BOUND 0x02004007
+#define FRSH_ERR_UNKNOWN_SCHEDULED_THREAD 0x02004008
+#define FRSH_ERR_NOT_CONTRACTED_VRES 0x02004009
+#define FRSH_ERR_NOT_SCHEDULED_THREAD 0x0200400A
+#define FRSH_ERR_TOO_MANY_SERVICE_JOBS 0x0200400B
+#define FRSH_ERR_TOO_MANY_SYNCH_OBJS 0x0200400C
+#define FRSH_ERR_TOO_MANY_VRES_IN_SYNCH_OBJ 0x0200400D
+#define FRSH_ERR_TOO_MANY_EVENTS_IN_SYNCH_OBJ 0x0200400E
+#define FRSH_ERR_INTERNAL_ERROR 0x0200400F
+#define FRSH_ERR_TOO_MANY_VRES 0x02004010
+#define FRSH_ERR_INVALID_SCHEDULER_REPLY 0x02004011
+#define FRSH_ERR_TOO_MANY_PENDING_REPLENISHMENTS 0x02004012
+#define FRSH_ERR_SYSTEM_ALREADY_INITIALIZED 0x02004013
+#define FRSH_ERR_SHARED_OBJ_ALREADY_INITIALIZED 0x02004014
+#define FRSH_ERR_SHARED_OBJ_NOT_INITIALIZED 0x02004015
+#define FRSH_ERR_SCHED_POLICY_NOT_COMPATIBLE 0x02004016
+#define FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE 0x02004017
+#define FRSH_ERR_ALREADY_BOUND 0x02004018
+#define FRSH_ERR_RESOURCE_ID_INVALID 0x02004019
+#define FRSH_ERR_TOO_LARGE 0x0200401A
+#define FRSH_ERR_BUFFER_FULL 0x0200401B
+#define FRSH_ERR_NO_SPACE 0x0200401C
+#define FRSH_ERR_NO_MESSAGES 0x0200401D
+#define FRSH_WRN_MODULE_NOT_SUPPORTED 0x0200401E
+#define FRSH_ERR_NOT_INITIALIZED 0x0200401F
+#define FRSH_ERR_TOO_MANY_SHARED_OBJS 0x02004020
+#define FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS 0x02004021
+#define FRSH_ERR_BUDGET_EXPIRED 0x02004022
+#define FRSH_ERR_SHARED_OBJECT_NOT_PROTECTED 0x02004023
+#define FRSH_ERR_NOT_IMPLEMENTED 0x02004024
+#define FRSH_ERR_CONTRACT_TYPE_NOT_COMPATIBLE 0x02004025
+#define FRSH_ERR_CAPACITY_NOT_DECREASING 0x02004026
+#define FRSH_ERR_CONTRACT_LABEL_UNKNOWN 0x02004027
+#define FRSH_ERR_OUT_OF_BUDGET 0x02004028
+#define FRSH_ERR_ALREADY_IN_FRSH 0x02004029
+
+#define FRSH_ERR_LAST_VALUE 0x02004030
+
+
+
+#ifdef AQuoSA
+#define my_frsh_perror(nn,ss) do { errno = nn; perror(ss); } while(0)
+#else
+#define my_frsh_perror(nn,ss) do { perror(ss); } while(0)
+#endif
+
+#define ERROR(nn,ss) do {if(nn>FRSH_ERR_BASE_VALUE) my_frsh_strerror(nn, ss); else { my_frsh_perror(nn, ss); } exit (nn);} while (0)
+
+
+int frsh_strerror (int error, char *message, size_t size);
+void my_frsh_strerror(int error, char *sss);
+
+/**
+ * This str_helper is needed to ensure argument expansion,
+ * see http://www.iar.com/p180591/p180591_eng.php
+ **/
+#define STR_HELPER(x) #x
+
+/**
+ * PERROR_FRESCOR
+ *
+ * This macro checks the given error number and composes a messages accordingly.
+ *
+ * @param nn Error number
+ * @param ss Error string (to be appended to FRSH or system error string)
+ **/
+#define PERROR_FRESCOR(_nn_,_ss_) do { \
+ \
+ char error_string[1024]; \
+ \
+ sprintf(error_string, "File: %s, in function %s at line %d, error %d: %s\n", __FILE__, __FUNCTION__, __LINE__, (_nn_), _ss_); \
+ \
+ if( (_nn_)>FRSH_ERR_BASE_VALUE ) { \
+ my_frsh_strerror( (_nn_), error_string); \
+ } else { \
+ my_frsh_perror(_nn_, error_string); \
+ } \
+} while(0)
+
+
+
+/**
+ * PERROR_AND_RETURN
+ *
+ * Macro that displays an error code and message and then returns from
+ * the current function
+ *
+ * @param nn Error number
+ * @param ss Error string (to be appended to FRSH or system error string)
+ **/
+#define PERROR_AND_RETURN(nn,ss) do { \
+ PERROR_FRESCOR(nn, ss); \
+ return (nn); \
+ } while (0)
+
+
+
+
+/**
+ * PERROR_AND_EXIT
+ *
+ * Macro that displays an error code and message and then aborts the
+ * program.
+ *
+ * @param nn Error number
+ * @param ss Error string (to be appended to FRSH or system error string)
+ **/
+#define PERROR_AND_EXIT(nn,ss) do { \
+ PERROR_FRESCOR(nn,ss); \
+ exit(nn); \
+ } while (0)
+
+
+/**
+ * PRW: Perror and Return Wrapper
+ *
+ * Function that calls funccall and checks the result != 0.
+ * In case of error it displays the error code with the function call
+ * as extra error string and returns from the function.
+ *
+ * terror (int) needs to be visible in the point of call.
+ *
+ * @param funccall Code to execute that should return 0 in a non error
+ * case.
+ **/
+#define PRW(funccall) do { \
+ if ( (terror = funccall ) != 0) \
+ { \
+ PERROR_AND_RETURN( terror, STR_HELPER(funccall) ); \
+ } \
+} while(0)
+
+
+
+/**
+ * PXW: Perror and eXit Wrapper
+ *
+ * Function that calls funccall and checks the result != 0.
+ * In case of error it displays the error code with the function call
+ * as extra error string and ABORTS the program.
+ *
+ * terror (int) needs to be visible in the point of call.
+ *
+ * @param funccall Code to execute that should return 0 in a non error
+ * case.
+ **/
+#define PXW(funccall) do { \
+ if ( (terror = funccall ) != 0) \
+ { \
+ PERROR_AND_EXIT( terror, STR_HELPER(funccall) ); \
+ } \
+} while(0)
+
+
+
+/**
+ * PERROR_KERN_AND_EXIT
+ *
+ * Function that displays an error code and message and then aborts the
+ * program.
+ *
+ * @param nn Error number
+ * @param ss Error string (to be appended to FRSH or system error string)
+ **/
+#define PERROR_KERN_AND_EXIT(nn, ss) do { \
+ errno = errno ? errno : (nn); \
+ kern_printf(ss); \
+ exit(nn); \
+ } while (0)
+
+
+
+
+/*}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* !FRSH_ERROR_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_feedback_control.h
+
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef _FRSH_FEEDBACK_CONTROL_H_
+#define _FRSH_FEEDBACK_CONTROL_H_
+
+#include <time.h>
+
+//#include "frsh_feedback_control_types.h"
+#include "frsh_core_types.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+#define FRSH_FEEDBACKCTRL_MODULE_SUPPORTED 1
+
+/**
+ * @file frsh_feedback_control.h
+ **/
+
+/**
+ * @defgroup feedbackctrl Feedback Control Module
+ *
+ * This module provides a way to implement a QoS manager at the
+ * application level.
+ *
+ * @note
+ * Please, note that, in order to exploit the feedback-scheduling
+ * functionality of FRESCOR, an application needs to use a set of
+ * different functions:
+ * <ul>
+ * <li>the frsh_contract_set_basic_params() and the
+ * frsh_contract_set_reclamation_params() functions are used
+ * to set the dynamic variability range (or options) for the budget;
+ * <li>the frsh_feedback_set_spare() function is used to communicate to
+ * the FMGR module what is the spare virtual resource that is used
+ * to reserve a fraction of resource availability by FMGR-enabled
+ * applications, so to avoid a complete occupation of the system
+ * (this is needed in common cases if one wants to keep a good
+ * performance of the QoS control loops);
+ * such spare vres needs to have been previously negotiated through
+ * the usual functions in the FRSH Core module;
+ * <li>the frsh_feedback_set_desired_budget() function is used to
+ * dynamically fine-tune the budget request for the application,
+ * leaving to the FMGR module the freedom to fulfill the requests
+ * made by all the applications in the system according to global
+ * QoS control goals, as well as to the importance and weight
+ * parameters that may be specified by the applications for individual
+ * virtual resources.
+ * </ul>
+ *
+ * @{
+ *
+ **/
+
+/**
+ * frsh_feedback_set_spare()
+ *
+ * This function is used to tell the FRSH FEEDBACKCTRL module what is
+ * the spare contract that is used as a "reserve" of computation
+ * resources that may be used by other contracts making use of adaptive
+ * reservations.
+ *
+ * @note
+ * No threads must be ever attached to the contract identified by
+ * spare_id. If this happens, behaviour is unspecified.
+ *
+ * @note
+ * This function must be called only once. If it is called more than
+ * once, then the behaviour is unspecified.
+ **/
+int frsh_feedback_set_spare(const frsh_contract_t *spare_contract);
+
+/**
+ * frsh_feedback_get_spare()
+ *
+ * Get version of the frsh_feedback_set_spare() function.
+ **/
+int frsh_feedback_get_spare(frsh_contract_t *spare_contract);
+
+/**
+ * frsh_feedback_set_desired_budget()
+ *
+ * This function sets the budget request that would best suite the
+ * needs of the application for the very next server periods. The
+ * budget actually used for the vres instances (application jobs),
+ * that may be retrieved through a frsh_feedback_get_actual_budget() call,
+ * is dynamically changed by the FMGR Module, and may be less than
+ * the required value, as due to the following rules:
+ *
+ * <ul>
+ * <li>if the required budget is less than the minimum guaranteed
+ * negotiated for the vres, then it is always granted;
+ * <li>if the set of requested budgets is schedulable, then all the
+ * requests are granted, except for what stated in the note below;
+ * <li>if the set of requested budgets overcomes the resource capacity
+ * and the required budget is higher than the minimum guaranteed
+ * negotiated for the vres, then the FMGR module makes an attempt to
+ * fulfill the application request by using also the spare computation
+ * resources that have been reserved through the
+ * frsh_feedback_set_spare() call.
+ * </ul>
+ *
+ * Before any frsh_feedback_set_desired_budget() call, the desired budget
+ * is assumed to be equal to the maximum budget value set during contract
+ * negotiation.
+ *
+ * @note
+ * If the requested budget is higher than the maximum value negotiated
+ * for the vres, then an error is returned.
+ *
+ * @note
+ * The actual budget that is used for a vres may change dynamically
+ * and asynchronously with respect to the threads attached to the vres,
+ * due to other contracts being negotiated, renegotiated or terminated,
+ * or due the call of the frsh_feedback_set_desired_budget() function
+ * for other virtual resources.
+ *
+ * @param[in] p_budget_in
+ * The new budget to set as desired.
+ **/
+int frsh_feedback_set_desired_budget(frsh_vres_id_t vres_id, frsh_rel_time_t *p_budget_in);
+
+/**
+ * frsh_feedback_get_desired_budget()
+ *
+ * Get version of the frsh_feedback_set_desired_budget() function.
+ *
+ * @param[out] p_budget_out
+ * The last budget set as desired through a frsh_feedback_set_desired_budget()
+ * call, or the maximum budget set during contract negotiation, if no such
+ * call ever occurred.
+ **/
+int frsh_feedback_get_desired_budget(frsh_vres_id_t vres_id, frsh_rel_time_t *p_budget_out);
+
+/**
+ * frsh_feedback_get_actual_budget()
+ *
+ * Retrieve the actual budget that is being dynamically used by the FMGR module for
+ * the specified vres. The value returned by this function (in the budget parameter)
+ * for a given vres may change dynamically as a result of a call to the
+ * frsh_feedback_set_desired_budget() function for the same or other virtual resources.
+ **/
+int frsh_feedback_get_actual_budget(frsh_vres_id_t vres_id, frsh_rel_time_t *budget);
+
+/*@}*/
+
+
+FRSH_CPP_END_DECLS
+
+#endif
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef FRSH_FEEDBACK_CONTROL_TYPES_H_
+#define FRSH_FEEDBACK_CONTROL_TYPES_H__
+
+#include <time.h>
+#include "frsh_opaque_types.h"
+#include "frsh_configuration_parameters.h"
+
+FRSH_CPP_BEGIN_DECLS
+/**
+ * @file frsh_feedback_control_types.h
+ **/
+
+/**
+ * @addtogroup feedbackctrl
+ *
+ * @{
+ **/
+
+/**
+ * Integer type from 0 to 100 representing the percentage of spare
+ * capacity that will be allocated for feedbackctrl
+ **/
+typedef int frsh_spare_subset_t;
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif /* !FRSH_FEEDBACK_CONTROL_TYPES_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_hierarchical.h
+
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef _FRSH_HIERARCHICAL_H_
+#define _FRSH_HIERARCHICAL_H_
+
+#include <time.h>
+#include "frsh_hierarchical_types.h"
+#include "frsh_core.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+#define FRSH_HIERARCHICAL_MODULE_SUPPORTED 1
+
+/**
+ * @file frsh_hierarchical.h
+ **/
+
+/**
+ * @defgroup hierarchical Hierarchical Scheduling Module
+ *
+ * This module includes the types and functions to use local
+ * schedulers within vres allowing to attach more than one thread
+ * to a vres and define an scheduling policy within.
+ *
+ * @{
+ **/
+
+/**
+ * frsh_local_scheduler_init()
+ *
+ * This call has the following effects:
+ * FP: none \n
+ * EDF: none \n
+ * TABLE_DRIVEN :
+ * Records the schedule duration, and starts the
+ * schedule at the time of the call. After the
+ * schedule duration has elapsed, the schedule in
+ * the table is repeated.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range,
+ * or info is NULL \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under the FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ **/
+int frsh_local_scheduler_init(
+ frsh_vres_id_t vres,
+ frsh_sched_init_info_t info);
+
+
+/**
+ * frsh_contract_set_sched_policy()
+ *
+ * The operation updates the specified contract parameters object by
+ * setting its scheduling policy to the specified input parameter.
+ * The default policy is FRSH_NONE, which means that only one thread
+ * may be bound to the vres
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if sched_policy is not in range,
+ * or contract is NULL
+ **/
+int frsh_contract_set_sched_policy
+ (frsh_contract_t *contract,
+ frsh_sched_policy_t sched_policy);
+
+
+/**
+ * frsh_contract_get_sched_policy()
+ *
+ * This operation obtains from the specified contract parameters
+ * object its scheduling policy, and copies it to the place pointed to
+ * by the corresponding input parameter.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if sched_policy or contract are NULL
+ **/
+int frsh_contract_get_sched_policy
+ (const frsh_contract_t *contract,
+ frsh_sched_policy_t *sched_policy);
+
+
+/**
+ * frsh_thread_create_local()
+ *
+ * This operation creates a thread and binds it to the specified
+ * vres, which must have a policy different than FRSH_NONE. The new
+ * thread is created with the arguments thread, attr, thread_code and
+ * arg as they are defined for the pthread_create() POSIX function
+ * call, and its local scheduling parameters are set to the value
+ * stored in the variable pointed to by sched_params, which must be
+ * compatible with the vres's scheduling policy. Then, the function
+ * binds the created thread to the new vres. The attr /parameter is
+ * overwritten as necessary to introduce the adequate scheduling
+ * policy and priority, according to the preemption level given in the
+ * contract and the frsh_priority_map() function defined by the user.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range,
+ * or sched_params is NULL \n
+ * FRSH_ERR_SCHED_POLICY_NOT_COMPATIBLE : if the scheduling policy
+ * in sched_params is not compatible to the vres's one \n
+ * FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
+ * main scheduler \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the referenced vres is not
+ * valid \n
+ * FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload
+ * of the vres is FRSH_OVERHEAD \n
+ * .
+ * It may also return any of the errors that may be returned by the
+ * pthread_create()POSIX function call
+ **/
+int frsh_thread_create_local(frsh_vres_id_t vres,
+ frsh_sched_params_t *sched_params,
+ frsh_thread_id_t *thread,
+ frsh_thread_attr_t *attr,
+ frsh_thread_code_t thread_code,
+ void *arg);
+
+/**
+ * frsh_thread_bind_local()
+ *
+ * This operation associates a thread with a vres, which must have a
+ * policy different than FRSH_NONE. The thread's local scheduling
+ * parameters are set to the value stored in the variable pointed to
+ * by sched_params, which must be compatible with the vres's
+ * scheduling policy. After the call the thread starts consuming the
+ * vres's budget and is executed according to the contract
+ * established for that vres and to its scheduling policy. If the
+ * thread was already bound to another vres, it is effectively
+ * unbound from it and bound to the specified one.
+ *
+ * Implementation dependent issue: In order to allow the usage of
+ * application defined schedulers, the given thread must not have the
+ * scheduling policy SCHED_APP and at the same time be attached to an
+ * application scheduler different than the frsh scheduler.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if the vres argument does not complain with
+ * the expected format or valid range, the given thread does not exist,
+ * or sched_params is NULL \n
+ * FRSH_ERR_SCHED_POLICY_NOT_COMPATIBLE : if the scheduling policy
+ * in sched_params is not compatible to the vres's one. \n
+ * FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
+ * main scheduler \n
+ * FRSH_ERR_UNKNOWN_APPSCHEDULED_THREAD : if the thread is attached to
+ * an application defined scheduler different than the frsh
+ * scheduler \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the referenced vres is not
+ * valid \n
+ * FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload
+ * of the vres is FRSH_OVERHEAD
+ **/
+int frsh_thread_bind_local(frsh_vres_id_t vres,
+ frsh_thread_id_t thread,
+ frsh_sched_params_t *sched_params);
+
+
+/**
+ * frsh_thread_set_local_sched_params()
+ *
+ * This function changes the local scheduling parameters of the thread
+ * to the value pointed to by sched_params. This value must be
+ * compatible with the scheduling policy of the vres to which the
+ * thread is bound.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if the given thread does not exist,
+ * or sched_params is NULL \n
+ * FRSH_ERR_SCHED_POLICY_NOT_COMPATIBLE : if the thread is already bound
+ * and the scheduling policy in sched_params is not compatible to the
+ * one of the thread's vres. \n
+ * FRSH_ERR_NOT_SCHEDULED_THREAD : if the given thread is not scheduled
+ * under FRSH \n
+ * FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
+ * main scheduler \n
+ * FRSH_ERR_UNKNOWN_APPSCHEDULED_THREAD : if the thread is attached to
+ * an application defined scheduler different than the frsh
+ * scheduler \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the thread is bound and its vres
+ * is not valid
+ **/
+int frsh_thread_set_local_sched_params (frsh_thread_id_t thread,
+ const frsh_sched_params_t *sched_params);
+
+/**
+ * frsh_thread_get_local_sched_params()
+ *
+ * This function stores the local scheduling parameters of the
+ * specified thread in the variable pointed to by sched_params.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if sched_params is NULL or the thread does
+ * not exist \n
+ * FRSH_ERR_NOT_SCHEDULED_THREAD : if the given thread is not scheduled
+ * under FRSH
+ **/
+int frsh_thread_get_local_sched_params(frsh_thread_id_t thread,
+ frsh_sched_params_t *sched_params);
+
+/*}*/
+
+FRSH_CPP_END_DECLS
+
+#endif // _FRSH_HIERARCHICAL_H_
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef FRSH_HIERARCHICAL_TYPES_H_
+#define FRSH_HIERARCHICAL_TYPES_H_
+
+/**
+ * @file frsh_hierarchical_types.h
+ **/
+
+#include <time.h>
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @addtogroup hierarchical
+ *
+ * @{
+ **/
+
+/** Scheduling policies **/
+typedef enum {FRSH_FP, FRSH_EDF, FRSH_TABLE_DRIVEN, FRSH_RR, FRSH_NONE}
+ frsh_sched_policy_t;
+
+#define FRSH_DEFAULT_SCHED_POLICY FRSH_NONE
+
+/**
+ * Scheduling policy and parameters
+ *
+ * The params member is a pointer to one of the
+ * following:
+ * FP: int (priority)
+ * EDF: frsh_rel_time_t (deadline)
+ * RR: none
+ * TABLE_DRIVEN : struct frsh_table_driven_params_t
+ **/
+typedef struct {
+ frsh_sched_policy_t policy;
+ void * params;
+} frsh_sched_params_t;
+
+
+/**
+ * Scheduling parameters for the table-driven policy
+ * list of target windows
+ **/
+typedef struct {
+ frsh_rel_time_t start;
+ frsh_rel_time_t end;
+ frsh_rel_time_t comp_time;
+} frsh_target_window_t;
+
+/**
+ * Container for a frsh_target_window array
+ **/
+typedef struct {
+ int size;
+ frsh_target_window_t table[FRSH_MAX_N_TARGET_WINDOWS];
+} frsh_table_driven_params_t;
+
+
+/**
+ * Initialization information for a scheduling policy
+ *
+ * It shall be one of the following:
+ * FP: none
+ * EDF: none
+ * RR: frsh_rel_time_t (slice duration)
+ * TABLE_DRIVEN : frsh_rel_time_t (schedule duration)
+ **/
+typedef void * frsh_sched_init_info_t;
+
+/*}*/
+
+FRSH_CPP_END_DECLS
+
+#endif /* !FRSH_HIERARCHICAL_TYPES_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_implementation_specific.h
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef _FRSH_IMPLEMENTATION_SPECIFIC_H_
+#define _FRSH_IMPLEMENTATION_SPECIFIC_H_
+
+#include "frsh_implementation_specific_types.h"
+#include "frsh_core.h"
+
+#define FRSH_IMPLEMENTATION_SPECIFIC_MODULE_SUPPORTED 1
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_implementation_specific.h
+ *
+ **/
+
+/**
+ * @defgroup implementationspec Implementation Specific module
+ *
+ * The operations defined in this module are of optional use. The
+ * intention is to provide better tunning options taking advantage of
+ * specific characteristics of the underlaying OS.
+ *
+ *
+ * e.g. being able to manually assign priorities assuming that the OS
+ * uses a fixed priority paradigm).
+ *
+ * @{
+ **/
+
+/**
+ * frsh_contract_set_preemption_level()
+ *
+ * The operation updates the specified contract parameters object by
+ * setting its preemption level to the specified input parameter.
+ *
+ * OBSERVATION: if this value is changed being any contract that
+ * uses the resource already accepted, the system's behavior and
+ * particularly the acceptance tests correctness are not garantee
+ * and probably wrong.
+ *
+ **/
+int frsh_contract_set_preemption_level
+ (frsh_contract_t *contract,
+ frsh_preemption_level_t preemption_level);
+
+
+/**
+ * frsh_contract_get_preemption_level()
+ *
+ * The operation obtains from the specified contract parameters object
+ * its preemption level and copies it to the place pointed to by the
+ * specified input parameter.
+ **/
+int frsh_contract_get_preemption_level
+ (const frsh_contract_t *contract,
+ frsh_preemption_level_t *preemption_level);
+
+/**
+ * frsh_service_thread_set_preemption_level()
+ *
+ * This function sets the preemption level of the service thread to
+ * the specified value. The initial preemption level is a configurable
+ * parameter. This value is stored in a temporary variable and it is
+ * used the next time the service thread data is updated with the
+ * frsh_service_thread_set_data() function.
+ **/
+int frsh_service_thread_set_preemption_level
+ (frsh_preemption_level_t preemption_level);
+
+/**
+ * frsh_service_thread_get_preemption_level()
+ *
+ * This function stores the current preemption level of the service
+ * thread in the variable pointed to by preemption_level
+ **/
+int frsh_service_thread_get_preemption_level
+ (frsh_preemption_level_t *preemption_level);
+
+
+/**
+ * frsh_thread_exit()
+ *
+ * This operation shall terminate the calling thread, make the value
+ * value_ptr available to any successful join with the terminating
+ * thread, and unbind the thread from its associated vres. After
+ * cleaning up the thread management data, it is unbound and the
+ * scheduling policy is changed to fixed priority before the posix
+ * pthread_exit() function is called.
+ *
+ * There is a limitation in the current version of the
+ * MaRTE implementation that causes the information of a terminated
+ * thread to continue to be stored in the frsh scheduler, and the thread
+ * to continue to be counted in the number of threads. The
+ * frsh_thread_exit operation allows the implementation to delete the
+ * thread's information, and then terminate the thread. Therefore, it
+ * is recommended to use this function to terminate a thread under frsh.
+ *
+ * Implementation dependent issue: in the implementation with an
+ * application scheduler, after cleaning up the thread management
+ * data, it is unbound and the scheduling policy changed to fixed
+ * priority before calling the posix pthread_exit() function.
+ *
+ * NOTE: This function, together with the internal function
+ * frsh_internal_remove_thread() has been removed from FRSH
+ * because it shouldn't be necessary.
+ *
+ * If there are some problems with MaRTE in thread termination
+ * it should be fixed in the OS and not here.
+ *
+ * The function does not do anything special that is not done in the
+ * terminate callback of the FRSH scheduler.
+ *
+ * If you want to be curious about what the function did, look at the
+ * SVN repository (revision 273) or one of the past branches.
+ **/
+void frsh_thread_exit (void *value_ptr);
+
+
+/**
+ * frsh_sharedobj_set_preemption_level()
+ *
+ * The operation updates the specified shared object by setting its
+ * preemption level to the specified input parameter.
+ *
+ * OBSERVATION: if this value is changed being any contract that
+ * uses the resource already accepted, the system's behavior and
+ * particularly the acceptance tests correctness are not garantee
+ * and probably wrong.
+ **/
+int frsh_sharedobj_set_preemption_level(frsh_sharedobj_handle_t obj_handle,
+ frsh_preemption_level_t preemption_level);
+
+/**
+ * frsh_sharedobj_get_preemption_level()
+ *
+ * The operation obtains from the specified shared object its
+ * preemption level and copies it to the place pointed to by the
+ * specified input parameter.
+ **/
+int frsh_sharedobj_get_preemption_level(frsh_sharedobj_handle_t obj_handle,
+ frsh_preemption_level_t *preemption_level);
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif // _FRSH_IMPLEMENTATION_SPECIFIC_H_
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_implementation_specific_types.h
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef FRSH_IMPLEMENTATION_SPECIFIC_TYPES_H_
+#define FRSH_IMPLEMENTATION_SPECIFIC_TYPES_H_
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_implementation_specific_types.h
+ **/
+
+/**
+ * @addtogroup implementationspec
+ *
+ * @{
+ **/
+
+/** Implementation specific preemption level values **/
+typedef unsigned long frsh_preemption_level_t; // range 1..2**32-1
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+
+#endif /* !FRSH_IMPLEMENTATION_SPECIFIC_TYPES_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_memory_management.h
+
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef _FRSH_MEMORY_MANAGEMENT_H_
+#define _FRSH_MEMORY_MANAGEMENT_H_
+
+#include "frsh_core_types.h"
+
+
+#define FRSH_MEMORY_MANAGEMENT_SUPPORTED 1
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_memory_management.h
+ **/
+
+/**
+ * @defgroup memmanagement Memory Management
+ *
+ * This module provides the types and the functions to add memory
+ * management support to FRSH contracts.
+ *
+ * @{
+ *
+ **/
+
+/**
+ * frsh_contract_set_min_memory()
+ *
+ * This function specifies in the contract the minimum
+ * memory needed by the application.
+ *
+ * @param[in] min_memory Minimum needed memory in bytes.
+ * @param[in] max_memory Maximum needed memory in bytes.
+ * @param contract Contract, in-out argument.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT if min_memory <0
+ *
+ **/
+int frsh_contract_set_min_memory(size_t min_memory,
+ frsh_contract_t *contract);
+
+/**
+ * frsh_contract_get_min_memory()
+ *
+ * This function gets the minimum memory parameter from the contract.
+ *
+ * @param[in] contract Contract object
+ * @param[out] min_memory Placeholder for the minimum required
+ * memory.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT if one of the pointers is NULL
+ **/
+int frsh_contract_get_min_memory(const frsh_contract_t *contract,
+ size_t *min_memory);
+
+// frsh_contract_set_max_memory() is new
+// frsh_contract_get_max_memory() is new
+
+/**
+ * frsh_contract_set_max_memory()
+ *
+ * This function specifies in the contract the minimum
+ * memory needed by the application.
+ *
+ * @param[in] max_memory Maximum needed memory in bytes.
+ * @param contract Contract, in-out argument.
+ *
+ * FRSH_ERR_BAD_ARGUMENT if min_memory > max_memory
+ *
+ **/
+int frsh_contract_set_max_memory(size_t max_memory,
+ frsh_contract_t *contract);
+
+
+/**
+ * frsh_contract_get_max_memory()
+ *
+ * This function gets the maximum memory parameter from the contract.
+ *
+ * @param[in] contract Contract object
+ * @param[out] max_memory Placeholder for the maximum required
+ * memory.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT if one of the pointers is NULL
+ **/
+int frsh_contract_get_max_memory(const frsh_contract_t *contract,
+ size_t *max_memory);
+
+
+/**
+ * frsh_vres_get_memory_info()
+ *
+ * This function gives us the runtime info of memory usage and
+ * reservation.
+ *
+ * @param[in] vres_id Identifier of vres
+ * @param[out] mem_allocated Memory currently allocated to the vres
+ * @param[out] mem_budget Total pool of memory reserved for the vres
+ * (until next renegotiation).
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT if one of the pointers is NULL
+ **/
+int frsh_vres_get_memory_info(frsh_vres_id_t vres_id,
+ size_t *mem_allocated,
+ size_t *mem_budget);
+
+
+/**
+ * frsh_vres_memalloc()
+ *
+ * This function reserves some memory from the memory to this virtual
+ * resource.
+ *
+ * @param[in] vres_id Identifier of vres.
+ * @param[in] Number of bytes
+ * @param[out] Valid pointer for the allocation
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT if the area pointer is NULL
+ * FRSH_ERR_OUT_OF_BUDGET if no budget is available
+ **/
+int frsh_vres_malloc(frsh_vres_id_t vres_id,
+ size_t num_bytes,
+ void **area);
+
+/**
+ * frsh_vres_memfree()
+ *
+ * This function returns the previously allocated memory area for this
+ * virtual_resource to the main memory.
+ *
+ * @param[in] vres_id Identifier of vres.
+ * @param[in] area Memory area to return
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT if the area pointer is NULL
+ **/
+int frsh_vres_memfree(frsh_vres_id_t vres_id,
+ void *area);
+
+
+
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif /* !FRSH_MEMORY_MANAGEMENT_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_opaque_types.h
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+// Implementation dependent definitions
+#ifndef _FRSH_OPAQUE_TYPES_H_
+#define _FRSH_OPAQUE_TYPES_H_
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_opaque_types.h
+ **/
+
+/**
+ * @defgroup opaque Opaque types
+ *
+ * This module specifies some #defines for privates types in the
+ * interface. In this way we warn the FRSH user never to access the internal
+ * members of the types directly allowing us to change their internal
+ * definitions to suit our needs.
+ *
+ * Note that in Ada the FRSH user would never be allowed to access the
+ * members directly, however in C the compiler does not prevent this.
+ * But this is the best we can do in this language.
+ *
+ * @{
+ **/
+
+#define FRSH_VRES_ID_T_OPAQUE unsigned int
+
+/** frsh_contract_parameters_t **/
+#define FRSH_CONTRACT_T_OPAQUE struct { \
+\
+ /** Processor Id or Network Id **/ \
+ frsh_resource_id_t resource_id; \
+\
+ /** Whether processor or network **/ \
+ frsh_resource_type_t resource_type; \
+\
+ /** Printable name for the contract
+ Unique within the local node **/ \
+ frsh_contract_label_t contract_label; \
+\
+ /** Minimum budget needed to perform a job. With the energy
+ module this will be an array **/ \
+ frsh_rel_time_t budget_min; \
+\
+ /** Maximum period that the system system can sustain **/ \
+ frsh_rel_time_t period_max; \
+\
+ /** Maximum budget that the vres can use
+ (and would be happy to have). With the energy module
+ this will be an array **/ \
+ frsh_rel_time_t budget_max; \
+\
+ /** Minimum period for that
+ the system can use (and would be happy to have) **/ \
+ frsh_rel_time_t period_min; \
+\
+ /** Set of discrete values for budget and period. With the
+ energy module this will be an array **/ \
+ frsh_utilization_set_t utilization_set; \
+\
+ /** Workload_type: bounded, indeterminate, overhead **/ \
+ frsh_workload_t workload; \
+\
+ /** Scheduling type: Regular, background
+ (in round-robin) or dummy **/ \
+ frsh_contract_type_t contract_type; \
+\
+ /** Whether delay equals period **/ \
+ bool d_equals_t; \
+\
+ /** Deadline (will be ignored if d_equals_t is TRUE **/ \
+ frsh_rel_time_t deadline; \
+\
+ /** Signal parameters for the case of
+ attempting to use too much budget **/ \
+ frsh_signal_t budget_overrun_signal; \
+ frsh_signal_info_t budget_overrun_siginfo; \
+\
+ /** Signal parameters for the case a deadline
+ is missed **/ \
+ frsh_signal_t deadline_miss_signal; \
+ frsh_signal_info_t deadline_miss_siginfo; \
+\
+ /** Wether the range of period and budget is specified
+ in a continuous way (max-min) or as a set of
+ discrete values **/ \
+ frsh_granularity_t granularity; \
+\
+ /** Non-cooperative parameter for fair capacity
+ distribution **/ \
+ int importance; \
+\
+ /** Cooperative parameter for fair capacity
+ distribution **/ \
+ int weight; \
+\
+ /** If > 0 it describes a duration for which
+ the allocated budget and capacity will be
+ maintained across negotiations and will
+ not be affected for dynamic spare capacity **/ \
+ frsh_rel_time_t stability_time; \
+\
+ /** Low level parameter related with the elegibility
+ preempt other threads **/ \
+ frsh_preemption_level_t preemption_level; \
+\
+ /** Set of critical sections that the vres executes
+ besides the normal budget **/ \
+ frsh_csects_group_t critical_sections; \
+\
+ /** Internal scheduling policy within the vres for
+ hierarchical scheduling systems **/ \
+ frsh_sched_policy_t policy; \
+\
+ /** Protocol info for distributed systems. We store it
+ as a pointer+size. It's internal meaning is imple-
+ mentation dependent. **/ \
+ frsh_protocol_info_t protocol_info; \
+ frsh_endpoint_queueing_info_t queueing_info; \
+\
+ /** Maximum loss rate
+ Percentage of packet loss in the network that is
+ tolerated by the application **/ \
+int max_loss_rate; \
+\
+ /** Minimum memory size to be reserved **/ \
+size_t minimum_memory; \
+\
+/** Maximum memory size to be reserved **/ \
+size_t maximum_memory; \
+}
+
+
+typedef int FRSH_SYNCHOBJ_HANDLE_T_OPAQUE;
+
+typedef int FRSH_SHAREDOBJ_HANDLE_T_OPAQUE;
+
+typedef unsigned int FRSH_GROUP_ID_T_OPAQUE;
+
+/**
+ * Critical section data
+ * - comon parameters
+ * op_kind; // kind of operation (READ or WRITE)
+ * obj_handle; // handle to shared object
+ * wcet; // Execution time
+ * blocking; // Blocking time (execution time + protection overheads)
+ * - attributes used only for protected shared objects
+ * op; // pointer to the operation
+ * - attributes used only for protected write operations
+ * areas; // memory areas to be protected
+ *
+ **/
+#define FRSH_CSECT_T_OPAQUE struct { \
+ frsh_csect_op_kind_t op_kind; \
+ frsh_sharedobj_handle_t obj_handle; \
+ frsh_rel_time_t wcet; \
+ frsh_rel_time_t blocking; \
+ frsh_csect_op_t op; \
+ frsh_memory_areas_t areas; \
+ frsh_memory_areas_t storage; \
+}
+
+
+//opaque types for frsh endpoints
+typedef int FRSH_SEND_ENDPOINT_T_OPAQUE;
+
+typedef int FRSH_RECEIVE_ENDPOINT_T_OPAQUE;
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif // _FRSH_OPAQUE_TYPES_H_
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_shared_objects.h
+
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef _FRSH_SHARED_OBJECTS_H_
+#define _FRSH_SHARED_OBJECTS_H_
+
+#include "frsh_shared_objects_types.h"
+#include "frsh_core_types.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+#define FRSH_SHAREDOBJS_MODULE_SUPPORTED 1
+
+/**
+ * @file frsh_shared_objects.h
+ **/
+
+/**
+ * @defgroup sharedobj Shared Objects module
+ *
+ * This module includes the functions to declare and use shared
+ * objects in different critical sections.
+ *
+ * A shared object is an abstraction of a mutex giving it a name and a
+ * possible priority ceiling.
+ *
+ * A critical section represents a usage of a shared object with a wcet.
+ * One or more critical sections can be included in a contract.
+ *
+ * There are two types of shared_objects: protected and unprotected.
+ *
+ * - <b>UNPROTECTED shared objects</b>. These shared objects are always
+ * used in trusted critical sections for which the worst-case
+ * execution times can be guaranteed not to be exceeded by the
+ * application designer (eg because tools have been used to verify
+ * the schedulability off-line). Given these conditions, there is
+ * no need to have a mechanism to monitor their execution time, with
+ * the corresponding savings in overhead.
+ *
+ * - <b>PROTECTED shared objects</b>. For these shared objects a mechanism
+ * may be used in one or more of their critical sections to monitor
+ * and enforce their worst-case execution time. These shared
+ * objects are restricted to data in regular memory because a
+ * mechanism to save and restore the state is necessary in order to
+ * cleanly abort a misbehaving critical section.\n
+ *
+ * Critical sections are categorized depending on wcet monitoring and
+ * rollback capability.
+ *
+ * - <b>UNCHECKED critical sections</b>. These critical sections are
+ * not monitored by FRSH for wcet compliance. Their wcet value is
+ * used only for analysis purposes (calculation of blocking times).
+ *
+ * - <b>READ critical sections</b>. These critical sections have
+ * their wcet enforced but they don't have any rollback action
+ * applied when their wcet is exceeded.
+ *
+ * - <b>WRITE critical sections</b>. These critical sections have
+ * their wcet monitored and they have a rollback mechanism applied
+ * to their memory areas prior to being aborted for exceeding their
+ * declared wcet.
+ *
+ * READ and WRITE critical sections must use PROTECTED shared objects,
+ * but UNCHECKED critical sections may use PROTECTED or UNPROTECTED
+ * shared objects.
+ *
+ * The monitoring mechanism for READ and WRITE critical section works
+ * by executing them indirectly via a registered callback function.
+ * UNCHECKED critical sections are executed directly by the
+ * application.
+ *
+ * The rollback mechanism for WRITE critical sections requires an
+ * additional registration of the memory areas that the callback
+ * function may modify. With this data FRSH will do an initial saving
+ * of this areas that will used for restoration when there is a rollback
+ * operation.
+ *
+ * Note that extra time for the saving and the restoration must be
+ * included in the wcet specified for a WRITE critical section.
+ * Functions are provided to assist the developer in calculating this
+ * extra time.
+ *
+ * The reason for allowing the use of PROTECTED shared objects in
+ * UNCHECKED critical sections is to allow for legacy or trusted
+ * code that would use UNCHECKED critical sections to share a shared
+ * object with an untrusted code using READ or WRITE critical sections.
+ *
+ * This module makes use of the following constants defined in
+ * frsh_configuration_parameters.h. We list them with our proposed
+ * default values.
+ *
+ * FRSH_MAX_N_SHARED_OBJECTS 100 \n
+ * FRSH_MAX_N_CRITICAL_SECTIONS 20\n
+ * FRSH_MAX_N_MEMORY_AREAS 4\n
+ *
+ * @{
+ **/
+
+
+/////////////////////////////////////////////////////
+// SHARED OBJECTS & OPERATIONS MANAGEMENT
+/////////////////////////////////////////////////////
+/**
+ * @defgroup so_opp_mgmnt Shared Objects & Operations
+ * @ingroup sharedobj
+ *
+ * These functions are used to declare shared objects and link them
+ * with a mutex.
+ *
+ * @{
+ **/
+
+/**
+ * frsh_sharedobj_init()
+ *
+ * Initialization of shared objects. If the object identified by
+ * obj_label does not yet exist, it is created, a handle to the object is
+ * returned in the variable pointed to by obj_handle, and the
+ * specified mutex is initialized with the appropriate attributes
+ * necessary for the current implementation. If the object already
+ * exists, the function fails. The object is created according to the
+ * kind of object (protected or unprotected) specified by obj_kind
+ *
+ * @param[in] obj_label Label defined by the application. Char * for
+ * a string of FRSH_MAX_SIZE_SHARED_OBJ_LABEL
+ * characters (+ null terminating \0).
+ *
+ * @param[in] obj_kind Whether it is protected or unprotected.
+ *
+ * @param[out] obj_handle Placeholder for the shared object handle.
+ *
+ * @param[out] mutex Placeholder for the mutex.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if obj_label, obj_handle, or mutex are NULL \n
+ * FRSH_ERR_SHARED_OBJ_ALREADY_INITIALIZED : if the object identified
+ * by label already exists \n
+ * FRSH_ERR_TOO_MANY_SHARED_OBJS : if the number of already
+ * initialized shared objects exceed the
+ * FRSH_MAX_N_SHARED_OBJECTS configuration parameter. \n
+ * .
+ * It may also return any of the error codes that are returned by
+ * fosa_mutex_init() and fosa_mutex_set_prioceiling().
+ *
+ **/
+int frsh_sharedobj_init
+ (char *obj_label,
+ frsh_sharedobj_kind_t obj_kind,
+ frsh_sharedobj_handle_t *obj_handle,
+ frsh_mutex_t *mutex);
+
+
+
+/**
+ * frsh_sharedobj_get_handle()
+ *
+ * Getting the handle of shared objects. If the object already exists
+ * a handle to the object is returned in the variable pointed to by
+ * obj_handle. Otherwise, an error code is returned.
+ *
+ * @param[in] obj_label Defined by the application at object creation
+ * time. Char * for a string of FRSH_MAX_SIZE_SHARED_OBJ_LABEL
+ * characters (+ null terminating \0).
+ *
+ * @param[out] obj_handle Placeholder for the object handle.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if label or obj_handle are NULL \n
+ * FRSH_ERR_SHARED_OBJ_NOT_INITIALIZED : if the shared object identified
+ * by obj_label does not exist \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid \n
+ * .
+ * It may also return any of the error codes that are returned by the
+ * fosa_mutex_init() function call
+ *
+ **/
+int frsh_sharedobj_get_handle
+ (char *obj_label,
+ frsh_sharedobj_handle_t *obj_handle);
+
+
+/**
+ * frsh_sharedobj_get_mutex()
+ *
+ * Getting the mutex of shared objects.
+ *
+ * @param[in] obj_handle Handle of the shared object
+ *
+ * @param[out] mutex Placeholder for A POINTER to a pointer of the
+ * mutex. We give the pointer to discourage the
+ * application of using a local copy of the mutex.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if obj_handle or mutex are NULL or obj_handle
+ * is not correct or reference a wrong shared object \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under the FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_sharedobj_get_mutex
+ (frsh_sharedobj_handle_t obj_handle,
+ frsh_mutex_t **mutex);
+
+/**
+ * frsh_sharedobj_get_obj_kind()
+ *
+ * Get the object kind (protected/unprotected) of the object handle.
+ *
+ * @param[in] obj_handle Handle of the shared object
+ *
+ * @param[out] obj_kind Placeholder for an enumeration variable of
+ * protected / unprotected.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if obj_handle or mutex are NULL or obj_handle
+ * is not correct or reference a wrong shared object \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under the FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_sharedobj_get_obj_kind
+ (frsh_sharedobj_handle_t obj_handle,
+ frsh_sharedobj_kind_t *obj_kind);
+
+/**
+ * frsh_sharedobj_remove()
+ *
+ * Allows the implementation to remove a shared object when the last
+ * vres referencing it is cancelled. This removes the object id and
+ * other internal data associated with the object, but does not remove
+ * the mutex; this is done by the application through the common POSIX
+ * API.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if obj_handle is NULL or obj_handle
+ * is not correct or references a wrong shared object \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under the FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_sharedobj_remove
+ (frsh_sharedobj_handle_t obj_handle);
+
+
+
+/*@}*/
+
+/////////////////////////////////////////////////////
+// CRITICAL SECTIONS
+/////////////////////////////////////////////////////
+/**
+ * @defgroup so_critical Critical Sections
+ * @ingroup sharedobj
+ *
+ * These functions are used to create and manage the parameters
+ * of critical sections. Critical sections are operations that
+ * make use of a shared object in a mutually exclusive way.
+ *
+ * @{
+ **/
+
+/**
+ * frsh_csect_init()
+ *
+ * Initialize the critical section pointed to by csect
+ * with a handle to its shared object, and the worst-case execution
+ * time.
+ *
+ * The operation_kind is set to FRSH_CSOK_UNCHECKED.
+ *
+ * @param[in] obj_handle Shared object previously initialised.
+ *
+ * @param[in] wcet Execution time of the critical section. This
+ * budget is consumed in parallel with the vres budget.
+ *
+ * @param[out] csect Critical section memory placeholder.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if obj_handle is NULL \b or \n
+ * obj_handle is not correct or references a wrong shared object \b or \n
+ * if wcet is in the wrong format for specifying a time interval value \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under the FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_csect_init
+ (frsh_sharedobj_handle_t obj_handle,
+ frsh_rel_time_t wcet,
+ frsh_csect_t *csect);
+
+
+/**
+ * frsh_csect_get_sharedobj_handle()
+ *
+ * Get in the variable pointed to by obj_handle the handle to the
+ * shared object stored in the critical section referenced by csect
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if csect or obj_handle are NULL or csect
+ * is not correct \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under the FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_csect_get_sharedobj_handle
+ (const frsh_csect_t *csect,
+ frsh_sharedobj_handle_t * obj_handle);
+
+/**
+ * frsh_csect_get_wcet()
+ *
+ * Get in the variable pointed to by wcet the worst-case execution time
+ * of the operation stored in the critical section referenced by csect.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if csect or wcet are NULL or csect
+ * is not correct \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_csect_get_wcet
+ (const frsh_csect_t *csect,
+ frsh_rel_time_t *wcet);
+
+
+/**
+ * frsh_csect_register_read_op()
+ *
+ * Register the given operation with the critical section and set
+ * op_kind to FRSH_CSOK_READ.
+ *
+ * The function returns an error if the shared_object is unprotected.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if csect or op are NULL or if csect points
+ * to a wrong critical section or if the shared_object is of type
+ * unprotected.
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_csect_register_read_op
+ (frsh_csect_t *csect,
+ frsh_csect_op_t op);
+
+/**
+ * frsh_csect_register_write_op()
+ *
+ * Register the given operation with the critical section, register
+ * the memory areas and set op_kind to FRSH_CSOK_WRITE.
+ *
+ * If the memory areas are empty the functions returns an error.
+ *
+ * The function returns an error if the shared_object is unprotected.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if op, csect or areas are NULL or csect points
+ * to a wrong critical section, or areas has a wrong size, or if the
+ * shared_object of csect is of type unprotected.
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under the FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_csect_register_write_op
+ (frsh_csect_t *csect,
+ frsh_csect_op_t op,
+ const frsh_memory_areas_t *areas);
+
+
+/**
+ * frsh_csect_get_op_kind()
+ *
+ * Returns the type of operation (read/write/unchecked) of the critical section.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if csect or op_kind are NULL or csect
+ * is not correct \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_csect_get_op_kind
+ (const frsh_csect_t *csect,
+ frsh_csect_op_kind_t *op_kind);
+
+
+/**
+ * frsh_csect_get_read_op()
+ *
+ * Get into the variable pointed to by op the operation pointer stored
+ * in the critical section referenced by csect.
+ *
+ * If the csect is of type write or unchecked it returns an error.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if csect is NULL or points to a wrong
+ * critical section, or to a critical section that is not of the
+ * FRSH_CSOK_READ kind \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_csect_get_read_op
+ (const frsh_csect_t *csect,
+ frsh_csect_op_t *op);
+
+
+
+/**
+ * frsh_csect_get_write_op()
+ *
+ * Get the operation pointer and the memory areas stored in the csect.
+ *
+ * If the csect is of type read or unchecked.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if csect is NULL or points to a wrong
+ * critical section, or to a critical section that is not of the
+ * FRSH_CSOK_WRITE kind \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid \n
+ *
+ **/
+int frsh_csect_get_write_op
+ (const frsh_csect_t *csect,
+ frsh_csect_op_t *op,
+ frsh_memory_areas_t *areas);
+
+
+/**
+ * frsh_csect_invoke()
+ *
+ * Invoke the registered operation in the critical section, with the pointers
+ * to the input and output parameters specified by input_arg and
+ * output arg.
+ *
+ * If the section is of type FRSH_CSOK_UNCHECKED, the function returns
+ * an error.
+ *
+ * For read operations, the mutex is locked, the csect budget is set equal
+ * to the wcet, the registered read operation is invoked, and then the
+ * mutex is unlocked; if the csect budget expires, the operation is
+ * interrupted, the mutex is unlocked, and the function returns with
+ * an error code.
+ *
+ * For write operations, the mutex is locked, the registered memory
+ * areas are backed up, the csect budget is set equal to the wcet, the
+ * registered write operation is called, and the mutex is unlocked. If
+ * the csect budget expires, the operation is interrupted, the backed-up
+ * memory areas are recovered, the mutex is unlocked, and the function
+ * returns with an error code. The blocking time suffered by higher
+ * priority tasks is at most the wcet of the operation plus the backup
+ * time plus the recovery time.
+ *
+ * If the shared object in the critical section is not protected it
+ * returns an error.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if csect is NULL or points to a wrong
+ * critical section, or to a critical section that is unprotected \n
+ * FRSH_ERR_BUDGET_EXPIRED : the csect budget expired and the protected
+ * operation was interrupted \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_csect_invoke
+ (const frsh_csect_t *csect,
+ const void * input_arg,
+ void * output_arg);
+
+/**
+ * frsh_csect_get_blocking_time()
+ *
+ * Get in the variable pointed to by blocking the maximum blocking
+ * time of the operation of the referenced protected critical section.
+ *
+ * For read or unchecked operations, the maximum blocking time is the wcet.
+ *
+ * For write operations, the maximum blocking time suffered by higher
+ * priority tasks is the wcet of the operation plus the backup time
+ * plus the recovery time.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if csect or blocking are NULL or if csect
+ * points to a wrong critical section, or to a critical section
+ * that is unprotected \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
+ * has been cancelled or it is not valid
+ *
+ **/
+int frsh_csect_get_blocking_time
+ (const frsh_csect_t *csect,
+ frsh_rel_time_t *blocking);
+
+
+/**
+ * frsh_csect_destroy()
+ *
+ * Destroy a critical section, deallocating all the resources that may
+ * have been allocated to it.
+ **/
+int frsh_csect_destroy
+ (frsh_csect_t *csect);
+
+/**
+ * frsh_csect_register_thread()
+ *
+ * Register the calling thread for invoking time-protected critical
+ * sections via frsh_csect_invoke.
+ **/
+int frsh_csect_register_thread();
+
+/**
+ * frsh_csect_deregister_thread()
+ *
+ * Deregister the calling thread from being able to invoke
+ * time-protected critical sections. This operation releases system
+ * resources that may have been allocated for the thread.
+ **/
+int frsh_csect_deregister_thread();
+
+
+
+/*@}*/ /* For so_critical group */
+
+
+/////////////////////////////////////////////////////
+// CONTRACT PARAMETERS
+/////////////////////////////////////////////////////
+/**
+ * @defgroup so_contract Shared Objects & Contract Parameters
+ * @ingroup sharedobj
+ *
+ * These functions are used to link shared objects to contracts via
+ * critical sections.
+ *
+ * @{
+ **/
+
+
+/**
+ * frsh_contract_set_csects()
+ *
+ * The operation updates the specified contract parameters object by
+ * setting its critical sections to the specified input parameter.
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if any of the pointers is NULL or
+ * the size of the critical_sections structure is less than zero
+ * or greater than FRSH_MAX_N_CRITICAL_SECTIONS
+ *
+ **/
+int frsh_contract_set_csects
+ (frsh_contract_t *contract,
+ const frsh_csects_group_t *critical_sections);
+
+/**
+ * frsh_contract_get_csects()
+ *
+ * The operation obtains from the specified contract parameters object
+ * its critical sections, and copies them to the places pointed to by
+ * the specified input parameter. Only those critical_section_data
+ * records that are in use in the critical_sections structure are
+ * copied (according to its size field).
+ *
+ * @return 0 if no error \n
+ * FRSH_ERR_BAD_ARGUMENT : if any of the pointers is NULL
+ *
+ **/
+int frsh_contract_get_csects
+ (const frsh_contract_t *contract,
+ frsh_csects_group_t *critical_sections);
+
+/*@}*/ /* For so_contract group */
+
+/*@}*/ /* For shared_objects group */
+
+FRSH_CPP_END_DECLS
+
+#endif // _FRSH_SHARED_OBJECTS_H_
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef FRSH_SHARED_OBJECTS_TYPES_H_
+#define FRSH_SHARED_OBJECTS_TYPES_H_
+
+#include <time.h>
+#include "frsh_core_types.h"
+#include "frsh_configuration_parameters.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_shared_objects_types.h
+ **/
+
+/**
+ * @addtogroup sharedobj
+ *
+ * @{
+ **/
+
+/** Mutex object. Attributes are handled by FOSA **/
+typedef fosa_mutex_t frsh_mutex_t;
+
+
+/**
+ * Shared object handle: It is an opaque type (i.e. the internal
+ * structure of this data type is implementation dependent).
+ **/
+typedef FRSH_SHAREDOBJ_HANDLE_T_OPAQUE frsh_sharedobj_handle_t;
+
+/**
+ * Shared object textual label
+ **/
+typedef char frsh_sharedobj_label_t[FRSH_MAX_SIZE_SHARED_OBJ_LABEL + 1];
+
+/**
+ * Kind of shared object: protected or unprotected
+ */
+typedef enum
+ {FRSH_SOK_UNPROTECTED, FRSH_SOK_PROTECTED}
+frsh_sharedobj_kind_t;
+
+/**
+ * Kind of protected operation: read, write or unchecked
+ **/
+typedef enum
+ {FRSH_CSOK_UNCHECKED, FRSH_CSOK_READ, FRSH_CSOK_WRITE}
+frsh_csect_op_kind_t;
+
+/**
+ * Pointer to protected operation, which takes a pointer to
+ * the input parameters, and a pointer to the output
+ * parameters; the user is responsible for not exceeding the
+ * sizes of the respective input and output parameters data structures
+ */
+typedef void (*frsh_csect_op_t)
+ (const void * input_arg, void * output_arg);
+
+/**
+ * A memory area
+ */
+typedef struct {
+ size_t size;
+ void * area;
+} frsh_memory_area_data_t;
+
+/**
+ * Memory areas container
+ **/
+typedef struct {
+ int size; // = 0
+ frsh_memory_area_data_t memory_areas[FRSH_MAX_N_MEMORY_AREAS];
+} frsh_memory_areas_t;
+
+
+/**
+ * Critical section data (opaque type)
+ **/
+typedef FRSH_CSECT_T_OPAQUE frsh_csect_t;
+
+
+/**
+ * Container of a group of critical sections, up to a maximum size
+ **/
+typedef struct {
+ int size; // size of the group; initially=0
+ frsh_csect_t csects[FRSH_MAX_N_CRITICAL_SECTIONS]; // array of csect
+} frsh_csects_group_t;
+
+/*@}*/
+
+
+FRSH_CPP_END_DECLS
+
+#endif /* !FRSH_SHARED_OBJECTS_TYPES_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_spare_capacity.h
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef _FRSH_SPARE_CAPACITY_H_
+#define _FRSH_SPARE_CAPACITY_H_
+
+#include <time.h>
+#include <stdint.h>
+#include "frsh_spare_capacity_types.h"
+#include "frsh_core_types.h"
+#include "frsh_core.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_spare_capacity.h
+ **/
+
+#define FRSH_SPARE_CAPACITY_MODULE_SUPPORTED 1
+
+
+/**
+ * @file frsh_spare_capacity.h
+ *
+ * This file contains the function prototypes for the usage of
+ * spare capacity and dynamic reclamation.
+ **/
+
+/**
+ * @defgroup sparecapacity Spare Capacity module
+ *
+ * This module manages the partition of exceeding capacity at
+ * negotiation time between the vres that express their desire of
+ * optional requirements.
+ *
+ * It works by:
+ *
+ * - Allowing to define a range of budget and period instead of
+ * giving WCET values only. This range can be continuous or
+ * discrete.
+ *
+ * - Specifying a fairness measurement to compete with other vres in the
+ * division of the share.
+ *
+ * - Specifying a stability_time time for vres that need to have
+ * a assigned capacity remain const during time (they would be
+ * annoyed if their budget or period would change).
+ *
+ * There are no specific negotiation calls because the algorithms used
+ * in the core module take already these min-max ranges into account.
+ *
+ * An operation is available for applications to ask for a stability
+ * period of a specified length. The framework will then return the
+ * total capacity (execution time budget and virtual resource period)
+ * that the application is guaranteed to receive in this stability
+ * period. The rationale for this service is that jobs may span a
+ * number of virtual resource periods, and need to have a guaranteed
+ * amount of capacity before they can choose a higher quality (longer
+ * execution time) method, when multiple methods are available. Also
+ * applications may require that the capacity provided to them and
+ * hence the quality of results produced remains consistent for a
+ * period of time, so that consistent behaviour is provided for the
+ * user (e.g. multimedia applications).
+ *
+ * Requesting a new stability period has the effect of cancelling any
+ * previous one. So a subsequent request for stability up to the same
+ * point in time could return a lower total capacity, if spare capacity
+ * re-allocation is in progress due to the admission of a new
+ * application. If a stability period expires without having explicitly
+ * set a new one, the system may decide to perform a reallocation of
+ * spare resources at that point, or may defer this decision to some
+ * future point in time when it is appropriate. In both cases, a new
+ * stability period will start when the new spare capacity assignment
+ * is in effect.
+ *
+ *
+ * NOTE: When we talk here about "spare capacity" we mean STATIC extra
+ * capacity at NEGOTIATION TIME. This is the minimum capacity
+ * that the vres will get based on contract negotiation.
+ * This capacity is distributed based on the importance and
+ * weight values and is known before-hand at the beginning of
+ * a period.
+ *
+ * Besides this extra capacity, there is the DYNAMIC extra
+ * capacity that results at RUN TIME from earlier job endings of
+ * bounded-workload vres. This extra capacity can vary
+ * between each execution period and is not known beforehand.
+ *
+ * This extra run-time capacity is assigned if the following 2
+ * conditions are met:
+ *
+ * - FRSH_DYNAMIC_RECLAIMING_MODULE_SUPPORTED is defined to 1
+ * (in frsh_dynamic_reclaiming.h).
+ *
+ * - There is at least one vres willing to accept this extra
+ * capacity:
+ * - A FRSH_BOUNDED workload vres with a range of Budget
+ * and Period that can absorb the extra capacity and
+ * whose static_time period is not active.
+ * - An INDETERMINATE workload vres with an active
+ * static_time period.
+ * @{
+ **/
+
+
+
+/**
+ * frsh_contract_set_reclamation_params()
+ *
+ * The operation updates the specified contract parameters object by
+ * setting its maximum usable budget, minimum period, granularity,
+ * utilization set, weight, and importance to the specified input
+ * parameters.
+ *
+ * @param contract Contract object
+ * @param stability_time Time in which FRSH guarantees that the
+ * assigned budget and period will remain permanent
+ * even across renegotiations.
+ * @param budget_max The maximum budget that the vres aspires to
+ * get allocated.
+ * @param period_min The minimum period (therefore minimal
+ * interarrival time) that the vres may get for
+ * awakening and replenishment periods.
+ * @param granularity FRSH_CONTINUOUS: Use min-max values,
+ * FRSH_DISCRETE: Use utilization_set.
+ * @param utilization_set A structure of discrete triples (budget,
+ * period, deadline)
+ * @param importance non-cooperative urgency indicator. Vres with
+ * higher importance will get all spare capacity des
+ * @param weight cooperative urgency indicator. At equal
+ * importance, spare capacity will be distributed
+ * proportionally to weight levels.
+ *
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT : if contract is NULL \b or \n
+ * (budget_max value is grater than period_max or smaller than budget_min) \b or \n
+ * (period_min is smaller than budget_mint or larger than period_max) \b or \n
+ * (granularity is neither FRSH_CONTINUOUS nor FRSH_DISCRETE) \b or \n
+ * (granularity is FRSH_CONTINUOUS and
+ * utilization_set is not FRSH_NULL_UTILIZATION_SET) \b or \n
+ * (granularity is FRSH_DISCRETE and
+ * utilization_set is FRSH_NULL_UTILIZATION_SET \b or \n
+ * (utilization_set is not FRSH_NULL_UTILIZATION_SET and
+ * (size of utilization_set less than 2 or greater
+ * than FRSH_MAX_N_UTILIZATION_VALUES) ) \b or \n
+ * (weight < 0) \b or \n
+ * (importance is less than 1 or greater than FRSH_N_IMPORTANCE_LEVELS) \b or \n
+ * (the utilization_set elements are not in increasing utilization order) \b or \n
+ * (the first utilization value in the utilization_set does not match
+ * the pair (budget_min, period_max) of the contract) \b or \n
+ * (the last utilization value in the utilization_set does not match
+ * the pair (budget_max, period_min) of the contract)
+ *
+ **/
+int frsh_contract_set_reclamation_params(frsh_contract_t *contract,
+ const frsh_rel_time_t *stability_time,
+ const frsh_rel_time_t *budget_max,
+ const frsh_rel_time_t *period_min,
+ frsh_granularity_t granularity,
+ const frsh_utilization_set_t *utilization_set,
+ int importance,
+ int weight);
+
+/**
+ * frsh_contract_get_reclamation_params()
+ *
+ * The operation obtains the sparecapacity contract parameters from
+ * the contract object.
+ *
+ * @see frsh_set_contract_reclamation_parameters() for the meaning of
+ * each parameter.
+ *
+ * Only the utilization_values of the utilization_set
+ * that are in use, are copied (according to its size field).
+ *
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT : if contract is NULL
+ *
+ **/
+int frsh_contract_get_reclamation_params
+ (const frsh_contract_t *contract,
+ frsh_rel_time_t *stability_time,
+ frsh_rel_time_t *budget_max,
+ frsh_rel_time_t *period_min,
+ frsh_granularity_t *granularity,
+ frsh_utilization_set_t *utilization_set,
+ int *importance,
+ int *weight);
+
+
+/**
+ * frsh_vres_get_remaining_stability_time()
+ *
+ * This operation returns the stability_time for the vres.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or
+ * capacity is NULL \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres has been cancelled or it
+ * is not valid \n
+ *
+ **/
+int frsh_vres_get_remaining_stability_time(frsh_vres_id_t vres,
+ frsh_rel_time_t *stability_time);
+
+
+/**
+ * frsh_vres_set_stability_time:
+ *
+ * Dynamically set the stability time for a given virtual resource to
+ * the specified interval. This operation sets a new value for the
+ * stability time associated with the virtual resource. As a result of
+ * this call the system may change the allocation of resources to the
+ * current virtual resource. Regardless of whether the resources are
+ * reallocated or not, the call resets the stability period so that
+ * the level of resources allocated to the virtual resource is kept
+ * stable for at least the duration of the requested interval. The
+ * possibly new values of budget and period are returned in the
+ * corresponding parameters
+ */
+
+int frsh_vres_set_stability_time
+ (frsh_vres_id_t vres,
+ const frsh_rel_time_t *stability_time,
+ frsh_rel_time_t *budget,
+ frsh_rel_time_t *period);
+
+
+/**
+ * frsh_resource_get_capacity()
+ *
+ * This operation gets the spare capacity currently assigned to an
+ * importance level. The capacity is the number obtained divided by
+ * UINT32_MAX, and it represents the processor or network
+ * utilization.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or
+ * capacity is NULL \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under the FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres has been cancelled or it
+ * is not valid \n
+ *
+ **/
+int frsh_resource_get_capacity(const frsh_resource_type_t resource_type,
+ const frsh_resource_id_t resource_id,
+ const int importance,
+ uint32_t *capacity);
+
+
+/**
+ * frsh_resource_get_total_weight()
+ *
+ * This operation calculates the sum of the weight parameters for all
+ * vres in the system for a certain importance level at a specific
+ * resource_id.
+ *
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or
+ * total_weight is NULL \n
+ * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
+ * scheduled under FRSH \n
+ * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
+ * running \n
+ * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres has been cancelled or it
+ * is not valid \n
+ **/
+int frsh_resource_get_total_weight
+ (const frsh_resource_type_t resource_type,
+ const frsh_resource_id_t resource_id,
+ const int importance,
+ uint32_t *total_weight);
+
+
+/**
+ * frsh_vres_decrease_capacity()
+ *
+ * This operation is mainly intended for distributed systems but may
+ * also be useful for control application in uniprocessor systems.
+ *
+ * It allows the vres to ask for less budget and period that what he
+ * has actually received. The request must be compatible with the
+ * rest of contract parameters.
+ *
+ **/
+int frsh_vres_decrease_capacity(frsh_vres_id_t vres,
+ frsh_rel_time_t new_budget,
+ frsh_rel_time_t new_period);
+
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif // _FRSH_SPARE_CAPACITY_H_
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_spare_capacity_types.h
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef FRSH_SPARE_CAPACITY_TYPES_H_
+#define FRSH_SPARE_CAPACITY_TYPES_H_
+
+#include <time.h>
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_spare_capacity_types.h
+ **/
+
+/**
+ * @addtogroup sparecapacity
+ *
+ * @{
+ **/
+
+/*************************/
+/* D E F I N I T I O N S */
+/*************************/
+
+/** Granularity of spare capacity requirements: continuous or discrete **/
+typedef enum {FRSH_GR_CONTINUOUS, FRSH_GR_DISCRETE} frsh_granularity_t;
+
+/** Utilization (C, T, and D) **/
+typedef struct {
+ frsh_rel_time_t budget; // Execution time
+ frsh_rel_time_t period; // Period
+ frsh_rel_time_t deadline; // Deadline
+} frsh_utilization_t;
+
+/** List of utilization values **/
+typedef struct {
+ int size; // = 0
+ frsh_utilization_t utilizations[FRSH_MAX_N_UTILIZATION_VALUES];
+} frsh_utilization_set_t;
+
+// Constants for assigning default values
+#define FRSH_DEFAULT_GRANULARITY FRSH_GR_CONTINUOUS
+#define FRSH_DEFAULT_WEIGHT 1 // Cannot be zero with fsa_response_time
+#define FRSH_DEFAULT_IMPORTANCE 1
+
+// Constants for omitting the assignment of values to specific
+// arguments in calls to initialization functions
+#define FRSH_NULL_UTILIZATION_SET \
+ (frsh_utilization_set_t *)NULL
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+
+#endif /* !FRSH_SPARE_CAPACITY_TYPES_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_thread.h
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+#ifndef _FRSH_THREADS_H_
+#define _FRSH_THREADS_H_
+
+#include "frsh_core_types.h"
+#include "frsh_core.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_thread_attrs.h
+ **/
+
+/**
+ * @defgroup threadfunc FRSH thread functions.
+ * @ingroup core
+ *
+ * These functions are used to manage frsh_thread_t and
+ * frsh_thread_attr_t used in the public API of FRSH.
+ *
+ * @{
+ **/
+
+
+/*************************
+ * Thread attributes
+ *************************/
+
+/**
+ * frsh_thread_attr_init()
+ *
+ * Initialize a thread attributes object
+ *
+ * This function initializes the object pointed to by attr to all
+ * the default values defined by FRSH
+ *
+ * @return 0 if successful; otherwise it returns \n
+ * FOSA_ENOMEM: insufficient memory exists to initialize the thread
+ * attributes object
+ **/
+static inline int frsh_thread_attr_init(frsh_thread_attr_t *attr)
+{
+ return fosa_thread_attr_init(attr);
+}
+
+/**
+ * frsh_thread_attr_destroy()
+ *
+ * Destroy a thread attributes object
+ *
+ * This function is used to destroy the thread attributes object,
+ * pointed to by attr, and deallocate any system resources allocated for it
+ *
+ * Returns 0
+ */
+static inline int frsh_thread_attr_destroy(frsh_thread_attr_t *attr)
+{
+ return fosa_thread_attr_destroy(attr);
+}
+
+/**
+ * frsh_thread_attr_set_stacksize()
+ *
+ * Set the thread minimum stack size in a thread attributes object
+ *
+ * This function sets the minimum stack size of the thread attributes
+ * object attr to the value given by stacksize, in bytes. This
+ * function has no runtime effect on the stack size, except when the
+ * attributes object is used to create a thread, when it will be
+ * created with the specified minimum stack size
+ *
+ * @return 0 if successful, or the following error code:
+ * FOSA_EINVAL: the specified stacksize value is not supported in
+ * this implementation
+ */
+static inline int frsh_thread_attr_set_stacksize(frsh_thread_attr_t *attr, size_t stacksize)
+{
+ return fosa_thread_attr_set_stacksize(attr, stacksize);
+}
+
+/**
+ * frsh_thread_attr_get_stacksize()
+ *
+ * Get the thread minimum stack size from a thread attributes object
+ *
+ * This function sets the variable pointed to by stacksize to the
+ * minimum stack size stored in the thread attributes object attr.
+ *
+ * @return 0
+ */
+static inline int frsh_thread_attr_get_stacksize
+ (const frsh_thread_attr_t *attr, size_t *stacksize)
+{
+ return fosa_thread_attr_get_stacksize(attr, stacksize);
+}
+
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif
+
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_spare_capacity_types.h
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef FRSH_TIME_H_
+#define FRSH_TIME_H_
+
+#include "frsh_core_types.h"
+#include "frsh_core.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+/**
+ * @file frsh_time.h
+ **/
+
+
+/**
+ * \addtogroup core
+ **/
+/*@{*/
+
+/***********************
+ * Relational operations
+ ***********************/
+
+/**
+ * frsh_abs_time_smaller()
+ *
+ * Check if an absolute time is smaller than another one.
+ **/
+static inline bool frsh_abs_time_smaller(frsh_abs_time_t t1, frsh_abs_time_t t2)
+{
+ return fosa_abs_time_smaller(t1, t2);
+}
+
+/**
+ * frsh_rel_time_smaller()
+ *
+ * Check if a relative interval is smaller than another one.
+ **/
+static inline bool frsh_rel_time_smaller(frsh_rel_time_t t1, frsh_rel_time_t t2)
+{
+ return fosa_rel_time_smaller(t1, t2);
+}
+
+/**
+ * frsh_abs_time_smaller_or_equal()
+ *
+ * Check if an absolute time is smaller than or equal to another one.
+ **/
+static inline bool frsh_abs_time_smaller_or_equal(frsh_abs_time_t t1, frsh_abs_time_t t2)
+{
+ return fosa_abs_time_smaller_or_equal(t1, t2);
+}
+
+/**
+ * frsh_rel_time_smaller_or_equal()
+ *
+ * Check if a relative interval is smaller than or equal to another one.
+ **/
+static inline bool frsh_rel_time_smaller_or_equal(frsh_rel_time_t t1, frsh_rel_time_t t2)
+{
+ return fosa_rel_time_smaller_or_equal(t1, t2);
+}
+
+
+/***********************
+ * Arithmetic operations
+ ***********************/
+
+/**
+ * frsh_abs_time_incr()
+ *
+ * Add a relative interval to an absolute time.
+ */
+static inline frsh_abs_time_t frsh_abs_time_incr(frsh_abs_time_t base, frsh_rel_time_t interval)
+{
+ return fosa_abs_time_incr(base, interval);
+}
+
+/**
+ * frsh_rel_time_add()
+ *
+ * Add a relative interval to another one.
+ */
+static inline frsh_rel_time_t frsh_rel_time_add(frsh_rel_time_t t1, frsh_rel_time_t t2)
+{
+ return fosa_rel_time_add(t1, t2);
+}
+
+static inline frsh_rel_time_t frsh_rel_time_incr(frsh_rel_time_t t1, frsh_rel_time_t t2)
+{
+ return fosa_rel_time_add(t1, t2);
+}
+
+
+
+
+/**
+ * frsh_abs_time_decr
+ *
+ * Subtract a relative interval from an absolute time.
+ */
+static inline frsh_abs_time_t frsh_abs_time_decr(frsh_abs_time_t time, frsh_rel_time_t interval)
+{
+ return fosa_abs_time_decr(time, interval);
+}
+
+/**
+ * frsh_rel_time_decr()
+ *
+ * Subtract a relative interval from another one.
+ */
+static inline frsh_rel_time_t frsh_rel_time_decr(frsh_rel_time_t total, frsh_rel_time_t part)
+{
+ return fosa_rel_time_decr(total, part);
+}
+
+
+/**
+ * frsh_abs_time_extract_interval()
+ *
+ * Subtract two absolute times to get a relative interval.
+ */
+static inline frsh_rel_time_t frsh_abs_time_extract_interval(frsh_abs_time_t past, frsh_abs_time_t future)
+{
+ return fosa_abs_time_extract_interval(past, future);
+}
+
+
+static inline frsh_rel_time_t frsh_abs_time_subtract(frsh_abs_time_t past, frsh_abs_time_t future)
+{
+ return fosa_abs_time_extract_interval(past, future);
+}
+
+
+
+
+/**
+ * frsh_rel_time_times_integer()
+ *
+ * Multiplies a relative time by an integer
+ */
+static inline frsh_rel_time_t frsh_rel_time_times_integer(frsh_rel_time_t time, long multiplier)
+{
+ return fosa_rel_time_times_integer(time, multiplier);
+}
+
+/**
+ * frsh_rel_time_times_integer()
+ *
+ * Divides a relative time by an integer
+ **/
+static inline frsh_rel_time_t frsh_rel_time_divided_by_integer(frsh_rel_time_t time, long divider)
+{
+ return fosa_rel_time_divided_by_integer(time, divider);
+}
+
+
+/************************************
+ * Conversion to-from natural formats
+ * Note: Overflows may occur
+ ************************************/
+
+/**
+ * frsh_msec_to_rel_time()
+ *
+ * Convert an integer value of milliseconds into a relative time interval.
+ */
+static inline frsh_rel_time_t frsh_msec_to_rel_time(long msec)
+{
+ return fosa_msec_to_rel_time(msec);
+}
+
+/**
+ * frsh_rel_time_to_msec()
+ *
+ * Convert a relative interval into an integer number of milliseconds.
+ */
+static inline long frsh_rel_time_to_msec(frsh_rel_time_t interval)
+{
+ return fosa_rel_time_to_msec(interval);
+}
+
+/**
+ * frsh_msec_to_abs_time()
+ *
+ * Convert an integer value of milliseconds into an absolute time instant
+ */
+static inline frsh_abs_time_t frsh_msec_to_abs_time(long msec)
+{
+ return fosa_msec_to_abs_time(msec);
+}
+
+/**
+ * frsh_abs_time_to_msec()
+ *
+ * Convert an absolute instant into an integer number of milliseconds.
+ */
+static inline long frsh_abs_time_to_msec(frsh_abs_time_t instant)
+{
+ return fosa_abs_time_to_msec(instant);
+}
+
+/**
+ * frsh_usec_to_rel_time()
+ *
+ * Convert an integer value of microseconds into an absolute instant.
+ */
+static inline frsh_rel_time_t frsh_usec_to_rel_time(long usec)
+{
+ return fosa_usec_to_rel_time(usec);
+}
+
+
+/**
+ * frsh_rel_time_to_usec()
+ *
+ * Convert a relative interval into an integer number of microseconds.
+ */
+static inline long frsh_rel_time_to_usec(frsh_rel_time_t interval)
+{
+ return fosa_rel_time_to_usec(interval);
+}
+
+/**
+ * frsh_usec_to_abs_time()
+ *
+ * Convert an integer value of microseconds into an absolute instant.
+ */
+static inline frsh_abs_time_t frsh_usec_to_abs_time(long usec)
+{
+ return fosa_usec_to_abs_time(usec);
+}
+
+
+/**
+ * frsh_abs_time_to_usec()
+ *
+ * Convert a relative interval into an integer number of microseconds.
+ */
+static inline long frsh_abs_time_to_usec(frsh_abs_time_t interval)
+{
+ return fosa_abs_time_to_usec(interval);
+}
+
+/**
+ * frsh_nsec_to_rel_time()
+ *
+ * Convert an integer value of microseconds into an absolute instant.
+ */
+static inline frsh_rel_time_t frsh_nsec_to_rel_time(long nsec)
+{
+ return fosa_nsec_to_rel_time(nsec);
+}
+
+
+/**
+ * frsh_rel_time_to_nsec()
+ *
+ * Convert a relative interval into an integer number of microseconds.
+ */
+static inline long frsh_rel_time_to_nsec(frsh_rel_time_t interval)
+{
+ return fosa_rel_time_to_nsec(interval);
+}
+
+/**
+ * frsh_nsec_to_abs_time()
+ *
+ * Convert an integer value of microseconds into an absolute instant.
+ */
+static inline frsh_abs_time_t frsh_nsec_to_abs_time(long nsec)
+{
+ return fosa_nsec_to_abs_time(nsec);
+}
+
+
+/**
+ * frsh_abs_time_to_nsec()
+ *
+ * Convert a relative interval into an integer number of microseconds.
+ */
+static inline long frsh_abs_time_to_nsec(frsh_abs_time_t interval)
+{
+ return fosa_abs_time_to_nsec(interval);
+}
+
+/******************************************
+ * Conversion to-from POSIX timespec format
+ ******************************************/
+
+/**
+ * frsh_timespec_to_rel_time()
+ *
+ * Convert a POSIX timespec value into a relative time interval.
+ */
+static inline frsh_rel_time_t frsh_timespec_to_rel_time(struct timespec interval)
+{
+ return fosa_timespec_to_rel_time(interval);
+}
+
+/**
+ * frsh_rel_time_to_timespec()
+ *
+ * Convert a relative interval into a POSIX timespec value.
+ */
+static inline struct timespec frsh_rel_time_to_timespec(frsh_rel_time_t interval)
+{
+ return fosa_rel_time_to_timespec(interval);
+}
+
+/**
+ * frsh_timespec_to_abs_time()
+ *
+ * Convert a POSIX timespec value into an absolute time.
+ */
+static inline frsh_abs_time_t frsh_timespec_to_abs_time(struct timespec time)
+{
+ return fosa_timespec_to_abs_time(time);
+}
+
+/**
+ * frsh_abs_time_to_timespec()
+ *
+ * Convert an absolute time into a POSIX timespec value.
+ */
+static inline struct timespec frsh_abs_time_to_timespec(frsh_abs_time_t time)
+{
+ return fosa_abs_time_to_timespec(time);
+}
+
+
+/**
+ * frsh_eat()
+ *
+ * Keep the thread busy executing for a given period of time.
+ **/
+static inline void frsh_eat(frsh_rel_time_t *cpu_time)
+{
+ fosa_eat(cpu_time);
+}
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif /* !FOSA_TIME_H_ */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2009 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_spare_capacity_types.h
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#ifndef FRSH_TIME_TYPES_H_
+#define FRSH_TIME_TYPES_H_
+
+#include <fosa_types.h>
+
+/**
+ * @file frsh_time_types.h
+ **/
+
+
+/**
+ * \addtogroup core
+ **/
+/*@{*/
+
+/** the time types shall have assignment and equal operators **/
+typedef fosa_abs_time_t frsh_abs_time_t;
+typedef fosa_rel_time_t frsh_rel_time_t;
+
+
+/*@}*/
+
+#endif /* !FRSH_TIME_TYPES_H_ */
--- /dev/null
+/**************************************************************************/
+/* Copyright (C) 2010 Czech Technical University in Prague */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+
+#ifndef _FRSH_TRANSACTION_H_
+#define _FRSH_TRANSACTION_H_
+
+#include "frsh_cpp_macros.h"
+#include "frsh_core_types.h"
+
+FRSH_CPP_BEGIN_DECLS
+
+struct fres_transaction_t_type;
+
+/* frsh_transaction_t is a pointer to resemble how frsh_contract_t is
+ * defined. */
+typedef struct fres_transaction_t_type *frsh_transaction_t;
+
+/**
+ * Initialize a transaction.
+ *
+ * @param transaction
+ *
+ * @param name The name of the transaction which can be used in
+ * frsh_transaction_wait_for_name().
+ *
+ * @return Zero on success, non-zero error code on return.
+ */
+int
+frsh_transaction_init(frsh_transaction_t *transaction,
+ char *name);
+
+/**
+ * Deallocates memory of the transaction object.
+ *
+ * @param transaction
+ */
+void
+frsh_transaction_destroy(frsh_transaction_t *transaction);
+
+/**
+ * Add a contract to the transaction.
+ *
+ * @param transaction Transaction
+ * @param contract Contract to add
+ *
+ * @param index Index of the contract within the transaction. The
+ * index is used in frsh_transaction_alloc_vres(). The first added
+ * contract must have zero index, the second one, etc.
+ *
+ * @return Zero on success, non-zero error code on return.
+ */
+int
+frsh_transaction_add_contract(frsh_transaction_t *transaction,
+ frsh_contract_t *contract,
+ int index);
+
+/**
+ * Negotiates a multi-resource transaction.
+ *
+ * No resource is allocated in this step of negotiation. Use
+ * frsh_transaction_alloc_vres() to allocate resource and use it in
+ * application.
+ *
+ * @param trans Transaction with added contracts.
+ *
+ * @return Zero on success, non-zero error code on return.
+ */
+int
+frsh_transaction_negotiate(frsh_transaction_t *trans);
+
+/**
+ * Cancels a negotiated transaction.
+ *
+ * @param trans
+ *
+ * @return Zero on success, non-zero error code on return.
+ */
+int
+frsh_transaction_cancel(frsh_transaction_t *trans);
+
+/**
+ * Retrieves a negotiated transaction by name.
+ *
+ * Applications that do not initiate transaction negotiation need a
+ * way to participate in the transaction. This function waits until
+ * the transaction with a given @a name is negotiated and then returns
+ * the @a transaction object.
+ *
+ * @param name
+ * @param transaction
+ *
+ * @return Zero on success, non-zero error code on return.
+ */
+int
+frsh_transaction_wait_for_name(frsh_transaction_t *transaction,
+ const char *name);
+/**
+ * Allocates VRES from the negotiated transaction.
+ *
+ * Given the transaction object and an index (see
+ * frsh_transaction_add_contract()) this function requests allocation
+ * of the
+ *
+ * @param t
+ * @param vres
+ * @param index
+ *
+ * @return
+ */
+int
+frsh_transaction_alloc_vres(frsh_transaction_t *t,
+ int index,
+ frsh_vres_id_t *vres);
+
+FRSH_CPP_END_DECLS
+
+#endif // _FRSH_TRANSACTION_H_
--- /dev/null
+# Doxyfile 1.5.6
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = "FRSH_FORB"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = doc
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek,
+# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish,
+# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish,
+# and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen to replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = YES
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page. This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT =
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH = .
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code. Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to FRAME, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature. Other possible values
+# for this tag are: HIERARCHIES, which will generate the Groups, Directories,
+# and Class Hiererachy pages using a tree view instead of an ordered list;
+# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which
+# disables this behavior completely. For backwards compatibility with previous
+# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE
+# respectively.
+
+GENERATE_TREEVIEW = NONE
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = NO
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = YES
+
+# By default doxygen will write a font called FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME = FreeSans
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is enabled by default, which results in a transparent
+# background. Warning: Depending on the platform used, enabling this option
+# may lead to badly anti-aliased labels on the edges of a graph (i.e. they
+# become hard to read).
+
+DOT_TRANSPARENT = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+default_CONFIG = CONFIG_FRSH_FORB=y
+SUBDIRS=$(ALL_OMK_SUBDIRS)
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+default_CONFIG = CONFIG_DEMO_VIDEO=y CONFIG_DEMO_CAMERA=n CONFIG_DEMO_DCAMERA=y
+
+
+SUBDIRS=$(SUBDIRS-y)
+SUBDIRS-$(CONFIG_DEMO_VIDEO) += video
+SUBDIRS-$(CONFIG_DEMO_CAMERA) += camera
+SUBDIRS-$(CONFIG_DEMO_DCAMERA) += dcamera
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+LDFLAGS+= -L/usr/X11R6/lib
+C_INCLUDE_PATH = -I/usr/X11R6/include
+GLUT_LIBS = glut GL GLU
+FRSH_LIBS = frsh
+lib_LOADLIBES+= $(GLUT_LIBS) m pthread rt $(FRSH_LIBS)
+
+bin_PROGRAMS = camera
+camera_SOURCES = camera.c show_video_v4l_main.c show_video_v4l_capture.c\
+ capture_v4l.c extract_skin_color.c
--- /dev/null
+#include <frsh.h>
+#include <error.h>
+
+#include "camera.h"
+
+int main(int argc, char *argv[])
+{
+ frsh_vres_id_t vres;
+ frsh_thread_attr_t attr;
+ frsh_thread_id_t thread;
+ frsh_contract_t contract;
+ frsh_rel_time_t budget, period;
+ int ret;
+ video_args_t video_args;
+
+ video_args.argc = argc;
+ video_args.argv = argv;
+
+ if (frsh_init()) {
+ error(1, 0, "FRSH initialization failed\n");
+
+ }
+
+ /* Contract negotiation for CPU */
+ ret = frsh_contract_init(&contract);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ budget = fosa_msec_to_rel_time(50);
+ period = fosa_msec_to_rel_time(100);
+ ret = frsh_contract_set_basic_params(&contract,
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+ ret = frsh_contract_set_resource_and_label(&contract, FRSH_RT_PROCESSOR,
+ 0,"aqcpu_cont1");
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ ret = frsh_contract_negotiate(&contract, &vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+
+ printf("Aqcpu vres negotiated\n");
+ pthread_attr_init(&attr);
+ ret = frsh_thread_create_and_bind(vres, &thread, &attr,
+ video_thread, (void*) &video_args);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_thread_create_and_bind");
+
+ pthread_join(thread.pthread_id, (void**) NULL);
+ printf("Test PASSED!\n");
+
+ return 0;
+}
--- /dev/null
+#ifndef CAMERA_H
+#define CAMERA_H
+
+#define PORT 65111
+#define PROTO FRSH_NETPF_FWP
+
+typedef struct video_args{
+ int argc;
+ char** argv;
+} video_args_t;
+
+void* video_thread(void* args);
+
+#endif /* CAMERA_H */
--- /dev/null
+/*==========================================================================
+ $Id$
+ capture_v4l.c: Functions for capturing image using Video4Linux.
+ Written by Naoyuki Ichimura, AIST, 2001.
+==========================================================================*/
+
+#include "capture_v4l.h"
+
+/*=== Global variable for this module ===*/
+static unsigned char *frame_buf;
+
+/*============================================================================
+ Functions for Device Open and Check
+============================================================================*/
+int CaptureV4LOpen( char *device_name )
+{
+
+ int fd;
+
+/*======= Open Video4Linux device ==========================*/
+ if( ( fd = open( device_name , O_RDWR ) ) == -1 ) {
+ return -1;
+ }
+
+ return fd;
+
+}
+
+int CaptureV4LGetDeviceCapability( int fd , struct video_capability *vcap )
+{
+
+/*======= Get device capabilities ==========================*/
+ if( ioctl( fd , VIDIOCGCAP , vcap ) == -1 ) {
+ return -1;
+ }
+
+ return 0;
+
+}
+
+void CaptureV4LDisplayDeviceCapability( struct video_capability vcap )
+{
+
+ fprintf( stdout , "*** Device information ***\n" );
+
+/*======= Display deivce name =============================*/
+ fprintf( stdout , "Device name:%s.\n" , vcap.name );
+
+/*======= Display deivce types ============================*/
+ fprintf( stdout , "Type of device:\n" );
+ if( vcap.type & VID_TYPE_CAPTURE ) {
+ fprintf( stdout , "Capture is OK.\n" );
+ } else {
+ fprintf( stderr , "This device may NOT be used for capture. Are you sure about it ?\n" );
+ }
+ if( vcap.type & VID_TYPE_TUNER ) {
+ fprintf( stdout , "Tuner exists.\n" );
+ }
+ if( vcap.type & VID_TYPE_TELETEXT ) {
+ fprintf( stdout , "Teletext can be used.\n" );
+ }
+ if( vcap.type & VID_TYPE_OVERLAY ) {
+ fprintf( stdout , "Overlay is OK.\n" );
+ }
+ if( vcap.type & VID_TYPE_CHROMAKEY ) {
+ fprintf( stdout , "Overlay by chromakey is OK.\n" );
+ }
+ if( vcap.type & VID_TYPE_CLIPPING ) {
+ fprintf( stdout , "Clipping overlay is OK.\n" );
+ }
+ if( vcap.type & VID_TYPE_FRAMERAM ) {
+ fprintf( stdout , "Overlay for frame buffer is OK.\n" );
+ }
+ if( vcap.type & VID_TYPE_SCALES ) {
+ fprintf( stdout , "Scaling by hardware can be used.\n" );
+ }
+ if( vcap.type & VID_TYPE_MONOCHROME ) {
+ fprintf( stdout , "Capture of monochrome image is OK.\n" );
+ }
+ if( vcap.type & VID_TYPE_SUBCAPTURE ) {
+ fprintf( stdout , "Capture of a part of image is OK.\n" );
+ }
+ fprintf( stdout , "\n" );
+
+/*======= Display number of video channels and audio ones ===*/
+ fprintf( stdout , "Number of channels: %d\n" , vcap.channels );
+ fprintf( stdout , "Number of audio devices: %d\n" , vcap.audios );
+
+ if( vcap.channels > MAX_NO_CHANNEL ) {
+ fprintf( stderr , "It seems that too many channels exist in this device: %d.\n" , vcap.channels );
+ }
+
+/*======= Display image size ================================*/
+ fprintf( stdout , "Maximum width of image: %d\n" , vcap.maxwidth );
+ fprintf( stdout , "Maximum height of image: %d\n", vcap.maxheight );
+ fprintf( stdout , "Minimum width of image: %d\n" , vcap.minwidth );
+ fprintf( stdout , "Minimum height of image: %d\n" , vcap.minheight );
+ fprintf( stdout , "\n" );
+
+}
+
+int CaptureV4LGetChannelInfo( int fd , struct video_channel vch[MAX_NO_CHANNEL] , int no_channel )
+{
+
+ int i;
+
+/*======= Get channel information ==========================*/
+ for( i = 0 ; i < no_channel ; i++ ) {
+ vch[i].channel = i; /* channel number */
+ if( ioctl( fd , VIDIOCGCHAN , &vch[i] ) == -1 ) {
+ return -1;
+ }
+ }
+
+ return 0;
+
+}
+
+void CaptureV4LDisplayChannelInfo( struct video_channel vch[MAX_NO_CHANNEL] , int no_channel )
+{
+
+ int i;
+
+ for( i = 0 ; i < no_channel ; i++ ) {
+ fprintf( stdout , "*** Channel number: %d ***\n" , vch[i].channel );
+ fprintf( stdout , "Channel name: %s\n" , vch[i].name );
+ if( vch[i].flags & VIDEO_VC_TUNER ) {
+ fprintf( stdout , "This channel has a tuner.\n" );
+ }
+ if( vch[i].flags & VIDEO_VC_AUDIO ) {
+ fprintf( stdout , "This channel has a audio.\n" );
+ }
+ if( vch[i].type & VIDEO_TYPE_TV ) {
+ fprintf( stdout , "Channel type is TV.\n" );
+ }
+ if( vch[i].type & VIDEO_TYPE_CAMERA ) {
+ fprintf( stdout , "Channel type is camera.\n" );
+ }
+ if( vch[i].norm & VIDEO_MODE_NTSC ) {
+ fprintf( stdout , "Video mode is NTSC.\n" );
+ }
+ if( vch[i].norm & VIDEO_MODE_PAL ) {
+ fprintf( stdout , "Video mode is PAL.\n" );
+ }
+ if( vch[i].norm & VIDEO_MODE_SECAM ) {
+ fprintf( stdout , "Video mode is SECAM.\n" );
+ }
+ }
+ fprintf( stdout , "\n" );
+
+}
+
+int CaptureV4LGetPictureInfo( int fd , struct video_picture *vp )
+{
+
+/*======= Get channel information ==========================*/
+ if( ioctl( fd , VIDIOCGPICT , vp ) == -1 ) {
+ return -1;
+ }
+
+ return 0;
+
+}
+
+void CaptureV4LDisplayPictureInfo( struct video_picture vp )
+{
+
+ fprintf( stdout , "*** Picture information ***\n" );
+ fprintf( stdout , "Brightness: %d\n" , vp.brightness );
+ fprintf( stdout , "Hue: %d\n" , vp.hue );
+ fprintf( stdout , "Color: %d\n" , vp.colour );
+ fprintf( stdout , "Contrast: %d\n" , vp.contrast );
+ fprintf( stdout , "Whiteness: %d\n" , vp.whiteness );
+ fprintf( stdout , "Depth: %d\n" , vp.depth );
+ switch( vp.palette ) {
+ case VIDEO_PALETTE_GREY:
+ fprintf( stdout , "Gray scale.\n" );
+ break;
+
+ case VIDEO_PALETTE_RGB565:
+ fprintf( stdout , "16bit RGB.\n" );
+ break;
+
+ case VIDEO_PALETTE_RGB24:
+ fprintf( stdout , "24bit RGB.\n" );
+ break;
+
+ case VIDEO_PALETTE_RGB32:
+ fprintf( stdout , "32bit RGB.\n" );
+ break;
+
+ case VIDEO_PALETTE_YUV422:
+ fprintf( stdout , "YUV422.\n" );
+ break;
+
+ default:
+ break;
+
+ }
+
+}
+
+int CaptureV4LGetMemoryMapInfo( int fd , struct video_mbuf *vm )
+{
+
+/*======= Get channel information ==========================*/
+ if( ioctl( fd , VIDIOCGMBUF , vm ) == -1 ) {
+ return -1;
+ }
+
+ return 0;
+
+}
+
+void CaptureV4LDisplayMemoryMapInfo( struct video_mbuf vm )
+{
+
+ int i;
+
+ fprintf( stdout , "Memory size: %d\n" , vm.size );
+ fprintf( stdout , "Number of frames: %d\n" , vm.frames );
+ for( i = 0 ; i < vm.frames ; i++ ) {
+ fprintf( stdout , "Offset (frame %d): %d\n" , i , vm.offsets[i] );
+ }
+
+}
+
+/*============================================================================
+ Functions for preparation of capture
+============================================================================*/
+int CaptureV4LSelectChannel( int fd , struct video_channel vch[MAX_NO_CHANNEL] , int channel_no )
+{
+
+ vch[channel_no].norm = VIDEO_MODE_NTSC;
+ if( ioctl( fd , VIDIOCSCHAN , &vch[channel_no] ) == -1 ) {
+ return -1;
+ }
+
+ return 0;
+
+}
+
+int CaptureV4LMemoryMapping( int fd , struct video_mbuf vm )
+{
+
+ if( ( frame_buf = (unsigned char *)mmap( 0 , (size_t)vm.size , PROT_READ | PROT_WRITE , MAP_SHARED , fd , 0 ) ) == MAP_FAILED ) {
+ return -1;
+ }
+
+ return 0;
+
+}
+
+/*============================================================================
+ Functions for capture
+============================================================================*/
+int CaptureV4LSimpleCapture( int fd , struct video_mmap *vmap )
+{
+
+/*======= Begin capture ====================================*/
+ if( ioctl( fd , VIDIOCMCAPTURE , vmap ) == -1 ) {
+ return -1;
+ }
+
+/*======= Wait capture =====================================*/
+ if( ioctl( fd , VIDIOCSYNC , &(vmap->frame) ) == -1 ) {
+ return -1;
+ }
+ return 0;
+}
+
+int CaptureV4LDoubleBufferingInitCapture( int fd , struct video_mmap *vmap )
+{
+
+/*======= Capture image into frame buffers at beginning ====*/
+ vmap->frame = 0;
+ if( ioctl( fd , VIDIOCMCAPTURE , vmap ) == -1 ) {
+ return -1;
+ }
+ vmap->frame = 1;
+ if( ioctl( fd , VIDIOCMCAPTURE , vmap ) == -1 ) {
+ return -1;
+ }
+ /*=== Set initial frame number ===*/
+ vmap->frame = 0;
+ return 0;
+}
+
+int CaptureV4LDoubleBufferingCaptureWait( int fd , struct video_mmap *vmap )
+{
+
+/*======= Wait Capture ====================================*/
+ if( ioctl( fd , VIDIOCSYNC , &(vmap->frame) ) == -1 ) {
+ return -1;
+ }
+
+ return 0;
+
+}
+
+int CaptureV4LDoubleBufferingCaptureNextFrame( int fd , struct video_mmap *vmap )
+{
+
+/*======= Capture next frame into current buffer ==========*/
+ if( ioctl( fd , VIDIOCMCAPTURE , vmap ) == -1 ) {
+ return -1;
+ }
+
+/*======= Change buffer ===================================*/
+ if( vmap->frame == 0 ) {
+ vmap->frame = 1;
+ } else {
+ vmap->frame = 0;
+ }
+
+ return 0;
+
+}
+
+/*============================================================================
+ Functions for image array
+============================================================================*/
+unsigned char *CaptureV4LSetImage( struct video_mmap vmap , struct video_mbuf vm )
+{
+
+ unsigned char tmpc;
+ unsigned char *pixel_pos;
+
+ int i;
+
+/*======= Change order of data from BGR to RGB ===============*/
+ pixel_pos = frame_buf+vm.offsets[vmap.frame];
+ for( i = 0 ; i < vmap.height*vmap.width ; i++ ) {
+ tmpc = pixel_pos[2];
+ pixel_pos[2] = pixel_pos[0];
+ pixel_pos[0] = tmpc;
+ pixel_pos += RGB;
+ }
+
+ return frame_buf+vm.offsets[vmap.frame];
+
+}
+
+void CaptureV4LSetImageDownSamplingForOpenGL( struct video_mmap vmap , struct video_mbuf vm , int down_sampling_rate , unsigned char *image , unsigned char *disp_image )
+{
+
+ unsigned char *pixel_pos;
+
+ int i,j;
+ int dheight,dwidth;
+
+/*======= Change order of data from BGR(capture board order) to RGB for processing ===============*/
+ dheight = vmap.height/down_sampling_rate;
+ dwidth = vmap.width/down_sampling_rate;
+ pixel_pos = frame_buf+vm.offsets[vmap.frame];
+ for( i = 0 ; i < dheight ; i++ ) {
+ for( j = 0 ; j < dwidth; j++ ) {
+ /* image for processing: RGB order */
+ image[((dheight-1-i)*dwidth+j)*RGB] = pixel_pos[2];
+ image[((dheight-1-i)*dwidth+j)*RGB+1] = pixel_pos[1];
+ image[((dheight-1-i)*dwidth+j)*RGB+2] = pixel_pos[0];
+ /* image for display: BRG order */
+ disp_image[((dheight-1-i)*dwidth+j)*RGB] = pixel_pos[0];
+ disp_image[((dheight-1-i)*dwidth+j)*RGB+1] = pixel_pos[1];
+ disp_image[((dheight-1-i)*dwidth+j)*RGB+2] = pixel_pos[2];
+ pixel_pos += RGB*down_sampling_rate;
+ }
+ pixel_pos += vmap.width*RGB*(down_sampling_rate-1);
+ }
+
+}
--- /dev/null
+/*==========================================================================
+ $Id$
+ capture_v4l.h: Header file for capturing image using Video4Linux.
+ Written by Naoyuki Ichimura, AIST, 2001.
+==========================================================================*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include <sys/types.h> /* for open() */
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <sys/ioctl.h> /* for ioctl() */
+
+#include <unistd.h> /* for mmap() */
+#include <sys/mman.h>
+
+#include <linux/videodev.h> /* for V4L */
+
+/*=====================================================
+ Definitions for Video4Linux
+=====================================================*/
+#define DEFAULT_DEVICE_NAME "/dev/video0" /* device file name */
+#define MAX_NO_CHANNEL 10 /* maximum number of channel of frame grabber */
+#define CAPTURE_IMAGE_WIDTH 640 /* image width */
+#define CAPTURE_IMAGE_HEIGHT 480 /* image height */
+
+#define RGB 3 /* number of bit plane */
+
+#define COMPOSITE1 0 /* for IO-DATA GV-VCP2M/PCI */
+#define COMPOSITE2 1
+#define S_VIDEO 2
+
+#define DOWN_SAMPLING_RATE 2 /* to remove even number field */
+
+#define IMAGE_WIDTH_DS CAPTURE_IMAGE_WIDTH/DOWN_SAMPLING_RATE /* image size after down sampling */
+#define IMAGE_HEIGHT_DS CAPTURE_IMAGE_HEIGHT/DOWN_SAMPLING_RATE
+
+/*=====================================================
+ Function Prototypes
+=====================================================*/
+int CaptureV4LOpen( char *device_name );
+int CaptureV4LGetDeviceCapability( int fd , struct video_capability *vcap );
+void CaptureV4LDisplayDeviceCapability( struct video_capability vcap );
+int CaptureV4LGetChannelInfo( int fd , struct video_channel vch[MAX_NO_CHANNEL] , int no_channel );
+void CaptureV4LDisplayChannelInfo( struct video_channel vch[MAX_NO_CHANNEL] , int no_channel );
+int CaptureV4LGetPictureInfo( int fd , struct video_picture *vp );
+void CaptureV4LDisplayPictureInfo( struct video_picture vp );
+int CaptureV4LGetMemoryMapInfo( int fd , struct video_mbuf *vm );
+void CaptureV4LDisplayMemoryMapInfo( struct video_mbuf vm );
+
+int CaptureV4LSelectChannel( int fd , struct video_channel vch[MAX_NO_CHANNEL] , int channel_no );
+int CaptureV4LMemoryMapping( int fd , struct video_mbuf vm );
+
+int CaptureV4LSimpleCapture( int fd , struct video_mmap *vmap );
+int CaptureV4LDoubleBufferingInitCapture( int fd , struct video_mmap *vmap );
+int CaptureV4LDoubleBufferingCaptureWait( int fd , struct video_mmap *vmap ) ;
+int CaptureV4LDoubleBufferingCaptureNextFrame( int fd , struct video_mmap *vmap );
+
+unsigned char *CaptureV4LSetImage( struct video_mmap vmap , struct video_mbuf vm );
+void CaptureV4LSetImageDownSamplingForOpenGL( struct video_mmap vmap , struct video_mbuf vm , int down_sampling_rate , unsigned char *image , unsigned char *disp_image );
+
+
--- /dev/null
+/*==========================================================================
+ $Id$
+ extract_skin_color.c: Functions for extracting skin color from image
+ using simple thresholding.
+ Written by Naoyuki Ichimura, AIST, 2001.
+==========================================================================*/
+
+#include "show_video_v4l.h"
+#include "extract_skin_color.h"
+
+void ExtractSkinColorSimpleThresholding( unsigned char *image , int iheight , int iwidth , unsigned char *skin_map )
+{
+
+ static unsigned char tmp_skin_map[IMAGE_WIDTH_DS*IMAGE_HEIGHT_DS]; /* Skin color map */
+
+ int i,j,k,l;
+ int hblock_size;
+ int no_skin_pixel;
+
+ double r,g,b; /* color components */
+ double sum_cc; /* sum of color components */
+
+/*======== Extract candidate pixels =======================================*/
+ for( i = 0 ; i < iheight ; i++ ) {
+ for( j = 0 ; j < iwidth ; j++ ) {
+
+ /*=== Calculate color component for skin color ===*/
+ sum_cc = (double)(image[(i*iwidth+j)*RGB]+image[(i*iwidth+j)*RGB+1]+image[(i*iwidth+j)*RGB+2]);
+ r = (double)image[(i*iwidth+j)*RGB]/sum_cc; /* r=R/(R+G+B) */
+ g = (double)image[(i*iwidth+j)*RGB+1]/sum_cc; /* g=G/(R+G+B) */
+ b = (double)image[(i*iwidth+j)*RGB+2]/sum_cc; /* b=B/(R+G+B) */
+ if( r > MIN_THRESH_r && r < MAX_THRESH_r ) {
+ tmp_skin_map[i*iwidth+j] = 1;
+ } else {
+ tmp_skin_map[i*iwidth+j] = 0;
+ }
+
+ }
+ }
+
+/*======== Post processing: dilation by majority in block (3x3) ========*/
+ hblock_size = BLOCK_SIZE/2;
+ for( i = hblock_size ; i < iheight-hblock_size ; i += BLOCK_SIZE ) {
+ for( j = hblock_size ; j < iwidth-hblock_size ; j += BLOCK_SIZE ) {
+ no_skin_pixel = 0;
+ for( k = -hblock_size ; k <= hblock_size ; k++ ) {
+ for( l = -hblock_size ; l <= hblock_size ; l++ ) {
+ if( tmp_skin_map[(i+k)*iwidth+(j+l)] ) {
+ no_skin_pixel++;
+ }
+ }
+ }
+ if( no_skin_pixel > BLOCK_SIZE*BLOCK_SIZE/2 ) { /* use majority rule */
+ for( k = -hblock_size ; k <= hblock_size ; k++ ) {
+ for( l = -hblock_size ; l <= hblock_size ; l++ ) {
+ skin_map[(i+k)*iwidth+(j+l)] = 1;
+ }
+ }
+ } else {
+ for( k = -hblock_size ; k <= hblock_size ; k++ ) {
+ for( l = -hblock_size ; l <= hblock_size ; l++ ) {
+ skin_map[(i+k)*iwidth+(j+l)] = 0;
+ }
+ }
+ }
+ }
+ }
+
+}
+
+void ShowSkinRegion( unsigned char *skin_map , int iheight , int iwidth )
+{
+
+ int i,j;
+
+ glColor3f( 0.0 , 1.0 , 0.0 ); /* green */
+ glPointSize( 2.0 ); /* point size */
+ for( i = 0 ; i < iheight ; i++ ) {
+ for( j = 0 ; j < iwidth ; j++ ) {
+ if( skin_map[i*iwidth+j] ) {
+ DisplayPoint( (double)j , (double)i );
+ }
+ }
+ }
+
+}
--- /dev/null
+/*==========================================================================
+ $Id$
+ extract_skin_color.h: Header file for extracting skin color from image
+ using simple thresholding.
+ Written by Naoyuki Ichimura, AIST, 2001.
+==========================================================================*/
+
+/*=== Thresholds for skin color ====*/
+#define MIN_THRESH_r 0.38
+#define MAX_THRESH_r 0.48
+
+/*=== for skin map =================*/
+#define BLOCK_SIZE 3 /* must be odd nubmer */
+#define THRESH_SKIN_PIXEL 50*50
+
+/*=== Definitions for display point by OpenGL ===*/
+#define DisplayPoint( x , y ) glBegin(GL_POINTS); glVertex2f( (x) , (y) ); glEnd();
+
+/*=== Prototypes ===*/
+void ExtractSkinColorSimpleThresholding( unsigned char *image , int iheight , int iwidth , unsigned char *skin_map );
+void ShowSkinRegion( unsigned char *skin_map , int iheight , int iwidth );
--- /dev/null
+# $Id$
+# Makefile:
+# Make file for show_video_v4l
+#
+
+#
+# macros
+#
+GLUT_LDFLAG = -L/usr/X11R6/lib -lglut -lGL -lGLU
+LDFLAGS = $(GLUT_LDFLAG) -lm
+
+GLUT_INCFLAG = -I/usr/X11R6/include
+INCFLAGS = $(GLUT_INCFLAG)
+
+CC = gcc
+CFLAGS = -O
+
+SRCS = show_video_v4l_main.c show_video_v4l_capture.c capture_v4l.c extract_skin_color.c
+HDRS = show_video_v4l.h capture_v4l.h extract_skin_color.h
+OBJS = $(SRCS:.c=.o)
+TARGET = show_video_v4l
+
+#
+# compile
+#
+.c.o:
+ $(CC) $(INCFLAGS) $(CFLAGS) -c $<
+#
+# link
+#
+$(TARGET) : $(OBJS)
+ $(CC) -o $@ $(OBJS) $(LDFLAGS)
+
+#
+# compare time
+#
+show_video_v4l_main.o : show_video_v4l_main.c $(HDRS)
+show_video_v4l_capture.o : show_video_v4l_capture.c $(HDRS)
+capture_v4l.o : capture_v4l.c $(HDRS)
+extract_skin_color.o : extract_skin_color.c $(HDRS)
+
+clean:
+ rm -f $(OBJS) $(TARGET) *~
--- /dev/null
+/*==========================================================================
+ $Id$
+ show_video_v4l.h: Header file for capturing video using V4L.
+ Written by Naoyuki Ichimura, AIST, 2001.
+==========================================================================*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include <GL/gl.h> /* for GLUT */
+#include <GL/glu.h>
+#include <GL/glut.h>
+
+#include "capture_v4l.h" /* for capture by V4L */
+
+/*==========================================================
+ Definitions for OpenGL
+==========================================================*/
+#define DEFAULT_ZOOM_RATE 1
+#define INIT_WINDOW_POS_X 200
+#define INIT_WINDOW_POS_Y 200
+
+/*==========================================================
+ Function Prototypes
+==========================================================*/
+/*=== show_video_v4l_capture.c ===*/
+int ShowVideoInitCaptureDevice( char *device_name , int channel_no );
+void ShowVideoCaptureImage();
+void ShowVideoDisplayImage();
+void ShowVideoMouseCheck( int button , int status , int x , int y );
+void ShowVideoChangeOrderImageRow( unsigned char *image , int iwidth , int iheight );
+void ShowVideoSavePPMImage( unsigned char *image , int iheight , int iwidth , int frame_no , char *image_prefix );
+
+
+
+
--- /dev/null
+/*==========================================================================
+ $Id$
+ show_video_v4l_capture.c: Functions for capturing video using V4L.
+ Written by Naoyuki Ichimura, AIST, 2001.
+==========================================================================*/
+
+#include "show_video_v4l.h"
+#include "extract_skin_color.h"
+
+#define PREFIX_IMAGE_FILE "video_image"
+
+/*=== Local global variables ===*/
+static unsigned char disp_image[IMAGE_WIDTH_DS*IMAGE_HEIGHT_DS*RGB];/* pointer to image buffer */
+
+static int fd; /* file descriptor for frame buffer */
+static int exit_flag; /* flag to exit program */
+static int frame_no=1; /* frame number */
+
+static struct video_mbuf vm; /* structure for frame buffer */
+static struct video_mmap vmap; /* structure for memory space for frame buffer */
+
+/*=== global variable ===*/
+extern int extract_skin_color; /* global variable for enabling image processing */
+
+void ShowVideoCaptureImage()
+{
+
+ //static char image_prefix[1024]=PREFIX_IMAGE_FILE; /* Prefix of output image file */
+ static unsigned char image[IMAGE_WIDTH_DS*IMAGE_HEIGHT_DS*RGB]; /* Captured image */
+ static unsigned char skin_map[IMAGE_WIDTH_DS*IMAGE_HEIGHT_DS]; /* Skin color map */
+
+/*======= Wait capture for current frame ====================*/
+ CaptureV4LDoubleBufferingCaptureWait( fd , &vmap );
+
+/*======= Set data to image array ===========================*/
+ CaptureV4LSetImageDownSamplingForOpenGL( vmap , vm , DOWN_SAMPLING_RATE , image , disp_image );
+
+/*======= Begin capture for next frame ======================*/
+ if( CaptureV4LDoubleBufferingCaptureNextFrame( fd , &vmap ) == -1 ) {
+ fprintf( stderr , "COuld not capture next frame.\n" );
+ exit(-1);
+ }
+
+/*======= Display image =====================================*/
+ ShowVideoDisplayImage();
+
+/*======= Extract skin color by simple thresholding =========*/
+ if( extract_skin_color ) {
+ ExtractSkinColorSimpleThresholding( image , IMAGE_HEIGHT_DS , IMAGE_WIDTH_DS , skin_map );
+ ShowSkinRegion( skin_map , IMAGE_HEIGHT_DS , IMAGE_WIDTH_DS );
+ }
+
+#if 0
+/*======= Save image ========================================*/
+ ShowVideoSavePPMImage( image , IMAGE_HEIGHT_DS , IMAGE_WIDTH_DS , frame_no , image_prefix );
+#endif
+
+/*======= Swap Buffer: show graphics ========================*/
+ glutSwapBuffers();
+
+/*======= Increment frame number ============================*/
+ frame_no++;
+
+/*======= Check exit flag ===================================*/
+ if( exit_flag ) {
+ exit(0);
+ }
+
+}
+
+int ShowVideoInitCaptureDevice( char *device_name , int channel_no )
+{
+
+ struct video_capability vcap; /* structure for video capability */
+ struct video_channel vch[MAX_NO_CHANNEL]; /* structure for video channel */
+ struct video_picture vp;
+
+/*======= Open video device ================================*/
+ if( ( fd = CaptureV4LOpen( device_name ) ) == -1 ) {
+ fprintf( stderr, "Could not open device %s.\n" , device_name );
+ exit(-1);
+ }
+
+/*======= Get information of device =========================*/
+ /*=== Get device capabilities ===*/
+ if( CaptureV4LGetDeviceCapability( fd , &vcap ) == -1 ) {
+ fprintf( stderr , "Could not get capabilities of video device.\n" );
+ exit(-1);
+ }
+
+ /*=== Get channel information ===*/
+ if( CaptureV4LGetChannelInfo( fd , vch , vcap.channels ) == -1 ) {
+ fprintf( stderr , "Could not get channel information of video device.\n" );
+ exit(-1);
+ }
+
+ /*=== Get memory map information ===*/
+ if( CaptureV4LGetMemoryMapInfo( fd , &vm ) == -1 ) {
+ fprintf( stderr , "Could not get memory map information.\n" );
+ exit(-1);
+ }
+
+/*======= Show picture information =========================*/
+ CaptureV4LGetPictureInfo( fd , &vp );
+ CaptureV4LDisplayPictureInfo( vp );
+
+/*======= Select channel ===================================*/
+ if( CaptureV4LSelectChannel( fd , vch , channel_no ) == -1 ) {
+ fprintf( stderr , "Could not select channel.\n" );
+ exit(-1);
+ }
+
+/*======= Mapping frame buffer ==============================*/
+ if( CaptureV4LMemoryMapping( fd , vm ) == -1 ) {
+ fprintf( stdout , "Could not map frame buffer.\n" );
+ exit(-1);
+ }
+
+/*======= Set image size and formate ========================*/
+ vmap.width = CAPTURE_IMAGE_WIDTH;
+ vmap.height = CAPTURE_IMAGE_HEIGHT;
+ vmap.format = VIDEO_PALETTE_RGB24;
+
+/*======= Begin Capture =====================================*/
+ CaptureV4LDoubleBufferingInitCapture( fd , &vmap );
+
+ return 0;
+
+}
+
+void ShowVideoDisplayImage()
+{
+
+ glRasterPos2i( 0 , 0 );
+ glDrawPixels( IMAGE_WIDTH_DS , IMAGE_HEIGHT_DS , GL_BGR , GL_UNSIGNED_BYTE , disp_image );
+ glFlush();
+
+}
+
+void ShowVideoMouseCheck( int button , int status , int x , int y )
+{
+
+ if( button == GLUT_LEFT_BUTTON && status == GLUT_DOWN ) {
+ exit_flag = 1;
+ }
+
+}
+
+void ShowVideoSavePPMImage( unsigned char *image , int iheight , int iwidth , int frame_no , char *image_prefix )
+{
+
+ char file_name[1024];
+
+ FILE *fp;
+
+ sprintf( file_name , "%s_%d.ppm" , image_prefix , frame_no );
+ if( ( fp = fopen( file_name , "w" ) ) == NULL ) {
+ fprintf( stderr , "Could not open image file: %s\n" , file_name );
+ exit(1);
+ }
+ fprintf( fp , "P6 %d %d 255\n" , iwidth , iheight );
+ fwrite( image , iheight*iwidth*RGB , 1 , fp );
+ fclose(fp);
+
+}
+
+
+
+
+
+
--- /dev/null
+/*==========================================================================
+ $Id$
+ show_video_v4l_main.c: Main routine for capturing video using GLUT and V4L.
+ Written by Naoyuki Ichimura, AIST, 2001.
+==========================================================================*/
+
+#include "show_video_v4l.h"
+
+int extract_skin_color; /* global variable for enabling image processing */
+
+#include "camera.h"
+//int main( int argc , char *argv[] )
+void* video_thread(void* args)
+{
+ video_args_t *video_args = (video_args_t*) args;
+ int argc = video_args->argc;
+ char** argv;
+
+ argv = video_args->argv;
+ static char window_title[1024]="Video Capture";
+ int i,j;
+ int video_input;
+
+ double zoom_rate; /* for zooming */
+
+/*======= Set option =========================================*/
+ zoom_rate = DEFAULT_ZOOM_RATE;
+ video_input = S_VIDEO;
+ extract_skin_color = 0;
+ for( i = j = 1 ; i < argc ; i++ ) {
+ if( argv[i][0] == '-' || argv[i][0] == '/' ) {
+ switch( argv[i][1] ) {
+ case 'z':
+ zoom_rate = atof(&argv[i][2]);
+ break;
+
+ case 'v':
+ video_input = atoi(&argv[i][2]);
+ break;
+
+ case 's':
+ extract_skin_color = 1;
+ break;
+
+ default:
+ break;
+
+ }
+ } else {
+ argv[j++] = argv[i];
+ }
+ }
+ argc = j;
+
+/*======= Initialize GLUT ====================================*/
+ glutInit( &argc , argv );
+ glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE ); /* enable double buffering of video board */
+
+/*======= Initialize window ==================================*/
+ glutInitWindowPosition( INIT_WINDOW_POS_X , INIT_WINDOW_POS_Y ); /* initial window position */
+ glutInitWindowSize( (int)(zoom_rate*IMAGE_WIDTH_DS) , (int)(zoom_rate*IMAGE_HEIGHT_DS) ); /* set window size */
+ glutCreateWindow( window_title ); /* creat window with name */
+
+/*======= Initialize projection ==============================*/
+ glOrtho( 0.0 , IMAGE_WIDTH_DS-1.0 , 0.0 , IMAGE_HEIGHT_DS , -1.0 , 1.0 );
+ glPixelZoom( zoom_rate , zoom_rate );
+
+/*======= Initilize capture device ============================*/
+ ShowVideoInitCaptureDevice( DEFAULT_DEVICE_NAME , video_input );
+
+/*======= Initilize buffer ====================================*/
+ glClearColor( 0.0 , 0.0 , 0.0 , 0.0 );
+ glClear( GL_COLOR_BUFFER_BIT );
+ glutSwapBuffers();
+ glFlush();
+
+/*======= Register callback functions =========================*/
+ glutDisplayFunc( ShowVideoDisplayImage );
+ glutMouseFunc( ShowVideoMouseCheck );
+ glutIdleFunc( ShowVideoCaptureImage ); /* global idle callback */
+
+/*======= Begin event loop ====================================*/
+ glutMainLoop();
+
+ exit(0);
+
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+ifneq ($(filter y true 1,$(FRSH_DISTRIBUTED_MODULE_SUPPORTED)),)
+LDFLAGS+= -L/usr/X11R6/lib
+
+ifneq ($(AQUOSA_ROOT),)
+LDFLAGS+=-L$(AQUOSA_ROOT)/lib -lqreslib -lqsuplib
+endif
+
+C_INCLUDE_PATH = -I/usr/X11R6/include
+GLUT_LIBS = glut GL GLU
+FRSH_LIBS = frsh
+lib_LOADLIBES+= $(GLUT_LIBS) m pthread rt $(FRSH_LIBS)
+
+bin_PROGRAMS = camserver camclient
+camserver_SOURCES = camserver.c show_video_v4l_main.c show_video_v4l_capture.c\
+ capture_v4l.c extract_skin_color.c
+camclient_SOURCES = camclient.c show_video_v4l_main.c show_video_v4l_capture.c\
+ capture_v4l.c extract_skin_color.c
+endif
--- /dev/null
+#include <frsh.h>
+#include <error.h>
+
+#include "camera.h"
+#include "show_video_v4l.h"
+
+int cpu_negotiated = 0;
+int exit_flag = 1;
+
+struct camclient_resources {
+ frsh_vres_id_t cpuvres;
+ frsh_receive_endpoint_t repoint;
+} camres;
+
+inline int cpuconts_negotiated(void)
+{
+ return (cpu_negotiated);
+}
+
+int negotiate_cpucont(void)
+{
+ frsh_vres_id_t vres;
+ frsh_contract_t contract;
+ frsh_rel_time_t budget, period;
+ int ret;
+
+ /* Contract negotiation for CPU */
+ budget = fosa_msec_to_rel_time(50);
+ period = fosa_msec_to_rel_time(100);
+ ret = frsh_contract_set_basic_params(&contract,
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+ ret = frsh_contract_set_resource_and_label(&contract, FRSH_RT_PROCESSOR,
+ 0,"aqcpu_cont1");
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ ret = frsh_contract_negotiate(&contract, &vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+ camres.cpuvres = vres;
+
+ printf("Cpu vres negotiated\n");
+ /*pthread_attr_init(&attr);
+ ret = frsh_thread_create_and_bind(vres, &thread, &attr,
+ video_thread, (void*) &video_args);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_thread_create_and_bind");
+
+ pthread_join(thread.pthread_id, (void**) NULL);
+ printf("Test PASSED!\n");*/
+ cpu_negotiated = 1;
+
+ return 0;
+}
+
+int negotiate_netconts(void)
+{
+ frsh_receive_endpoint_t repoint;
+ frsh_receive_endpoint_protocol_info_t recv_pinfo;
+ frsh_endpoint_queueing_info_t qinfo;
+
+ recv_pinfo.body = NULL;
+ /* local_addr should be handled when creating socket */
+ if (frsh_receive_endpoint_create(PROTO, PORT, qinfo, recv_pinfo,
+ &repoint) != 0){
+ return -1;
+ }
+
+ camres.repoint = repoint;
+ printf("Receive endpoint created\n");
+ return 0;
+}
+
+int negotiate_contracts(void)
+{
+ frsh_contract_t contract;
+ int ret;
+
+ if (frsh_init()) {
+ error(1, 0, "FRSH initialization failed\n");
+ }
+
+ ret = frsh_contract_init(&contract);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ //negotiate_cpuconts();
+ negotiate_netconts();
+
+ return 0;
+}
+
+#if 0
+void init_gui(void)
+{
+ int video_input;
+ double zoom_rate; /* for zooming */
+
+ zoom_rate = DEFAULT_ZOOM_RATE;
+ video_input = S_VIDEO;
+ //extract_skin_color = 0;
+
+ /*======= Initialize GLUT ====================================*/
+ /* enable double buffering of video board */
+ glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
+
+ /*======= Initialize window ==================================*/
+ /* initial window position */
+ glutInitWindowPosition( INIT_WINDOW_POS_X , INIT_WINDOW_POS_Y );
+ /* set window size */
+ glutInitWindowSize( (int)(zoom_rate*IMAGE_WIDTH_DS) ,
+ (int)(zoom_rate*IMAGE_HEIGHT_DS) );
+ /* creat window with name */
+ glutCreateWindow( "video capture" );
+
+ /*======= Initialize projection ==============================*/
+ glOrtho( 0.0 , IMAGE_WIDTH_DS-1.0 , 0.0 , IMAGE_HEIGHT_DS , -1.0 , 1.0 );
+ glPixelZoom( zoom_rate , zoom_rate );
+
+ /*======= Initialize buffer ==================================*/
+ glClearColor( 0.0 , 0.0 , 0.0 , 0.0 );
+ glClear( GL_COLOR_BUFFER_BIT );
+ glutSwapBuffers();
+ glFlush();
+ /*======= Register callback functions =========================*/
+ glutDisplayFunc( ShowVideoDisplayImage );
+ glutMouseFunc( ShowVideoMouseCheck );
+ glutIdleFunc( ShowVideoCaptureImage ); /* global idle callback */
+
+ /*======= Begin event loop ====================================*/
+ glutMainLoop();
+
+ ShowVideoDisplayImage();
+}
+#endif
+
+void* receiver_thread(void* arg)
+{
+ size_t len;
+ frsh_network_address_t from;
+ int count = 0;
+
+ while (1) {
+ if ((frsh_receive_sync(camres.repoint, disp_image , sizeof(disp_image),
+ &len, &from))){
+ perror("Error while receiving data");
+ return NULL;
+ }
+ printf("Received frame %d\n",count++);
+ ShowVideoDisplayImage();
+ }
+
+ //ShowVideoDisplayImage();
+ //clock_gettime(CLOCK_MONOTONIC, &recvtime);
+ //printf("Received %d: sec = %ld nsec = %ld \n", count, recvtime.tv_sec,
+ // recvtime.tv_nsec);
+ printf("Exiting receiver\n");
+// }
+ exit_flag = 1;
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ video_args_t video_args;
+ int ret;
+
+ video_args.argc = argc;
+ video_args.argv = argv;
+
+ //glutInit( &argc , argv );
+ negotiate_contracts();
+ //init_gui();
+
+ if (cpuconts_negotiated()) {
+ frsh_thread_attr_t attr;
+ //frsh_thread_id_t thread;
+
+ pthread_attr_init(&attr);
+ /*ret = frsh_thread_create_and_bind(camres.cpuvres, &thread,
+ &attr, camclient_run, (void*) NULL);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_thread_create_and_bind");
+ pthread_join(thread.pthread_id, (void**) NULL); */
+ } else {
+ pthread_attr_t attr;
+ pthread_t video_th;
+ pthread_t recv_th;
+
+ pthread_attr_init(&attr);
+
+
+ ret = pthread_create(&video_th, &attr, video_thread,
+ (void*) &video_args);
+ if (ret) PERROR_AND_EXIT(ret, "Failed to create video thread");
+ ret = pthread_create(&recv_th, &attr, receiver_thread,
+ (void*) NULL);
+ if (ret) PERROR_AND_EXIT(ret, "Failed to create receiver thread");
+
+ pthread_join(recv_th, (void**) NULL);
+ }
+
+ return 0;
+}
--- /dev/null
+#ifndef CAMERA_H
+#define CAMERA_H
+
+#define PORT 65111
+#define PROTO FRSH_NETPF_FWP
+
+typedef struct video_args{
+ int argc;
+ char** argv;
+} video_args_t;
+
+void* video_thread(void* args);
+
+#endif /* CAMERA_H */
--- /dev/null
+#include <frsh.h>
+#include <error.h>
+
+#include "camera.h"
+#include "show_video_v4l.h"
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+//#define V_CHANNEL S_VIDEO
+#define V_CHANNEL 0
+
+#define FRAMEDELAY (1000/25) /* ms */
+
+#define MSGPERIOD FRAMEDELAY /* ms */
+#define MSGSIZE 65500
+//#define MSGSIZE 100
+#define MSGBUDGET 1
+#define MSGBYTES MSGSIZE*MSGBUDGET
+
+
+int cpu_negotiated = 0;
+int exit_flag = 1;
+
+struct camserver_resources {
+ frsh_vres_id_t cpuvres;
+ frsh_vres_id_t netvres;
+ frsh_send_endpoint_t sepoint;
+} camres;
+
+inline int cpuconts_negotiated(void)
+{
+ return (cpu_negotiated);
+}
+
+int negotiate_cpucont(void)
+{
+ frsh_vres_id_t vres;
+ frsh_contract_t contract;
+ frsh_rel_time_t budget, period;
+ int ret;
+
+ /* Contract negotiation for CPU */
+ budget = fosa_msec_to_rel_time(50);
+ period = fosa_msec_to_rel_time(100);
+ ret = frsh_contract_set_basic_params(&contract,
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+ ret = frsh_contract_set_resource_and_label(&contract, FRSH_RT_PROCESSOR,
+ 0,"aqcpu_cont1");
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ ret = frsh_contract_negotiate(&contract, &vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+ camres.cpuvres = vres;
+
+ printf("Cpu vres negotiated\n");
+ /*pthread_attr_init(&attr);
+ ret = frsh_thread_create_and_bind(vres, &thread, &attr,
+ video_thread, (void*) &video_args);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_thread_create_and_bind");
+
+ pthread_join(thread.pthread_id, (void**) NULL);
+ printf("Test PASSED!\n");*/
+ cpu_negotiated = 1;
+
+ return 0;
+}
+
+int negotiate_netconts(void)
+{
+ frsh_send_endpoint_t sepoint;
+ frsh_vres_id_t vres;
+ frsh_send_endpoint_protocol_info_t send_pinfo;
+ frsh_contract_t contract;
+ frsh_rel_time_t budget, period;
+ int ret;
+ /*struct timespec sendtime;*/
+
+ send_pinfo.body = NULL;
+ if (frsh_send_endpoint_create(PROTO, inet_addr("127.0.0.1"), PORT,
+ send_pinfo, &sepoint)< 0) {
+ return -1;
+ }
+
+ /* Contract negotiation */
+ ret = frsh_contract_init(&contract);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ frsh_network_bytes_to_budget(FRSH_NETPF_FWP, MSGBYTES, &budget);
+ period = fosa_msec_to_rel_time(MSGPERIOD);
+ ret = frsh_contract_set_basic_params(&contract,
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+ ret = frsh_contract_set_resource_and_label(&contract,FRSH_RT_NETWORK,
+ FRSH_NETPF_FWP,
+ "fwp_cont1");
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ ret = frsh_contract_negotiate(&contract, &vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+
+ printf("Send endpoint created\n");
+ frsh_send_endpoint_bind(vres, sepoint);
+ printf("Send endpoint bounded\n");
+
+ camres.netvres = vres;
+ camres.sepoint = sepoint;
+
+ return 0;
+}
+
+int negotiate_contracts(void)
+{
+ frsh_contract_t contract;
+ int ret;
+
+ if (frsh_init()) {
+ error(1, 0, "FRSH initialization failed\n");
+ }
+
+ ret = frsh_contract_init(&contract);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ //negotiate_cpuconts();
+ negotiate_netconts();
+
+ return 0;
+}
+
+void init_grabber(void)
+{
+ int video_input;
+
+ //zoom_rate = DEFAULT_ZOOM_RATE;
+ video_input = V_CHANNEL;
+
+ /*======= Initilize capture device ============================*/
+ ShowVideoInitCaptureDevice( DEFAULT_DEVICE_NAME , video_input );
+}
+
+void* sender_thread(void* arg)
+{
+ int ret;
+ //char msg[MSGSIZE];
+ int count = 0;
+ struct timespec framedelay = {
+ .tv_sec = 0,
+ .tv_nsec = FRAMEDELAY*1000000
+ };
+
+ while (1) {
+ /* grab image */
+ ShowVideoCaptureImage();
+ //ShowVideoDisplayImage();
+ /* send to client */
+ printf("Sent frame %d\n", count++);
+ //if ((ret = frsh_send_async(sepoint, disp_image , MSG_SIZE))){
+ if ((ret = frsh_send_async(camres.sepoint, disp_image , MSGSIZE))){
+ /*printf("Error code: %d\n", ret);
+ perror("Error while sending data");
+ return NULL;*/
+ }
+ nanosleep(&framedelay, NULL);
+ }
+
+ /* temporali delay */
+ sleep(10);
+ exit_flag = 1;
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int ret;
+
+ video_args_t video_args;
+
+ video_args.argc = argc;
+ video_args.argv = argv;
+
+ negotiate_contracts();
+ init_grabber();
+
+ if (cpuconts_negotiated()) {
+ /*frsh_thread_attr_t attr;
+ frsh_thread_id_t thread;
+ int ret;
+
+ pthread_attr_init(&attr);
+ ret = frsh_thread_create_and_bind(camres.cpuvres, &thread,
+ &attr, camclient_run, (void*) NULL);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_thread_create_and_bind");
+ pthread_join(thread.pthread_id, (void**) NULL); */
+ } else {
+ pthread_attr_t attr;
+ //pthread_t video_th;
+ pthread_t sender_th;
+
+ pthread_attr_init(&attr);
+
+ /* for test purposes */
+ /*ret = pthread_create(&video_th, &attr, video_thread,
+ (void*) &video_args);
+ if (ret) PERROR_AND_EXIT(ret, "Failed to create video thread");*/
+ ret = pthread_create(&sender_th, &attr, sender_thread,
+ (void*) NULL);
+ if (ret) PERROR_AND_EXIT(ret, "Failed to create sender thread");
+
+ pthread_join(sender_th, (void**) NULL);
+ }
+
+ return 0;
+}
--- /dev/null
+/*==========================================================================
+ $Id$
+ capture_v4l.c: Functions for capturing image using Video4Linux.
+ Written by Naoyuki Ichimura, AIST, 2001.
+==========================================================================*/
+
+#include "capture_v4l.h"
+
+/*=== Global variable for this module ===*/
+static unsigned char *frame_buf;
+
+/*============================================================================
+ Functions for Device Open and Check
+============================================================================*/
+int CaptureV4LOpen( char *device_name )
+{
+
+ int fd;
+
+/*======= Open Video4Linux device ==========================*/
+ if( ( fd = open( device_name , O_RDWR ) ) == -1 ) {
+ return -1;
+ }
+
+ return fd;
+
+}
+
+int CaptureV4LGetDeviceCapability( int fd , struct video_capability *vcap )
+{
+
+/*======= Get device capabilities ==========================*/
+ if( ioctl( fd , VIDIOCGCAP , vcap ) == -1 ) {
+ return -1;
+ }
+
+ return 0;
+
+}
+
+void CaptureV4LDisplayDeviceCapability( struct video_capability vcap )
+{
+
+ fprintf( stdout , "*** Device information ***\n" );
+
+/*======= Display deivce name =============================*/
+ fprintf( stdout , "Device name:%s.\n" , vcap.name );
+
+/*======= Display deivce types ============================*/
+ fprintf( stdout , "Type of device:\n" );
+ if( vcap.type & VID_TYPE_CAPTURE ) {
+ fprintf( stdout , "Capture is OK.\n" );
+ } else {
+ fprintf( stderr , "This device may NOT be used for capture. Are you sure about it ?\n" );
+ }
+ if( vcap.type & VID_TYPE_TUNER ) {
+ fprintf( stdout , "Tuner exists.\n" );
+ }
+ if( vcap.type & VID_TYPE_TELETEXT ) {
+ fprintf( stdout , "Teletext can be used.\n" );
+ }
+ if( vcap.type & VID_TYPE_OVERLAY ) {
+ fprintf( stdout , "Overlay is OK.\n" );
+ }
+ if( vcap.type & VID_TYPE_CHROMAKEY ) {
+ fprintf( stdout , "Overlay by chromakey is OK.\n" );
+ }
+ if( vcap.type & VID_TYPE_CLIPPING ) {
+ fprintf( stdout , "Clipping overlay is OK.\n" );
+ }
+ if( vcap.type & VID_TYPE_FRAMERAM ) {
+ fprintf( stdout , "Overlay for frame buffer is OK.\n" );
+ }
+ if( vcap.type & VID_TYPE_SCALES ) {
+ fprintf( stdout , "Scaling by hardware can be used.\n" );
+ }
+ if( vcap.type & VID_TYPE_MONOCHROME ) {
+ fprintf( stdout , "Capture of monochrome image is OK.\n" );
+ }
+ if( vcap.type & VID_TYPE_SUBCAPTURE ) {
+ fprintf( stdout , "Capture of a part of image is OK.\n" );
+ }
+ fprintf( stdout , "\n" );
+
+/*======= Display number of video channels and audio ones ===*/
+ fprintf( stdout , "Number of channels: %d\n" , vcap.channels );
+ fprintf( stdout , "Number of audio devices: %d\n" , vcap.audios );
+
+ if( vcap.channels > MAX_NO_CHANNEL ) {
+ fprintf( stderr , "It seems that too many channels exist in this device: %d.\n" , vcap.channels );
+ }
+
+/*======= Display image size ================================*/
+ fprintf( stdout , "Maximum width of image: %d\n" , vcap.maxwidth );
+ fprintf( stdout , "Maximum height of image: %d\n", vcap.maxheight );
+ fprintf( stdout , "Minimum width of image: %d\n" , vcap.minwidth );
+ fprintf( stdout , "Minimum height of image: %d\n" , vcap.minheight );
+ fprintf( stdout , "\n" );
+
+}
+
+int CaptureV4LGetChannelInfo( int fd , struct video_channel vch[MAX_NO_CHANNEL] , int no_channel )
+{
+
+ int i;
+
+/*======= Get channel information ==========================*/
+ for( i = 0 ; i < no_channel ; i++ ) {
+ vch[i].channel = i; /* channel number */
+ if( ioctl( fd , VIDIOCGCHAN , &vch[i] ) == -1 ) {
+ return -1;
+ }
+ }
+
+ return 0;
+
+}
+
+void CaptureV4LDisplayChannelInfo( struct video_channel vch[MAX_NO_CHANNEL] , int no_channel )
+{
+
+ int i;
+
+ for( i = 0 ; i < no_channel ; i++ ) {
+ fprintf( stdout , "*** Channel number: %d ***\n" , vch[i].channel );
+ fprintf( stdout , "Channel name: %s\n" , vch[i].name );
+ if( vch[i].flags & VIDEO_VC_TUNER ) {
+ fprintf( stdout , "This channel has a tuner.\n" );
+ }
+ if( vch[i].flags & VIDEO_VC_AUDIO ) {
+ fprintf( stdout , "This channel has a audio.\n" );
+ }
+ if( vch[i].type & VIDEO_TYPE_TV ) {
+ fprintf( stdout , "Channel type is TV.\n" );
+ }
+ if( vch[i].type & VIDEO_TYPE_CAMERA ) {
+ fprintf( stdout , "Channel type is camera.\n" );
+ }
+ if( vch[i].norm & VIDEO_MODE_NTSC ) {
+ fprintf( stdout , "Video mode is NTSC.\n" );
+ }
+ if( vch[i].norm & VIDEO_MODE_PAL ) {
+ fprintf( stdout , "Video mode is PAL.\n" );
+ }
+ if( vch[i].norm & VIDEO_MODE_SECAM ) {
+ fprintf( stdout , "Video mode is SECAM.\n" );
+ }
+ }
+ fprintf( stdout , "\n" );
+
+}
+
+int CaptureV4LGetPictureInfo( int fd , struct video_picture *vp )
+{
+
+/*======= Get channel information ==========================*/
+ if( ioctl( fd , VIDIOCGPICT , vp ) == -1 ) {
+ return -1;
+ }
+
+ return 0;
+
+}
+
+void CaptureV4LDisplayPictureInfo( struct video_picture vp )
+{
+
+ fprintf( stdout , "*** Picture information ***\n" );
+ fprintf( stdout , "Brightness: %d\n" , vp.brightness );
+ fprintf( stdout , "Hue: %d\n" , vp.hue );
+ fprintf( stdout , "Color: %d\n" , vp.colour );
+ fprintf( stdout , "Contrast: %d\n" , vp.contrast );
+ fprintf( stdout , "Whiteness: %d\n" , vp.whiteness );
+ fprintf( stdout , "Depth: %d\n" , vp.depth );
+ switch( vp.palette ) {
+ case VIDEO_PALETTE_GREY:
+ fprintf( stdout , "Gray scale.\n" );
+ break;
+
+ case VIDEO_PALETTE_RGB565:
+ fprintf( stdout , "16bit RGB.\n" );
+ break;
+
+ case VIDEO_PALETTE_RGB24:
+ fprintf( stdout , "24bit RGB.\n" );
+ break;
+
+ case VIDEO_PALETTE_RGB32:
+ fprintf( stdout , "32bit RGB.\n" );
+ break;
+
+ case VIDEO_PALETTE_YUV422:
+ fprintf( stdout , "YUV422.\n" );
+ break;
+
+ default:
+ break;
+
+ }
+
+}
+
+int CaptureV4LGetMemoryMapInfo( int fd , struct video_mbuf *vm )
+{
+
+/*======= Get channel information ==========================*/
+ if( ioctl( fd , VIDIOCGMBUF , vm ) == -1 ) {
+ return -1;
+ }
+
+ return 0;
+
+}
+
+void CaptureV4LDisplayMemoryMapInfo( struct video_mbuf vm )
+{
+
+ int i;
+
+ fprintf( stdout , "Memory size: %d\n" , vm.size );
+ fprintf( stdout , "Number of frames: %d\n" , vm.frames );
+ for( i = 0 ; i < vm.frames ; i++ ) {
+ fprintf( stdout , "Offset (frame %d): %d\n" , i , vm.offsets[i] );
+ }
+
+}
+
+/*============================================================================
+ Functions for preparation of capture
+============================================================================*/
+int CaptureV4LSelectChannel( int fd , struct video_channel vch[MAX_NO_CHANNEL] , int channel_no )
+{
+
+ vch[channel_no].norm = VIDEO_MODE_NTSC;
+ if( ioctl( fd , VIDIOCSCHAN , &vch[channel_no] ) == -1 ) {
+ return -1;
+ }
+
+ return 0;
+
+}
+
+int CaptureV4LMemoryMapping( int fd , struct video_mbuf vm )
+{
+
+ if( ( frame_buf = (unsigned char *)mmap( 0 , (size_t)vm.size , PROT_READ | PROT_WRITE , MAP_SHARED , fd , 0 ) ) == MAP_FAILED ) {
+ return -1;
+ }
+
+ return 0;
+
+}
+
+/*============================================================================
+ Functions for capture
+============================================================================*/
+int CaptureV4LSimpleCapture( int fd , struct video_mmap *vmap )
+{
+
+/*======= Begin capture ====================================*/
+ if( ioctl( fd , VIDIOCMCAPTURE , vmap ) == -1 ) {
+ return -1;
+ }
+
+/*======= Wait capture =====================================*/
+ if( ioctl( fd , VIDIOCSYNC , &(vmap->frame) ) == -1 ) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int CaptureV4LDoubleBufferingInitCapture( int fd , struct video_mmap *vmap )
+{
+
+/*======= Capture image into frame buffers at beginning ====*/
+ vmap->frame = 0;
+ if( ioctl( fd , VIDIOCMCAPTURE , vmap ) == -1 ) {
+ return -1;
+ }
+ vmap->frame = 1;
+ if( ioctl( fd , VIDIOCMCAPTURE , vmap ) == -1 ) {
+ return -1;
+ }
+ /*=== Set initial frame number ===*/
+ vmap->frame = 0;
+ return 0;
+}
+
+int CaptureV4LDoubleBufferingCaptureWait( int fd , struct video_mmap *vmap )
+{
+
+/*======= Wait Capture ====================================*/
+ if( ioctl( fd , VIDIOCSYNC , &(vmap->frame) ) == -1 ) {
+ return -1;
+ }
+
+ return 0;
+
+}
+
+int CaptureV4LDoubleBufferingCaptureNextFrame( int fd , struct video_mmap *vmap )
+{
+
+/*======= Capture next frame into current buffer ==========*/
+ if( ioctl( fd , VIDIOCMCAPTURE , vmap ) == -1 ) {
+ return -1;
+ }
+
+/*======= Change buffer ===================================*/
+ if( vmap->frame == 0 ) {
+ vmap->frame = 1;
+ } else {
+ vmap->frame = 0;
+ }
+
+ return 0;
+
+}
+
+/*============================================================================
+ Functions for image array
+============================================================================*/
+unsigned char *CaptureV4LSetImage( struct video_mmap vmap , struct video_mbuf vm )
+{
+
+ unsigned char tmpc;
+ unsigned char *pixel_pos;
+
+ int i;
+
+/*======= Change order of data from BGR to RGB ===============*/
+ pixel_pos = frame_buf+vm.offsets[vmap.frame];
+ for( i = 0 ; i < vmap.height*vmap.width ; i++ ) {
+ tmpc = pixel_pos[2];
+ pixel_pos[2] = pixel_pos[0];
+ pixel_pos[0] = tmpc;
+ pixel_pos += RGB;
+ }
+
+ return frame_buf+vm.offsets[vmap.frame];
+
+}
+
+void CaptureV4LSetImageDownSamplingForOpenGL( struct video_mmap vmap , struct video_mbuf vm , int down_sampling_rate , unsigned char *image , unsigned char *disp_image )
+{
+
+ unsigned char *pixel_pos;
+
+ int i,j;
+ int dheight,dwidth;
+
+/*======= Change order of data from BGR(capture board order) to RGB for processing ===============*/
+ dheight = vmap.height/down_sampling_rate;
+ dwidth = vmap.width/down_sampling_rate;
+ pixel_pos = frame_buf+vm.offsets[vmap.frame];
+ for( i = 0 ; i < dheight ; i++ ) {
+ for( j = 0 ; j < dwidth; j++ ) {
+ /* image for processing: RGB order */
+ image[((dheight-1-i)*dwidth+j)*RGB] = pixel_pos[2];
+ image[((dheight-1-i)*dwidth+j)*RGB+1] = pixel_pos[1];
+ image[((dheight-1-i)*dwidth+j)*RGB+2] = pixel_pos[0];
+ /* image for display: BRG order */
+ disp_image[((dheight-1-i)*dwidth+j)*RGB] = pixel_pos[0];
+ disp_image[((dheight-1-i)*dwidth+j)*RGB+1] = pixel_pos[1];
+ disp_image[((dheight-1-i)*dwidth+j)*RGB+2] = pixel_pos[2];
+ pixel_pos += RGB*down_sampling_rate;
+ }
+ pixel_pos += vmap.width*RGB*(down_sampling_rate-1);
+ }
+
+}
--- /dev/null
+/*==========================================================================
+ $Id$
+ capture_v4l.h: Header file for capturing image using Video4Linux.
+ Written by Naoyuki Ichimura, AIST, 2001.
+==========================================================================*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include <sys/types.h> /* for open() */
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <sys/ioctl.h> /* for ioctl() */
+
+#include <unistd.h> /* for mmap() */
+#include <sys/mman.h>
+
+#include <linux/videodev.h> /* for V4L */
+
+/*=====================================================
+ Definitions for Video4Linux
+=====================================================*/
+#define DEFAULT_DEVICE_NAME "/dev/video0" /* device file name */
+#define MAX_NO_CHANNEL 10 /* maximum number of channel of frame grabber */
+#define CAPTURE_IMAGE_WIDTH 352 /* image width */
+#define CAPTURE_IMAGE_HEIGHT 288 /* image height */
+
+#define RGB 3 /* number of bit plane */
+
+#define COMPOSITE1 0 /* for IO-DATA GV-VCP2M/PCI */
+#define COMPOSITE2 1
+#define S_VIDEO 2
+
+#define DOWN_SAMPLING_RATE 4 /* to remove even number field */
+
+#define IMAGE_WIDTH_DS CAPTURE_IMAGE_WIDTH/DOWN_SAMPLING_RATE /* image size after down sampling */
+#define IMAGE_HEIGHT_DS CAPTURE_IMAGE_HEIGHT/DOWN_SAMPLING_RATE
+
+/*=====================================================
+ Function Prototypes
+=====================================================*/
+int CaptureV4LOpen( char *device_name );
+int CaptureV4LGetDeviceCapability( int fd , struct video_capability *vcap );
+void CaptureV4LDisplayDeviceCapability( struct video_capability vcap );
+int CaptureV4LGetChannelInfo( int fd , struct video_channel vch[MAX_NO_CHANNEL] , int no_channel );
+void CaptureV4LDisplayChannelInfo( struct video_channel vch[MAX_NO_CHANNEL] , int no_channel );
+int CaptureV4LGetPictureInfo( int fd , struct video_picture *vp );
+void CaptureV4LDisplayPictureInfo( struct video_picture vp );
+int CaptureV4LGetMemoryMapInfo( int fd , struct video_mbuf *vm );
+void CaptureV4LDisplayMemoryMapInfo( struct video_mbuf vm );
+
+int CaptureV4LSelectChannel( int fd , struct video_channel vch[MAX_NO_CHANNEL] , int channel_no );
+int CaptureV4LMemoryMapping( int fd , struct video_mbuf vm );
+
+int CaptureV4LSimpleCapture( int fd , struct video_mmap *vmap );
+int CaptureV4LDoubleBufferingInitCapture( int fd , struct video_mmap *vmap );
+int CaptureV4LDoubleBufferingCaptureWait( int fd , struct video_mmap *vmap ) ;
+int CaptureV4LDoubleBufferingCaptureNextFrame( int fd , struct video_mmap *vmap );
+
+unsigned char *CaptureV4LSetImage( struct video_mmap vmap , struct video_mbuf vm );
+void CaptureV4LSetImageDownSamplingForOpenGL( struct video_mmap vmap , struct video_mbuf vm , int down_sampling_rate , unsigned char *image , unsigned char *disp_image );
+
+
--- /dev/null
+/*==========================================================================
+ $Id$
+ extract_skin_color.c: Functions for extracting skin color from image
+ using simple thresholding.
+ Written by Naoyuki Ichimura, AIST, 2001.
+==========================================================================*/
+
+#include "show_video_v4l.h"
+#include "extract_skin_color.h"
+
+void ExtractSkinColorSimpleThresholding( unsigned char *image , int iheight , int iwidth , unsigned char *skin_map )
+{
+
+ static unsigned char tmp_skin_map[IMAGE_WIDTH_DS*IMAGE_HEIGHT_DS]; /* Skin color map */
+
+ int i,j,k,l;
+ int hblock_size;
+ int no_skin_pixel;
+
+ double r,g,b; /* color components */
+ double sum_cc; /* sum of color components */
+
+/*======== Extract candidate pixels =======================================*/
+ for( i = 0 ; i < iheight ; i++ ) {
+ for( j = 0 ; j < iwidth ; j++ ) {
+
+ /*=== Calculate color component for skin color ===*/
+ sum_cc = (double)(image[(i*iwidth+j)*RGB]+image[(i*iwidth+j)*RGB+1]+image[(i*iwidth+j)*RGB+2]);
+ r = (double)image[(i*iwidth+j)*RGB]/sum_cc; /* r=R/(R+G+B) */
+ g = (double)image[(i*iwidth+j)*RGB+1]/sum_cc; /* g=G/(R+G+B) */
+ b = (double)image[(i*iwidth+j)*RGB+2]/sum_cc; /* b=B/(R+G+B) */
+ if( r > MIN_THRESH_r && r < MAX_THRESH_r ) {
+ tmp_skin_map[i*iwidth+j] = 1;
+ } else {
+ tmp_skin_map[i*iwidth+j] = 0;
+ }
+
+ }
+ }
+
+/*======== Post processing: dilation by majority in block (3x3) ========*/
+ hblock_size = BLOCK_SIZE/2;
+ for( i = hblock_size ; i < iheight-hblock_size ; i += BLOCK_SIZE ) {
+ for( j = hblock_size ; j < iwidth-hblock_size ; j += BLOCK_SIZE ) {
+ no_skin_pixel = 0;
+ for( k = -hblock_size ; k <= hblock_size ; k++ ) {
+ for( l = -hblock_size ; l <= hblock_size ; l++ ) {
+ if( tmp_skin_map[(i+k)*iwidth+(j+l)] ) {
+ no_skin_pixel++;
+ }
+ }
+ }
+ if( no_skin_pixel > BLOCK_SIZE*BLOCK_SIZE/2 ) { /* use majority rule */
+ for( k = -hblock_size ; k <= hblock_size ; k++ ) {
+ for( l = -hblock_size ; l <= hblock_size ; l++ ) {
+ skin_map[(i+k)*iwidth+(j+l)] = 1;
+ }
+ }
+ } else {
+ for( k = -hblock_size ; k <= hblock_size ; k++ ) {
+ for( l = -hblock_size ; l <= hblock_size ; l++ ) {
+ skin_map[(i+k)*iwidth+(j+l)] = 0;
+ }
+ }
+ }
+ }
+ }
+
+}
+
+void ShowSkinRegion( unsigned char *skin_map , int iheight , int iwidth )
+{
+
+ int i,j;
+
+ glColor3f( 0.0 , 1.0 , 0.0 ); /* green */
+ glPointSize( 2.0 ); /* point size */
+ for( i = 0 ; i < iheight ; i++ ) {
+ for( j = 0 ; j < iwidth ; j++ ) {
+ if( skin_map[i*iwidth+j] ) {
+ DisplayPoint( (double)j , (double)i );
+ }
+ }
+ }
+
+}
--- /dev/null
+/*==========================================================================
+ $Id$
+ extract_skin_color.h: Header file for extracting skin color from image
+ using simple thresholding.
+ Written by Naoyuki Ichimura, AIST, 2001.
+==========================================================================*/
+
+/*=== Thresholds for skin color ====*/
+#define MIN_THRESH_r 0.38
+#define MAX_THRESH_r 0.48
+
+/*=== for skin map =================*/
+#define BLOCK_SIZE 3 /* must be odd nubmer */
+#define THRESH_SKIN_PIXEL 50*50
+
+/*=== Definitions for display point by OpenGL ===*/
+#define DisplayPoint( x , y ) glBegin(GL_POINTS); glVertex2f( (x) , (y) ); glEnd();
+
+/*=== Prototypes ===*/
+void ExtractSkinColorSimpleThresholding( unsigned char *image , int iheight , int iwidth , unsigned char *skin_map );
+void ShowSkinRegion( unsigned char *skin_map , int iheight , int iwidth );
--- /dev/null
+/*
+ * example.c
+ *
+ * This file illustrates how to use the IJG code as a subroutine library
+ * to read or write JPEG image files. You should look at this code in
+ * conjunction with the documentation file libjpeg.doc.
+ *
+ * This code will not do anything useful as-is, but it may be helpful as a
+ * skeleton for constructing routines that call the JPEG library.
+ *
+ * We present these routines in the same coding style used in the JPEG code
+ * (ANSI function definitions, etc); but you are of course free to code your
+ * routines in a different style if you prefer.
+ */
+
+#include <stdio.h>
+
+/*
+ * Include file for users of JPEG library.
+ * You will need to have included system headers that define at least
+ * the typedefs FILE and size_t before you can include jpeglib.h.
+ * (stdio.h is sufficient on ANSI-conforming systems.)
+ * You may also wish to include "jerror.h".
+ */
+
+#include "jpeglib.h"
+
+/*
+ * <setjmp.h> is used for the optional error recovery mechanism shown in
+ * the second part of the example.
+ */
+
+#include <setjmp.h>
+
+
+
+/******************** JPEG COMPRESSION SAMPLE INTERFACE *******************/
+
+/* This half of the example shows how to feed data into the JPEG compressor.
+ * We present a minimal version that does not worry about refinements such
+ * as error recovery (the JPEG code will just exit() if it gets an error).
+ */
+
+
+/*
+ * IMAGE DATA FORMATS:
+ *
+ * The standard input image format is a rectangular array of pixels, with
+ * each pixel having the same number of "component" values (color channels).
+ * Each pixel row is an array of JSAMPLEs (which typically are unsigned chars).
+ * If you are working with color data, then the color values for each pixel
+ * must be adjacent in the row; for example, R,G,B,R,G,B,R,G,B,... for 24-bit
+ * RGB color.
+ *
+ * For this example, we'll assume that this data structure matches the way
+ * our application has stored the image in memory, so we can just pass a
+ * pointer to our image buffer. In particular, let's say that the image is
+ * RGB color and is described by:
+ */
+
+//extern JSAMPLE * image_buffer; /* Points to large array of R,G,B-order data */
+extern int image_height; /* Number of rows in image */
+extern int image_width; /* Number of columns in image */
+
+
+/*
+ * Sample routine for JPEG compression. We assume that the target file name
+ * and a compression quality factor are passed in.
+ */
+
+void rgb2jpeg(JSAMPLE *jpeg_buffer, JSAMPLE *rgb_buffer,int image_height,
+ int image_width, int quality)
+{
+ /* This struct contains the JPEG compression parameters and pointers to
+ * working space (which is allocated as needed by the JPEG library).
+ * It is possible to have several such structures, representing multiple
+ * compression/decompression processes, in existence at once. We refer
+ * to any one struct (and its associated working data) as a "JPEG object".
+ */
+ struct jpeg_compress_struct cinfo;
+ /* This struct represents a JPEG error handler. It is declared separately
+ * because applications often want to supply a specialized error handler
+ * (see the second half of this file for an example). But here we just
+ * take the easy way out and use the standard error handler, which will
+ * print a message on stderr and call exit() if compression fails.
+ * Note that this struct must live as long as the main JPEG parameter
+ * struct, to avoid dangling-pointer problems.
+ */
+ struct jpeg_error_mgr jerr;
+ /* More stuff */
+ JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
+ int row_stride; /* physical row width in image buffer */
+
+ /* Step 1: allocate and initialize JPEG compression object */
+
+ /* We have to set up the error handler first, in case the initialization
+ * step fails. (Unlikely, but it could happen if you are out of memory.)
+ * This routine fills in the contents of struct jerr, and returns jerr's
+ * address which we place into the link field in cinfo.
+ */
+ cinfo.err = jpeg_std_error(&jerr);
+ /* Now we can initialize the JPEG compression object. */
+ jpeg_create_compress(&cinfo);
+
+ /* Step 2: specify data destination (eg, a file) */
+ /* Note: steps 2 and 3 can be done in either order. */
+
+ /* Here we use the library-supplied code to send compressed data to a
+ * stdio stream. You can also write your own code to do something else.
+ * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
+ * requires it in order to write binary files.
+ */
+ /*if ((outfile = fopen(filename, "wb")) == NULL) {
+ fprintf(stderr, "can't open %s\n", filename);
+ exit(1);
+ }
+ jpeg_stdio_dest(&cinfo, outfile);*/
+ SDL_RWops *rw;
+
+ rw = SDL_RWFromMem(rgb_image, sizeof(rgb_image));
+
+ /* Step 3: set parameters for compression */
+
+ /* First we supply a description of the input image.
+ * Four fields of the cinfo struct must be filled in:
+ */
+ cinfo.image_width = image_width; /* image width and height, in pixels */
+ cinfo.image_height = image_height;
+ cinfo.input_components = 3; /* # of color components per pixel */
+ cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
+ /* Now use the library's routine to set default compression parameters.
+ * (You must set at least cinfo.in_color_space before calling this,
+ * since the defaults depend on the source color space.)
+ */
+ jpeg_set_defaults(&cinfo);
+ /* Now you can set any non-default parameters you wish to.
+ * Here we just illustrate the use of quality (quantization table) scaling:
+ */
+ jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
+
+ /* Step 4: Start compressor */
+
+ /* TRUE ensures that we will write a complete interchange-JPEG file.
+ * Pass TRUE unless you are very sure of what you're doing.
+ */
+ jpeg_start_compress(&cinfo, TRUE);
+
+ /* Step 5: while (scan lines remain to be written) */
+ /* jpeg_write_scanlines(...); */
+
+ /* Here we use the library's state variable cinfo.next_scanline as the
+ * loop counter, so that we don't have to keep track ourselves.
+ * To keep things simple, we pass one scanline per call; you can pass
+ * more if you wish, though.
+ */
+ row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */
+
+ while (cinfo.next_scanline < cinfo.image_height) {
+ /* jpeg_write_scanlines expects an array of pointers to scanlines.
+ * Here the array is only one element long, but you could pass
+ * more than one scanline at a time if that's more convenient.
+ */
+ row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
+ (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
+ }
+
+ /* Step 6: Finish compression */
+
+ jpeg_finish_compress(&cinfo);
+ /* After finish_compress, we can close the output file. */
+ fclose(outfile);
+
+ /* Step 7: release JPEG compression object */
+
+ /* This is an important step since it will release a good deal of memory. */
+ jpeg_destroy_compress(&cinfo);
+
+ /* And we're done! */
+}
+
+
+/*
+ * SOME FINE POINTS:
+ *
+ * In the above loop, we ignored the return value of jpeg_write_scanlines,
+ * which is the number of scanlines actually written. We could get away
+ * with this because we were only relying on the value of cinfo.next_scanline,
+ * which will be incremented correctly. If you maintain additional loop
+ * variables then you should be careful to increment them properly.
+ * Actually, for output to a stdio stream you needn't worry, because
+ * then jpeg_write_scanlines will write all the lines passed (or else exit
+ * with a fatal error). Partial writes can only occur if you use a data
+ * destination module that can demand suspension of the compressor.
+ * (If you don't know what that's for, you don't need it.)
+ *
+ * If the compressor requires full-image buffers (for entropy-coding
+ * optimization or a multi-scan JPEG file), it will create temporary
+ * files for anything that doesn't fit within the maximum-memory setting.
+ * (Note that temp files are NOT needed if you use the default parameters.)
+ * On some systems you may need to set up a signal handler to ensure that
+ * temporary files are deleted if the program is interrupted. See libjpeg.doc.
+ *
+ * Scanlines MUST be supplied in top-to-bottom order if you want your JPEG
+ * files to be compatible with everyone else's. If you cannot readily read
+ * your data in that order, you'll need an intermediate array to hold the
+ * image. See rdtarga.c or rdbmp.c for examples of handling bottom-to-top
+ * source data using the JPEG code's internal virtual-array mechanisms.
+ */
+
+
+
+/******************** JPEG DECOMPRESSION SAMPLE INTERFACE *******************/
+
+/* This half of the example shows how to read data from the JPEG decompressor.
+ * It's a bit more refined than the above, in that we show:
+ * (a) how to modify the JPEG library's standard error-reporting behavior;
+ * (b) how to allocate workspace using the library's memory manager.
+ *
+ * Just to make this example a little different from the first one, we'll
+ * assume that we do not intend to put the whole image into an in-memory
+ * buffer, but to send it line-by-line someplace else. We need a one-
+ * scanline-high JSAMPLE array as a work buffer, and we will let the JPEG
+ * memory manager allocate it for us. This approach is actually quite useful
+ * because we don't need to remember to deallocate the buffer separately: it
+ * will go away automatically when the JPEG object is cleaned up.
+ */
+
+
+/*
+ * ERROR HANDLING:
+ *
+ * The JPEG library's standard error handler (jerror.c) is divided into
+ * several "methods" which you can override individually. This lets you
+ * adjust the behavior without duplicating a lot of code, which you might
+ * have to update with each future release.
+ *
+ * Our example here shows how to override the "error_exit" method so that
+ * control is returned to the library's caller when a fatal error occurs,
+ * rather than calling exit() as the standard error_exit method does.
+ *
+ * We use C's setjmp/longjmp facility to return control. This means that the
+ * routine which calls the JPEG library must first execute a setjmp() call to
+ * establish the return point. We want the replacement error_exit to do a
+ * longjmp(). But we need to make the setjmp buffer accessible to the
+ * error_exit routine. To do this, we make a private extension of the
+ * standard JPEG error handler object. (If we were using C++, we'd say we
+ * were making a subclass of the regular error handler.)
+ *
+ * Here's the extended error handler struct:
+ */
+
+struct my_error_mgr {
+ struct jpeg_error_mgr pub; /* "public" fields */
+
+ jmp_buf setjmp_buffer; /* for return to caller */
+};
+
+typedef struct my_error_mgr * my_error_ptr;
+
+/*
+ * Here's the routine that will replace the standard error_exit method:
+ */
+
+//METHODDEF(void)
+void
+my_error_exit (j_common_ptr cinfo)
+{
+ /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
+ my_error_ptr myerr = (my_error_ptr) cinfo->err;
+
+ /* Always display the message. */
+ /* We could postpone this until after returning, if we chose. */
+ (*cinfo->err->output_message) (cinfo);
+
+ /* Return control to the setjmp point */
+ longjmp(myerr->setjmp_buffer, 1);
+}
+
+
+/*
+ * Sample routine for JPEG decompression. We assume that the source file name
+ * is passed in. We want to return 1 on success, 0 on error.
+ */
+
+
+int jpeg2rgb (JSAMPLE *rgb_buffer, JSAMPLE *jpeg_buffer)
+{
+ /* This struct contains the JPEG decompression parameters and pointers to
+ * working space (which is allocated as needed by the JPEG library).
+ */
+ struct jpeg_decompress_struct cinfo;
+ /* We use our private extension JPEG error handler.
+ * Note that this struct must live as long as the main JPEG parameter
+ * struct, to avoid dangling-pointer problems.
+ */
+ struct my_error_mgr jerr;
+ /* More stuff */
+ FILE * infile; /* source file */
+ JSAMPARRAY buffer; /* Output row buffer */
+ int row_stride; /* physical row width in output buffer */
+
+ /* In this example we want to open the input file before doing anything else,
+ * so that the setjmp() error recovery below can assume the file is open.
+ * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
+ * requires it in order to read binary files.
+ */
+ SDL_RWops *rw;
+
+ rw = SDL_RWFromMem(rgb_image, sizeof(rgb_image));
+
+ /*if ((infile = fopen(filename, "rb")) == NULL) {
+ fprintf(stderr, "can't open %s\n", filename);
+ return 0;
+ }*/
+
+ /* Step 1: allocate and initialize JPEG decompression object */
+
+ /* We set up the normal JPEG error routines, then override error_exit. */
+ cinfo.err = jpeg_std_error(&jerr.pub);
+ jerr.pub.error_exit = my_error_exit;
+ /* Establish the setjmp return context for my_error_exit to use. */
+ if (setjmp(jerr.setjmp_buffer)) {
+ /* If we get here, the JPEG code has signaled an error.
+ * We need to clean up the JPEG object, close the input file, and return.
+ */
+ jpeg_destroy_decompress(&cinfo);
+ fclose(infile);
+ return 0;
+ }
+ /* Now we can initialize the JPEG decompression object. */
+ jpeg_create_decompress(&cinfo);
+
+ /* Step 2: specify data source (eg, a file) */
+
+ jpeg_stdio_src(&cinfo, infile);
+
+ /* Step 3: read file parameters with jpeg_read_header() */
+
+ (void) jpeg_read_header(&cinfo, TRUE);
+ /* We can ignore the return value from jpeg_read_header since
+ * (a) suspension is not possible with the stdio data source, and
+ * (b) we passed TRUE to reject a tables-only JPEG file as an error.
+ * See libjpeg.doc for more info.
+ */
+
+ /* Step 4: set parameters for decompression */
+
+ /* In this example, we don't need to change any of the defaults set by
+ * jpeg_read_header(), so we do nothing here.
+ */
+
+ /* Step 5: Start decompressor */
+
+ (void) jpeg_start_decompress(&cinfo);
+ /* We can ignore the return value since suspension is not possible
+ * with the stdio data source.
+ */
+
+ /* We may need to do some setup of our own at this point before reading
+ * the data. After jpeg_start_decompress() we have the correct scaled
+ * output image dimensions available, as well as the output colormap
+ * if we asked for color quantization.
+ * In this example, we need to make an output work buffer of the right size.
+ */
+ /* JSAMPLEs per row in output buffer */
+ row_stride = cinfo.output_width * cinfo.output_components;
+ /* Make a one-row-high sample array that will go away when done with image */
+ buffer = (*cinfo.mem->alloc_sarray)
+ ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
+
+ /* Step 6: while (scan lines remain to be read) */
+ /* jpeg_read_scanlines(...); */
+
+ /* Here we use the library's state variable cinfo.output_scanline as the
+ * loop counter, so that we don't have to keep track ourselves.
+ */
+ while (cinfo.output_scanline < cinfo.output_height) {
+ /* jpeg_read_scanlines expects an array of pointers to scanlines.
+ * Here the array is only one element long, but you could ask for
+ * more than one scanline at a time if that's more convenient.
+ */
+ (void) jpeg_read_scanlines(&cinfo, buffer, 1);
+ /* Assume put_scanline_someplace wants a pointer and sample count. */
+ put_scanline_someplace(buffer[0], row_stride);
+ }
+
+ /* Step 7: Finish decompression */
+
+ (void) jpeg_finish_decompress(&cinfo);
+ /* We can ignore the return value since suspension is not possible
+ * with the stdio data source.
+ */
+
+ /* Step 8: Release JPEG decompression object */
+
+ /* This is an important step since it will release a good deal of memory. */
+ jpeg_destroy_decompress(&cinfo);
+
+ /* After finish_decompress, we can close the input file.
+ * Here we postpone it until after no more JPEG errors are possible,
+ * so as to simplify the setjmp error logic above. (Actually, I don't
+ * think that jpeg_destroy can do an error exit, but why assume anything...)
+ */
+ fclose(infile);
+
+ /* At this point you may want to check to see whether any corrupt-data
+ * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
+ */
+
+ /* And we're done! */
+ return 1;
+}
+
+
+/*
+ * SOME FINE POINTS:
+ *
+ * In the above code, we ignored the return value of jpeg_read_scanlines,
+ * which is the number of scanlines actually read. We could get away with
+ * this because we asked for only one line at a time and we weren't using
+ * a suspending data source. See libjpeg.doc for more info.
+ *
+ * We cheated a bit by calling alloc_sarray() after jpeg_start_decompress();
+ * we should have done it beforehand to ensure that the space would be
+ * counted against the JPEG max_memory setting. In some systems the above
+ * code would risk an out-of-memory error. However, in general we don't
+ * know the output image dimensions before jpeg_start_decompress(), unless we
+ * call jpeg_calc_output_dimensions(). See libjpeg.doc for more about this.
+ *
+ * Scanlines are returned in the same order as they appear in the JPEG file,
+ * which is standardly top-to-bottom. If you must emit data bottom-to-top,
+ * you can use one of the virtual arrays provided by the JPEG memory manager
+ * to invert the data. See wrbmp.c for an example.
+ *
+ * As with compression, some operating modes may require temporary files.
+ * On some systems you may need to set up a signal handler to ensure that
+ * temporary files are deleted if the program is interrupted. See libjpeg.doc.
+ */
--- /dev/null
+/*==========================================================================
+ $Id$
+ show_video_v4l.h: Header file for capturing video using V4L.
+ Written by Naoyuki Ichimura, AIST, 2001.
+==========================================================================*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include <GL/gl.h> /* for GLUT */
+#include <GL/glu.h>
+#include <GL/glut.h>
+
+#include "capture_v4l.h" /* for capture by V4L */
+
+/* pointer to image buffer */
+extern unsigned char disp_image[IMAGE_WIDTH_DS*IMAGE_HEIGHT_DS*RGB];
+/*==========================================================
+ Definitions for OpenGL
+==========================================================*/
+#define DEFAULT_ZOOM_RATE 4
+#define INIT_WINDOW_POS_X 200
+#define INIT_WINDOW_POS_Y 200
+
+/*==========================================================
+ Function Prototypes
+==========================================================*/
+/*=== show_video_v4l_capture.c ===*/
+void ShowVideoIdle();
+int ShowVideoInitCaptureDevice( char *device_name , int channel_no );
+void ShowVideoCaptureImage();
+void ShowVideoDisplayImage();
+void ShowVideoMouseCheck( int button , int status , int x , int y );
+void ShowVideoChangeOrderImageRow( unsigned char *image , int iwidth , int iheight );
+void ShowVideoSavePPMImage( unsigned char *image , int iheight , int iwidth , int frame_no , char *image_prefix );
+
+
+
+
--- /dev/null
+/*==========================================================================
+ $Id$
+ show_video_v4l_capture.c: Functions for capturing video using V4L.
+ Written by Naoyuki Ichimura, AIST, 2001.
+==========================================================================*/
+
+#include "show_video_v4l.h"
+#include "extract_skin_color.h"
+#include <time.h>
+
+#define PREFIX_IMAGE_FILE "video_image"
+
+/*=== Local global variables ===*/
+unsigned char disp_image[IMAGE_WIDTH_DS*IMAGE_HEIGHT_DS*RGB];/* pointer to image buffer */
+
+static int fd; /* file descriptor for frame buffer */
+static int exit_flag; /* flag to exit program */
+static int frame_no=1; /* frame number */
+
+static struct video_mbuf vm; /* structure for frame buffer */
+static struct video_mmap vmap; /* structure for memory space for frame buffer */
+
+/*=== global variable ===*/
+extern int extract_skin_color; /* global variable for enabling image processing */
+
+void ShowVideoCaptureImage()
+{
+
+ //static char image_prefix[1024]=PREFIX_IMAGE_FILE; /* Prefix of output image file */
+ static unsigned char image[IMAGE_WIDTH_DS*IMAGE_HEIGHT_DS*RGB]; /* Captured image */
+ static unsigned char skin_map[IMAGE_WIDTH_DS*IMAGE_HEIGHT_DS]; /* Skin color map */
+
+/*======= Wait capture for current frame ====================*/
+ //CaptureV4LDoubleBufferingCaptureWait( fd , &vmap );
+ CaptureV4LSimpleCapture( fd , &vmap );
+
+
+/*======= Set data to image array ===========================*/
+ CaptureV4LSetImageDownSamplingForOpenGL( vmap , vm , DOWN_SAMPLING_RATE , image , disp_image );
+
+/*======= Begin capture for next frame ======================*/
+ // if( CaptureV4LDoubleBufferingCaptureNextFrame( fd , &vmap ) == -1 ) {
+ //fprintf( stderr , "COuld not capture next frame.\n" );
+ //exit(-1);
+ //}
+
+/*======= Display image =====================================*/
+ //ShowVideoDisplayImage();
+/*======= Extract skin color by simple thresholding =========*/
+ if( extract_skin_color ) {
+ ExtractSkinColorSimpleThresholding( image , IMAGE_HEIGHT_DS , IMAGE_WIDTH_DS , skin_map );
+ ShowSkinRegion( skin_map , IMAGE_HEIGHT_DS , IMAGE_WIDTH_DS );
+ }
+
+
+#if 0
+/*======= Save image ========================================*/
+ ShowVideoSavePPMImage( image , IMAGE_HEIGHT_DS , IMAGE_WIDTH_DS , frame_no , image_prefix );
+#endif
+
+ /*======= Swap Buffer: show graphics ========================*/
+ //glutSwapBuffers();
+
+/*======= Increment frame number ============================*/
+ frame_no++;
+
+/*======= Check exit flag ===================================*/
+ if( exit_flag ) {
+ exit(0);
+ }
+
+}
+
+void ShowVideoDisplayImage()
+{
+
+ glRasterPos2i( 0 , 0 );
+ glDrawPixels( IMAGE_WIDTH_DS , IMAGE_HEIGHT_DS , GL_BGR , GL_UNSIGNED_BYTE , disp_image );
+ glFlush();
+
+}
+
+void ShowVideoIdle()
+{
+ struct timespec idle_time = {.tv_sec = 0, .tv_nsec = 50000000};
+
+ nanosleep(&idle_time, NULL);
+}
+
+int ShowVideoInitCaptureDevice( char *device_name , int channel_no )
+{
+
+ struct video_capability vcap; /* structure for video capability */
+ struct video_channel vch[MAX_NO_CHANNEL]; /* structure for video channel */
+ struct video_picture vp;
+
+/*======= Open video device ================================*/
+ if( ( fd = CaptureV4LOpen( device_name ) ) == -1 ) {
+ fprintf( stderr, "Could not open device %s.\n" , device_name );
+ exit(-1);
+ }
+
+/*======= Get information of device =========================*/
+ /*=== Get device capabilities ===*/
+ if( CaptureV4LGetDeviceCapability( fd , &vcap ) == -1 ) {
+ fprintf( stderr , "Could not get capabilities of video device.\n" );
+ exit(-1);
+ }
+
+ /*=== Get channel information ===*/
+ if( CaptureV4LGetChannelInfo( fd , vch , vcap.channels ) == -1 ) {
+ fprintf( stderr , "Could not get channel information of video device.\n" );
+ exit(-1);
+ }
+
+ /*=== Get memory map information ===*/
+ if( CaptureV4LGetMemoryMapInfo( fd , &vm ) == -1 ) {
+ fprintf( stderr , "Could not get memory map information.\n" );
+ exit(-1);
+ }
+
+/*======= Show picture information =========================*/
+ CaptureV4LGetPictureInfo( fd , &vp );
+ CaptureV4LDisplayPictureInfo( vp );
+
+/*======= Select channel ===================================*/
+ if( CaptureV4LSelectChannel( fd , vch , channel_no ) == -1 ) {
+ fprintf( stderr , "Could not select channel.\n" );
+ exit(-1);
+ }
+
+/*======= Mapping frame buffer ==============================*/
+ if( CaptureV4LMemoryMapping( fd , vm ) == -1 ) {
+ fprintf( stdout , "Could not map frame buffer.\n" );
+ exit(-1);
+ }
+
+/*======= Set image size and formate ========================*/
+ vmap.width = CAPTURE_IMAGE_WIDTH;
+ vmap.height = CAPTURE_IMAGE_HEIGHT;
+ vmap.format = VIDEO_PALETTE_RGB24;
+
+/*======= Begin Capture =====================================*/
+ //CaptureV4LDoubleBufferingInitCapture( fd , &vmap );
+
+ return 0;
+
+}
+
+
+void ShowVideoMouseCheck( int button , int status , int x , int y )
+{
+
+ if( button == GLUT_LEFT_BUTTON && status == GLUT_DOWN ) {
+ exit_flag = 1;
+ }
+
+}
+
+void ShowVideoSavePPMImage( unsigned char *image , int iheight , int iwidth , int frame_no , char *image_prefix )
+{
+
+ char file_name[1024];
+
+ FILE *fp;
+
+ sprintf( file_name , "%s_%d.ppm" , image_prefix , frame_no );
+ if( ( fp = fopen( file_name , "w" ) ) == NULL ) {
+ fprintf( stderr , "Could not open image file: %s\n" , file_name );
+ exit(1);
+ }
+ fprintf( fp , "P6 %d %d 255\n" , iwidth , iheight );
+ fwrite( image , iheight*iwidth*RGB , 1 , fp );
+ fclose(fp);
+
+}
+
+
+
+
+
+
--- /dev/null
+/*==========================================================================
+ $Id$
+ show_video_v4l_main.c: Main routine for capturing video using GLUT and V4L.
+ Written by Naoyuki Ichimura, AIST, 2001.
+==========================================================================*/
+
+#include "show_video_v4l.h"
+
+int extract_skin_color; /* global variable for enabling image processing */
+
+#include "camera.h"
+//int main( int argc , char *argv[] )
+void* video_thread(void* args)
+{
+ video_args_t *video_args = (video_args_t*) args;
+ int argc = video_args->argc;
+ char** argv;
+
+ argv = video_args->argv;
+ static char window_title[1024]="Video Capture";
+ int i,j;
+ int video_input;
+
+ double zoom_rate; /* for zooming */
+
+/*======= Set option =========================================*/
+ zoom_rate = DEFAULT_ZOOM_RATE;
+ //video_input = S_VIDEO;
+ video_input = 0;
+ extract_skin_color = 0;
+ for( i = j = 1 ; i < argc ; i++ ) {
+ if( argv[i][0] == '-' || argv[i][0] == '/' ) {
+ switch( argv[i][1] ) {
+ case 'z':
+ zoom_rate = atof(&argv[i][2]);
+ break;
+
+ case 'v':
+ video_input = atoi(&argv[i][2]);
+ break;
+
+ case 's':
+ extract_skin_color = 1;
+ break;
+
+ default:
+ break;
+
+ }
+ } else {
+ argv[j++] = argv[i];
+ }
+ }
+ argc = j;
+
+/*======= Initialize GLUT ====================================*/
+ glutInit( &argc , argv );
+ glutInitDisplayMode( GLUT_RGBA); /* enable double buffering of video board */
+
+/*======= Initialize window ==================================*/
+ glutInitWindowPosition( INIT_WINDOW_POS_X , INIT_WINDOW_POS_Y ); /* initial window position */
+ glutInitWindowSize( (int)(zoom_rate*IMAGE_WIDTH_DS) , (int)(zoom_rate*IMAGE_HEIGHT_DS) ); /* set window size */
+ glutCreateWindow( window_title ); /* creat window with name */
+
+/*======= Initialize projection ==============================*/
+ glOrtho( 0.0 , IMAGE_WIDTH_DS-1.0 , 0.0 , IMAGE_HEIGHT_DS , -1.0 , 1.0 );
+ glPixelZoom( zoom_rate , zoom_rate );
+
+/*======= Initilize capture device ============================*/
+ //ShowVideoInitCaptureDevice( DEFAULT_DEVICE_NAME , video_input );
+
+/*======= Initilize buffer ====================================*/
+ glClearColor( 0.0 , 0.0 , 0.0 , 0.0 );
+ glClear( GL_COLOR_BUFFER_BIT );
+ //glutSwapBuffers();
+ glFlush();
+
+/*======= Register callback functions =========================*/
+ glutDisplayFunc( ShowVideoDisplayImage );
+ glutMouseFunc( ShowVideoMouseCheck );
+ //glutIdleFunc( ShowVideoCaptureImage ); /* global idle callback */
+ glutIdleFunc( ShowVideoIdle ); /* global idle callback */
+
+/*======= Begin event loop ====================================*/
+ glutMainLoop();
+
+ exit(0);
+
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+FRSH_LIBS = frsh
+lib_LOADLIBES+= m pthread rt $(FRSH_LIBS)
+
+bin_PROGRAMS = fplayer
+fplayer_SOURCES = play.c play.h
+
+bin_PROGRAMS += fplayer_th
+fplayer_th_SOURCES = play_th.c play_th.h
+
--- /dev/null
+#include "play.h"
+
+frsh_rel_time_t player_budget, player_period;
+frsh_contract_t player_contract;
+frsh_thread_id_t player_thread;
+frsh_vres_id_t player_vres;
+
+sem_t *player_stopper;
+int stopper_fd;
+
+void player(struct player_args *args)
+{
+ char cmd[255];
+
+ fprintf(stdout, "== Waiting for being bound...\n");
+
+ sem_wait(player_stopper);
+ munmap(player_stopper, sizeof(sem_t));
+
+ fprintf(stdout,
+ "== Starting playing %s, with %d/%d CPU bandwidth\n",
+ args->file, args->budget, args->period);
+
+ snprintf(cmd, 255, PLAYER_BINARY PLAYER_ARGS " %s", args->file);
+ fprintf(stdout, "== Issuing command:\n %s\n", cmd);
+
+ execlp(PLAYER_BINARY, PLAYER_BINARY, PLAYER_ARGS, args->file, (char*) NULL);
+}
+
+int main(int argc, char *argv[])
+{
+ struct player_args args;
+ int player_status;
+ pid_t player_pid;
+ int opt, terror;
+
+ if (argc < 7) {
+err_usage:
+ fprintf(stderr, "USAGE:\n"
+ "%s -b budget_usec -p period_usec -f file\n\n",
+ argv[0]);
+ error(EXIT_FAILURE, EINVAL, "Wrong argument count");
+ }
+
+ while ((opt = getopt(argc, argv, "b:p:f:")) != -1) {
+ switch (opt) {
+ case 'b':
+ args.budget = atoi(optarg);
+ break;
+ case 'p':
+ args.period = atoi(optarg);
+ break;
+ case 'f':
+ strncpy(args.file, optarg, sizeof(args.file));
+ break;
+ default:
+ goto err_usage;
+ }
+ }
+
+ PXW(frsh_init());
+
+ stopper_fd = shm_open("/stopper", O_CREAT|O_EXCL|O_RDWR, S_IRWXU);
+ if (stopper_fd < 0) assert_perror(errno);
+
+ terror = ftruncate(stopper_fd, sizeof(sem_t));
+ if (terror) {
+ shm_unlink("/stopper");
+ assert_perror(errno);
+ }
+
+ player_stopper = mmap(NULL, sizeof(sem_t), PROT_READ|PROT_WRITE,
+ MAP_SHARED, stopper_fd, 0);
+ if (player_stopper == MAP_FAILED) {
+ shm_unlink("/stopper");
+ assert_perror(errno);
+ }
+
+ terror = close(stopper_fd);
+ if (terror) {
+ shm_unlink("/stopper");
+ assert_perror(errno);
+ }
+
+ sem_init(player_stopper, 1, 0);
+ fprintf(stderr, "FRSH initialized\n");
+
+ player_budget = fosa_usec_to_rel_time(args.budget);
+ player_period = fosa_usec_to_rel_time(args.period);
+ PXW(frsh_contract_init(&player_contract));
+ PXW(frsh_contract_set_basic_params(&player_contract,
+ &player_budget,
+ &player_period,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR));
+ PXW(frsh_contract_set_resource_and_label(&player_contract,
+ FRSH_RT_PROCESSOR,
+ 0,
+ "PLAYER_CONTRACT"));
+ fprintf(stdout, "Player contract initialized\n");
+
+ PXW(frsh_contract_negotiate(&player_contract, &player_vres));
+ fprintf(stdout, "Player contract negotiated\n");
+
+ terror = player_pid = fork();
+ if (terror < 0) {
+ /* error */
+ assert_perror(errno);
+ } else if (!terror) {
+ /* child process: */
+ player(&args);
+ }
+
+ player_thread.linux_pid = player_thread.linux_tid = player_pid;
+ PXW(frsh_thread_bind(player_vres, player_thread));
+ fprintf(stdout, "Player thread bound to its contract\n");
+
+ sem_post(player_stopper);
+ munmap(player_stopper, sizeof(sem_t));
+ shm_unlink("/stopper");
+
+ waitpid(player_pid, &player_status, 0);
+ if (WIFEXITED(player_status))
+ fprintf(stdout, "Playback finished normally\n");
+ else if (WIFSIGNALED(player_status))
+ fprintf(stdout, "Playback aborted\n");
+
+ PXW(frsh_contract_cancel(player_vres));
+
+ exit(EXIT_SUCCESS);
+}
+
--- /dev/null
+#ifndef _PLAY_H_
+#define _PLAY_H_
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <error.h>
+#include <assert.h>
+#include <semaphore.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#include <frsh.h>
+
+#define PLAYER_BINARY "mplayer"
+#define PLAYER_ARGS " -fs -zoom "
+
+struct player_args {
+ int budget, period;
+ char file[128];
+};
+
+void player(struct player_args *args);
+
+#endif /* _PLAY_H_ */
+
--- /dev/null
+#include "play_th.h"
+
+static void player_cleanup(void *arg)
+{
+ frsh_vres_id_t vres;
+
+ frsh_thread_get_vres_id(fosa_thread_self(), &vres);
+ frsh_contract_cancel(vres);
+}
+
+void *player(void *thread_args)
+{
+ struct player_args *args = (struct player_args*) thread_args;
+
+ frsh_rel_time_t player_budget, player_period;
+ frsh_contract_t player_contract;
+ frsh_vres_id_t player_vres;
+
+ int terror, status;
+ char cmd[255];
+
+ fprintf(stdout, "== Waiting for being bound...\n");
+
+ fprintf(stdout,
+ "== Starting playing %s, with %d/%d CPU bandwidth\n",
+ args->file, args->budget, args->period);
+
+ player_budget = fosa_usec_to_rel_time(args->budget);
+ player_period = fosa_usec_to_rel_time(args->period);
+ PXW(frsh_contract_init(&player_contract));
+ PXW(frsh_contract_set_basic_params(&player_contract,
+ &player_budget,
+ &player_period,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR));
+ PXW(frsh_contract_set_resource_and_label(&player_contract,
+ FRSH_RT_PROCESSOR,
+ 0,
+ "PLAYER_CONTRACT"));
+ fprintf(stdout, "== Player contract initialized\n");
+
+ PXW(frsh_contract_negotiate(&player_contract, &player_vres));
+ fprintf(stdout, "== Player contract negotiated\n");
+
+ pthread_cleanup_push(player_cleanup, NULL);
+
+ PXW(frsh_thread_bind(player_vres, fosa_thread_self()));
+ fprintf(stdout, "== Player thread bound to its contract\n");
+
+ snprintf(cmd, 255, PLAYER_BINARY PLAYER_ARGS " %s", args->file);
+
+ fprintf(stdout, "== Issuing command:\n %s\n", cmd);
+
+ status = system(cmd);
+
+ if (WIFEXITED(status))
+ fprintf(stdout, "== Playback finished normally\n");
+ else if (WIFSIGNALED(status))
+ fprintf(stdout, "== Playback aborted\n");
+
+ pthread_cleanup_pop(1);
+
+ pthread_exit(EXIT_SUCCESS);
+}
+
+int main(int argc, char *argv[])
+{
+ pthread_t player_thread;
+ pthread_attr_t player_attr;
+ struct player_args args;
+ int opt, terror;
+
+ if (argc < 7) {
+err_usage:
+ fprintf(stderr, "USAGE:\n"
+ "%s -b budget_usec -p period_usec -f file\n\n",
+ argv[0]);
+ error(EXIT_FAILURE, EINVAL, "Wrong argument count");
+ }
+
+ while ((opt = getopt(argc, argv, "b:p:f:")) != -1) {
+ switch (opt) {
+ case 'b':
+ args.budget = atoi(optarg);
+ break;
+ case 'p':
+ args.period = atoi(optarg);
+ break;
+ case 'f':
+ strncpy(args.file, optarg, sizeof(args.file));
+ break;
+ default:
+ goto err_usage;
+ }
+ }
+
+ PXW(frsh_init());
+ fprintf(stdout, "FRSH initialized\n");
+
+ terror = pthread_attr_init(&player_attr);
+ if (terror) assert_perror(errno);
+
+ terror = pthread_create(&player_thread, &player_attr, player, (void*) &args);
+ if (terror) assert_perror(errno);
+ fprintf(stdout, "FRSH thread created, waiting for its termination...\n");
+
+ terror = pthread_join(player_thread, NULL);
+ if (terror) assert_perror(errno);
+ fprintf(stdout, "FRSH thread ended. Exiting\n\n");
+
+ exit(EXIT_SUCCESS);
+}
+
--- /dev/null
+#ifndef _PLAY_H_
+#define _PLAY_H_
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <error.h>
+#include <assert.h>
+#include <semaphore.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#include <frsh.h>
+
+#define PLAYER_BINARY "mplayer"
+#define PLAYER_ARGS " -fs -zoom "
+
+struct player_args {
+ int budget, period;
+ char file[128];
+};
+
+void *player(void *args);
+
+#endif /* _PLAY_H_ */
+
--- /dev/null
+*.png
+*.pdf
--- /dev/null
+FIGS = $(wildcard *.svg)
+
+TARGETS = $(FIGS:%.svg=%.pdf) $(FIGS:%.svg=%.png)
+
+all: $(TARGETS)
+
+clean:
+ rm $(TARGETS)
+
+%.png: %.svg
+ inkscape --export-area-drawing --export-png=$@ --export-background-opacity=1.0 $<
+
+%.ps: %.svg
+ inkscape --export-ps=$@ $<
+
+%-page.pdf: %.svg
+ inkscape --export-pdf=$@ $<
+
+%-page.pdf: %.ps
+ ps2pdf $< $@
+
+%.pdf: %-page.pdf
+ pdfcrop $< $@
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2383"
+ sodipodi:version="0.32"
+ inkscape:version="0.47 r22583"
+ sodipodi:docname="contract.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ version="1.0"
+ inkscape:export-filename="/home/wsh/frescor/doc/prezentations/contract-flow.png"
+ inkscape:export-xdpi="120"
+ inkscape:export-ydpi="120">
+ <defs
+ id="defs2385">
+ <marker
+ inkscape:stockid="Arrow1Sstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Sstart"
+ style="overflow:visible">
+ <path
+ id="path3403"
+ d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="matrix(0.2,0,0,0.2,1.2,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mstart"
+ style="overflow:visible">
+ <path
+ id="path3978"
+ d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="matrix(0.4,0,0,0.4,4,0)" />
+ </marker>
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 372.04724 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1052.3622 : 372.04724 : 1"
+ inkscape:persp3d-origin="526.18109 : 248.03149 : 1"
+ id="perspective2543" />
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mend"
+ style="overflow:visible">
+ <path
+ id="path4099"
+ d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="matrix(-0.4,0,0,-0.4,-4,0)" />
+ </marker>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4.0587435"
+ inkscape:cx="502.90715"
+ inkscape:cy="718.33483"
+ inkscape:current-layer="g3333"
+ inkscape:document-units="px"
+ showgrid="false"
+ inkscape:window-width="1270"
+ inkscape:window-height="963"
+ inkscape:window-x="1680"
+ inkscape:window-y="0"
+ inkscape:object-paths="true"
+ inkscape:object-nodes="false"
+ objecttolerance="10"
+ gridtolerance="10000"
+ guidetolerance="2"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-nodes="true"
+ showborder="true"
+ inkscape:connector-spacing="3"
+ units="cm"
+ borderlayer="false"
+ inkscape:snap-intersection-line-segments="true"
+ inkscape:snap-intersection-grid-guide="false"
+ inkscape:snap-center="true"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:window-maximized="0">
+ <sodipodi:guide
+ orientation="1,0"
+ position="485.75011,639.07471"
+ id="guide2693" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata2388">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ id="layer2"
+ inkscape:label="Contract flow"
+ style="display:inline"
+ transform="translate(-58.52032,-298.67903)">
+ <g
+ id="g4013"
+ transform="matrix(0.4763631,0,0,0.4763631,327.4978,400.92868)">
+ <rect
+ y="305.53189"
+ x="424.65244"
+ height="362.0498"
+ width="211.34297"
+ id="rect3553"
+ style="fill:#ffc0c0;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <g
+ id="g3333"
+ transform="translate(0,-194.88188)"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="fill:#5599ff;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect2517"
+ width="189.63651"
+ height="34.305229"
+ x="437.48056"
+ y="535.75897" />
+ <text
+ id="text3313"
+ y="560.36761"
+ x="538.02631"
+ style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10"
+ xml:space="preserve"><tspan
+ y="560.36761"
+ x="538.02631"
+ id="tspan3315"
+ sodipodi:role="line">Global contract ID</tspan></text>
+ </g>
+ <g
+ id="g2611"
+ transform="matrix(1.005391,0,0,1,-2.3585736,66.474812)"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3571"
+ width="188.35999"
+ height="80.019386"
+ x="437.49869"
+ y="373.50946" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ x="454.54352"
+ y="394.85056"
+ id="text3573"><tspan
+ sodipodi:role="line"
+ x="454.54352"
+ y="394.85056"
+ id="tspan2673">Basic params</tspan><tspan
+ sodipodi:role="line"
+ x="454.54352"
+ y="409.88306"
+ id="tspan2677"
+ style="font-size:10px;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">budget</tspan><tspan
+ sodipodi:role="line"
+ x="454.54352"
+ y="422.38306"
+ id="tspan2679"
+ style="font-size:10px;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">period</tspan><tspan
+ sodipodi:role="line"
+ x="454.54352"
+ y="434.88306"
+ id="tspan2681"
+ style="font-size:10px;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">workload</tspan><tspan
+ sodipodi:role="line"
+ x="454.54352"
+ y="447.38306"
+ id="tspan2683"
+ style="font-size:10px;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">...</tspan></text>
+ </g>
+ <g
+ id="g2616"
+ transform="translate(0,106.7147)"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ y="417.76917"
+ x="437.48056"
+ height="44.567593"
+ width="189.63651"
+ id="rect3585"
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ id="text3587"
+ y="440.06357"
+ x="455.11615"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ id="tspan3589"
+ y="440.06357"
+ x="455.11615"
+ sodipodi:role="line">Timing reqs.</tspan><tspan
+ y="455.09607"
+ x="455.11615"
+ sodipodi:role="line"
+ id="tspan2685"
+ style="font-size:10px;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">deadline</tspan><tspan
+ y="467.59607"
+ x="455.11615"
+ sodipodi:role="line"
+ id="tspan2687"
+ style="font-size:10px;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" /><tspan
+ id="tspan3591"
+ y="480.09607"
+ x="455.11615"
+ sodipodi:role="line" /></text>
+ </g>
+ <g
+ id="g2622"
+ transform="translate(0,112.31959)"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3595"
+ width="189.63651"
+ height="39.759399"
+ x="437.48056"
+ y="461.21204" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ x="453.98822"
+ y="481.5563"
+ id="text3597"><tspan
+ sodipodi:role="line"
+ x="453.98822"
+ y="481.5563"
+ id="tspan3601"
+ style="text-align:start;text-anchor:start;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">Res. specific par.</tspan><tspan
+ sodipodi:role="line"
+ x="453.98822"
+ y="496.58881"
+ id="tspan2695"
+ style="font-size:10px;text-align:start;text-anchor:start;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">...</tspan></text>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ x="747.26892"
+ y="541.07788"
+ id="text3329"
+ transform="translate(-152.74315,9.39647)"><tspan
+ sodipodi:role="line"
+ id="tspan3331"
+ x="747.26892"
+ y="541.07788" /></text>
+ <text
+ xml:space="preserve"
+ style="font-size:15.90077018999999936px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ x="436.09311"
+ y="327.21503"
+ id="text2620"><tspan
+ sodipodi:role="line"
+ id="tspan2622"
+ x="436.09311"
+ y="327.21503">Contract</tspan></text>
+ <g
+ transform="translate(0,89.79245)"
+ id="g3460"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3462"
+ width="189.63651"
+ height="53.897011"
+ x="437.48056"
+ y="291.81458" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ x="454.789"
+ y="312.21606"
+ id="text3464"><tspan
+ sodipodi:role="line"
+ x="454.789"
+ y="312.21606"
+ id="tspan3468">Resource</tspan><tspan
+ sodipodi:role="line"
+ x="454.789"
+ y="327.24857"
+ id="tspan2689"
+ style="font-size:10px;text-align:start;text-anchor:start;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">type</tspan><tspan
+ sodipodi:role="line"
+ x="454.789"
+ y="339.74857"
+ id="tspan2691"
+ style="font-size:10px;text-align:start;text-anchor:start;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">id</tspan></text>
+ </g>
+ <g
+ transform="translate(0,156.55916)"
+ id="g2699"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ y="461.21204"
+ x="437.48056"
+ height="39.759399"
+ width="189.63651"
+ id="rect2701"
+ style="fill:#ffcc00;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ id="text2703"
+ y="481.5563"
+ x="453.98822"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ style="text-align:start;text-anchor:start;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="tspan2705"
+ y="481.5563"
+ x="453.98822"
+ sodipodi:role="line">Res. specific par.</tspan><tspan
+ style="font-size:10px;text-align:start;text-anchor:start;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="tspan2707"
+ y="496.58881"
+ x="453.98822"
+ sodipodi:role="line">priority</tspan></text>
+ </g>
+ <rect
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.21407068000000007;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3456"
+ width="188.74805"
+ height="276.93176"
+ x="437.60571"
+ y="381.69553" />
+ </g>
+ <text
+ id="text2603"
+ y="499.10986"
+ x="-684.84082"
+ style="font-size:9.52726172999999932px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ xml:space="preserve"
+ transform="matrix(0,-1,1,0,0,0)"><tspan
+ y="499.10986"
+ x="-684.84082"
+ id="tspan2605"
+ sodipodi:role="line">Contract blocks</tspan></text>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.59545386;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Mstart);marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 535.90603,629.20072 L 501.90329,644.62327"
+ id="path2609"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.59545386;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Mstart);marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 535.95703,682.40198 L 501.90329,644.62327"
+ id="path2611"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path11031"
+ d="M 535.95703,704.12038 L 501.90329,644.62327"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.59545386;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Mstart);marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path11033"
+ d="M 535.95703,660.7437 L 501.90329,644.62327"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.59545386;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Mstart);marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.59545386;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Mstart);marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 535.95703,595.73192 L 501.90327,644.62326"
+ id="path4605"
+ sodipodi:nodetypes="cc" />
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="1052.3622"
+ height="744.09448"
+ id="svg4707"
+ sodipodi:version="0.32"
+ inkscape:version="0.47 r22583"
+ sodipodi:docname="frsh-forb-arch.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ inkscape:export-filename="/home/wsh/frescor/doc/prezentations/dtm-architecture.png"
+ inkscape:export-xdpi="120"
+ inkscape:export-ydpi="120"
+ version="1.0">
+ <defs
+ id="defs4709">
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mend"
+ style="overflow:visible">
+ <path
+ id="path3415"
+ d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="matrix(-0.4,0,0,-0.4,-4,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mstart"
+ style="overflow:visible">
+ <path
+ id="path3412"
+ d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="matrix(0.4,0,0,0.4,4,0)" />
+ </marker>
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 384 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1024 : 384 : 1"
+ inkscape:persp3d-origin="512 : 256 : 1"
+ id="perspective4715" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.163993"
+ inkscape:cx="509.44821"
+ inkscape:cy="372.06678"
+ inkscape:current-layer="g5379"
+ inkscape:document-units="px"
+ showgrid="false"
+ inkscape:snap-global="true"
+ inkscape:window-width="1680"
+ inkscape:window-height="998"
+ inkscape:window-x="1024"
+ inkscape:window-y="0"
+ inkscape:snap-intersection-line-segments="true"
+ inkscape:object-paths="false"
+ inkscape:object-nodes="true"
+ objecttolerance="10000"
+ gridtolerance="10000"
+ showborder="false"
+ inkscape:snap-bbox="false"
+ inkscape:bbox-paths="true"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ guidetolerance="3"
+ inkscape:window-maximized="1"
+ inkscape:snap-grids="false"
+ inkscape:snap-to-guides="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid5238"
+ visible="true"
+ enabled="true" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata4712">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ transform="translate(-48.5,-26.392853)">
+ <g
+ id="g5379"
+ transform="translate(54.641006,54.585953)">
+ <use
+ height="768"
+ width="1024"
+ transform="translate(476,0)"
+ id="use6480"
+ xlink:href="#rect6476"
+ y="0"
+ x="0"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <rect
+ y="-622.41089"
+ x="90.060234"
+ height="594.45782"
+ width="411.84955"
+ id="rect6476"
+ style="fill:#d5d5ff;fill-opacity:1;stroke:#000000;stroke-width:3.12047005000000022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ transform="scale(1,-1)" />
+ <g
+ id="g2961"
+ transform="matrix(1,0,0,0.93850794,0,10.31112)"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ transform="scale(1,-1)"
+ y="-304.49786"
+ x="8.7381992"
+ height="119.52741"
+ width="989.138"
+ id="rect2499"
+ style="fill:#7f7f7f;fill-opacity:0.25098039000000000;stroke:none;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ transform="matrix(0,-1,1,0,0,0)"
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10"
+ x="-244.36307"
+ y="31.471245"
+ id="text3285"><tspan
+ sodipodi:role="line"
+ x="-241.02322"
+ y="31.471245"
+ id="tspan3289">Resource </tspan><tspan
+ sodipodi:role="line"
+ x="-244.36307"
+ y="56.471245"
+ id="tspan3009">independent</tspan><tspan
+ sodipodi:role="line"
+ x="-244.36307"
+ y="81.471245"
+ id="tspan3015">level</tspan></text>
+ </g>
+ <rect
+ style="fill:#5599ff;fill-opacity:1;stroke:#000000;stroke-width:1.94235766000000010;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3285"
+ width="320.45312"
+ height="80.05764"
+ x="589.97119"
+ y="-277.9216"
+ transform="scale(1,-1)" />
+ <g
+ id="g2966"
+ transform="matrix(1,0,0,0.94160041,0,20.710131)"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ transform="scale(1,-1)"
+ style="fill:#7f7f7f;fill-opacity:0.25098039000000000;stroke:none;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3283"
+ width="987.80408"
+ height="256.01465"
+ x="8.8086605"
+ y="-601.58911" />
+ <text
+ id="text3299"
+ y="55.075195"
+ x="-467.86731"
+ style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10"
+ xml:space="preserve"
+ transform="matrix(0,-1,1,0,0,0)"><tspan
+ y="55.075195"
+ x="-467.86731"
+ sodipodi:role="line"
+ id="tspan3007">Resource-specific level</tspan></text>
+ </g>
+ <rect
+ y="-277.89279"
+ x="110"
+ height="80"
+ width="319.63229"
+ id="rect5272"
+ style="fill:#5599ff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ transform="scale(1,-1)" />
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:#000000;stroke-width:1.80635451999999996;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect5280"
+ width="150.19365"
+ height="65.174194"
+ x="109.90318"
+ y="-112.97017"
+ transform="scale(1,-1)" />
+ <text
+ id="text5286"
+ y="230.05099"
+ x="270.07495"
+ style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10"
+ xml:space="preserve"><tspan
+ y="230.05099"
+ x="270.07495"
+ sodipodi:role="line"
+ id="tspan3686">FRSH Contract Broker Agent</tspan><tspan
+ id="tspan3292"
+ y="255.05099"
+ x="270.07495"
+ sodipodi:role="line">(FCB)</tspan></text>
+ <text
+ id="text5292"
+ y="75.480728"
+ x="185.78125"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ y="75.480728"
+ x="185.78125"
+ id="tspan5294"
+ sodipodi:role="line">Application</tspan><tspan
+ id="tspan5296"
+ y="100.48073"
+ x="185.78125"
+ sodipodi:role="line">1</tspan></text>
+ <use
+ x="0"
+ y="0"
+ xlink:href="#rect5280"
+ id="use3001"
+ transform="translate(168.43239,0)"
+ width="1052.3622"
+ height="744.09448"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <g
+ id="g2547"
+ transform="matrix(1,0,0,-1,20,618.38307)"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ x="340.78125"
+ y="-542.90234"
+ id="text5298"
+ transform="scale(1,-1)"><tspan
+ sodipodi:role="line"
+ id="tspan5300"
+ x="340.78125"
+ y="-542.90234">Application</tspan><tspan
+ sodipodi:role="line"
+ x="340.78125"
+ y="-517.90234"
+ id="tspan5302">2</tspan></text>
+ </g>
+ <g
+ id="g2780"
+ transform="translate(40,-19.991355)"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <path
+ style="fill:none;stroke:#7f7f7f;stroke-width:2.99999976000000013;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="m 77.381923,331.12462 145.078657,0"
+ id="path2773"
+ sodipodi:nodetypes="cc" />
+ <text
+ id="text2776"
+ y="338.39813"
+ x="226.99577"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#727272;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ y="338.39813"
+ x="226.99577"
+ id="tspan2778"
+ sodipodi:role="line">Internal API</tspan></text>
+ </g>
+ <g
+ id="g3279"
+ transform="translate(40,-300.0724)"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#727272;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10"
+ x="235.1579"
+ y="463.61404"
+ id="text3274"><tspan
+ sodipodi:role="line"
+ id="tspan3276"
+ x="235.1579"
+ y="463.61404"
+ style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:cmr10;-inkscape-font-specification:cmr10">FRSH API</tspan></text>
+ </g>
+ <path
+ id="path5318"
+ d="m 190,112.5481 0,83.33737"
+ style="fill:none;stroke:#000000;stroke-width:2.99999976000000013;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <path
+ id="path5320"
+ d="m 360,112.5481 0,83.33737"
+ style="fill:none;stroke:#000000;stroke-width:2.99999976000000013;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <g
+ id="g2505"
+ transform="translate(20,159.8928)"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ y="198"
+ x="180"
+ height="80"
+ width="109.46667"
+ id="rect5304"
+ style="fill:#ffcc00;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ x="234.28412"
+ y="219.20953"
+ id="text6362"><tspan
+ sodipodi:role="line"
+ id="tspan6364"
+ x="234.28412"
+ y="219.20953">Resource</tspan><tspan
+ sodipodi:role="line"
+ x="234.28412"
+ y="244.20953"
+ id="tspan6366">Manager</tspan><tspan
+ sodipodi:role="line"
+ x="234.28412"
+ y="269.20953"
+ id="tspan6368">[CPU]</tspan></text>
+ </g>
+ <g
+ id="g2529"
+ transform="translate(20,439.8928)"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <g
+ id="g2512"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ y="58"
+ x="180"
+ height="80"
+ width="109.46667"
+ id="rect5284"
+ style="fill:#ffcc00;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ </g>
+ <text
+ id="text6370"
+ y="79.209534"
+ x="234.73822"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#0000ff;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ y="79.209534"
+ x="234.73822"
+ id="tspan6372"
+ sodipodi:role="line">Resource</tspan><tspan
+ id="tspan6374"
+ y="104.20953"
+ x="234.73822"
+ sodipodi:role="line">Manager</tspan><tspan
+ id="tspan6376"
+ y="129.20953"
+ x="234.73822"
+ sodipodi:role="line">[Network]</tspan></text>
+ </g>
+ <g
+ id="g2522"
+ transform="translate(20,159.8928)"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="fill:#fff6d5;fill-opacity:1;stroke:#ffcc00;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect5308"
+ width="109.46667"
+ height="80"
+ x="300"
+ y="198" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ x="354.08392"
+ y="218.97168"
+ id="text6378"><tspan
+ sodipodi:role="line"
+ id="tspan6380"
+ x="354.08392"
+ y="218.97168">Resource</tspan><tspan
+ sodipodi:role="line"
+ x="354.08392"
+ y="243.97168"
+ id="tspan6382">Allocator</tspan><tspan
+ sodipodi:role="line"
+ x="354.08392"
+ y="268.97168"
+ id="tspan6384">[CPU]</tspan></text>
+ </g>
+ <g
+ id="g2515"
+ transform="translate(20,439.8928)"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ y="58"
+ x="300"
+ height="80"
+ width="109.46667"
+ id="rect5306"
+ style="fill:#fff6d5;fill-opacity:1;stroke:#ffcc00;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#0000ff;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ x="354.08392"
+ y="77.816833"
+ id="text6386"><tspan
+ sodipodi:role="line"
+ id="tspan6388"
+ x="354.08392"
+ y="77.816833">Resource</tspan><tspan
+ sodipodi:role="line"
+ x="354.08392"
+ y="102.81683"
+ id="tspan6390">Allocator</tspan><tspan
+ sodipodi:role="line"
+ x="354.08392"
+ y="127.81683"
+ id="tspan6392">[Network]</tspan></text>
+ </g>
+ <path
+ sodipodi:nodetypes="cccc"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#Arrow1Mend);-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="m 190,277.8928 0,50 190,0 0,30"
+ id="path6394" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#Arrow1Mend);-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="m 150,277.8928 0,190 230,0 0,30"
+ id="path6396"
+ sodipodi:nodetypes="cccc" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#rect5280"
+ id="use3003"
+ transform="translate(477.09817,0)"
+ width="1052.3622"
+ height="744.09448"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ x="665.78125"
+ y="75.339127"
+ id="text6414"><tspan
+ sodipodi:role="line"
+ id="tspan6416"
+ x="665.78125"
+ y="75.339127">Application</tspan><tspan
+ sodipodi:role="line"
+ x="665.78125"
+ y="100.33913"
+ id="tspan6418">3</tspan></text>
+ <use
+ x="0"
+ y="0"
+ xlink:href="#rect5280"
+ id="use3005"
+ transform="translate(647.6762,0)"
+ width="1052.3622"
+ height="744.09448"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <g
+ id="g3384"
+ transform="matrix(1,0,0,-1,-60,618.38307)"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <text
+ id="text6420"
+ y="-542.90234"
+ x="900.78125"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ xml:space="preserve"
+ transform="scale(1,-1)"><tspan
+ y="-542.90234"
+ x="900.78125"
+ id="tspan6422"
+ sodipodi:role="line">Application</tspan><tspan
+ id="tspan6424"
+ y="-517.90234"
+ x="900.78125"
+ sodipodi:role="line">4</tspan></text>
+ </g>
+ <rect
+ y="-437.89279"
+ x="680"
+ height="80"
+ width="109.46667"
+ id="rect6426"
+ style="fill:#ffcc00;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ transform="scale(1,-1)" />
+ <rect
+ y="-577.89282"
+ x="800"
+ height="80"
+ width="109.46667"
+ id="rect6428"
+ style="fill:#fff6d5;fill-opacity:1;stroke:#ffcc00;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ transform="scale(1,-1)" />
+ <rect
+ style="fill:#fff6d5;fill-opacity:1;stroke:#ffcc00;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect6430"
+ width="109.46667"
+ height="80"
+ x="800"
+ y="-437.89279"
+ transform="scale(1,-1)" />
+ <g
+ id="g2785"
+ transform="translate(535.24317,-19.991355)"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path2787"
+ d="m 77.381923,331.12462 145.078657,0"
+ style="fill:none;stroke:#7f7f7f;stroke-width:2.99999976000000013;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#727272;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ x="226.99577"
+ y="338.39813"
+ id="text2789"><tspan
+ sodipodi:role="line"
+ id="tspan2791"
+ x="226.99577"
+ y="338.39813">Internal API</tspan></text>
+ </g>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="m 650,277.8928 0,120 30,0"
+ id="path6432"
+ sodipodi:nodetypes="ccc" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10"
+ x="750.45654"
+ y="230.05098"
+ id="text3287"><tspan
+ sodipodi:role="line"
+ x="750.45654"
+ y="230.05098"
+ id="tspan3690">FRSH Contract Broker Agent</tspan><tspan
+ id="tspan3294"
+ sodipodi:role="line"
+ x="750.45654"
+ y="255.05098">(FCB)</tspan></text>
+ <g
+ transform="matrix(1,0,0,0.93850794,0,-120.31162)"
+ id="g2991"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="fill:#7f7f7f;fill-opacity:0.25098039000000000;stroke:none;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect2993"
+ width="989.138"
+ height="40.652828"
+ x="8.7381992"
+ y="-313.64276"
+ transform="scale(1,-1)" />
+ <text
+ id="text2995"
+ y="57.471245"
+ x="-293.37494"
+ style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10"
+ xml:space="preserve"
+ transform="matrix(0,-1,1,0,0,0)"><tspan
+ id="tspan2997"
+ y="57.471245"
+ x="-293.37494"
+ sodipodi:role="line">API</tspan></text>
+ </g>
+ <g
+ id="g3378"
+ transform="matrix(1,0,0,-1.0030347,40,636.07201)"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:cmr10;-inkscape-font-specification:cmr10">
+ <g
+ id="g2537"
+ transform="matrix(0.2445503,0,0,6.6105265,374.6211,-325.97454)"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:cmr10;-inkscape-font-specification:cmr10">
+ <rect
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#92dd00;fill-opacity:1;stroke:#000000;stroke-width:0.88691992;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;font-family:cmr10;-inkscape-font-specification:cmr10"
+ id="rect2530"
+ width="141.37917"
+ height="79.947182"
+ x="148.90085"
+ y="58.0858" />
+ </g>
+ <text
+ transform="matrix(0,1,1,0,0,0)"
+ id="text3345"
+ y="434.62158"
+ x="210.31944"
+ style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10"
+ xml:space="preserve"><tspan
+ id="tspan3351"
+ y="434.62158"
+ x="210.31944"
+ sodipodi:role="line">OS Kernel/Resource Schedulers</tspan></text>
+ </g>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="m 590.42493,237.8928 -162.22842,0"
+ id="path6434"
+ sodipodi:nodetypes="cc" />
+ <g
+ transform="translate(520,-300.0724)"
+ id="g3284"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <text
+ id="text3288"
+ y="463.61404"
+ x="235.1579"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#727272;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ y="463.61404"
+ x="235.1579"
+ id="tspan3290"
+ sodipodi:role="line"
+ style="font-size:18px;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">FRSH API</tspan></text>
+ </g>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2.99999976000000013;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="m 670,112.5481 0,83.33737"
+ id="path6436" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:2.99999976000000013;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="m 840,112.5481 0,83.33737"
+ id="path6438" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ x="734.28412"
+ y="378.62662"
+ id="text6440"><tspan
+ sodipodi:role="line"
+ id="tspan6442"
+ x="734.28412"
+ y="378.62662">Resource</tspan><tspan
+ sodipodi:role="line"
+ x="734.28412"
+ y="403.62662"
+ id="tspan6444">Manager</tspan><tspan
+ sodipodi:role="line"
+ x="734.28412"
+ y="428.62662"
+ id="tspan6446">[CPU]</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ x="854.08392"
+ y="378.86447"
+ id="text6456"><tspan
+ sodipodi:role="line"
+ id="tspan6458"
+ x="854.08392"
+ y="378.86447">Resource</tspan><tspan
+ sodipodi:role="line"
+ x="854.08392"
+ y="403.86447"
+ id="tspan6460">Allocator</tspan><tspan
+ sodipodi:role="line"
+ x="854.08392"
+ y="428.86447"
+ id="tspan6462">[CPU]</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#0000ff;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ x="854.08392"
+ y="520.01935"
+ id="text6464"><tspan
+ sodipodi:role="line"
+ id="tspan6466"
+ x="854.08392"
+ y="520.01935">Resource</tspan><tspan
+ sodipodi:role="line"
+ x="854.08392"
+ y="545.01935"
+ id="tspan6468">Allocator</tspan><tspan
+ sodipodi:role="line"
+ x="854.08392"
+ y="570.01935"
+ id="tspan6470">[Network]</tspan></text>
+ <path
+ id="path6472"
+ d="m 670,277.8928 0,50 190,0 0,30"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#Arrow1Mend);-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ sodipodi:nodetypes="cccc" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path6474"
+ d="m 630,277.8928 0,190 230,0 0,30"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#Arrow1Mend);-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ id="text6482"
+ y="614.17255"
+ x="138.25345"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ y="614.17255"
+ x="138.25345"
+ id="tspan6484"
+ sodipodi:role="line">Node 1</tspan></text>
+ <text
+ id="text6486"
+ y="612.53638"
+ x="607.83942"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ y="612.53638"
+ x="607.83942"
+ id="tspan6488"
+ sodipodi:role="line">Node 2</tspan></text>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="M 119.32585,649.87501 L 180.67416,649.87501"
+ id="path6490" />
+ <text
+ id="text6492"
+ y="652.36639"
+ x="196.57716"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:cmr10;-inkscape-font-specification:cmr10;font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ y="652.36639"
+ x="196.57716"
+ id="tspan6494"
+ sodipodi:role="line" /></text>
+ <text
+ id="text6496"
+ y="657.15527"
+ x="200.43163"
+ style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10"
+ xml:space="preserve"><tspan
+ y="657.15527"
+ x="200.43163"
+ id="tspan6498"
+ sodipodi:role="line">Communication during negotiation</tspan></text>
+ <path
+ id="path5310"
+ d="m 170,277.8928 0,120 30,0"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ sodipodi:nodetypes="ccc" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path5312"
+ d="m 130,277.8928 0,260 70,0"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1.93676317000000009;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="m 424.06364,538.279 31.43053,0"
+ id="path3400"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path3402"
+ d="m 424.06364,397.02182 31.43053,0"
+ style="fill:none;stroke:#000000;stroke-width:1.93676317000000009;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <path
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:none;stroke:#000000;stroke-width:1.93676317;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);font-family:cmr10;-inkscape-font-specification:cmr10"
+ d="m 424.06364,80.383072 31.43053,0"
+ id="path3404"
+ sodipodi:nodetypes="cc" />
+ <g
+ id="g3314"
+ transform="matrix(1,0,0,-1,517.7855,635.8928)"
+ style="-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <g
+ transform="matrix(0.2445503,0,0,6.6305874,374.6211,-327.14298)"
+ id="g3316"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:cmr10;-inkscape-font-specification:cmr10">
+ <rect
+ y="58.0858"
+ x="148.90085"
+ height="79.947182"
+ width="141.37917"
+ id="rect3318"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#92dd00;fill-opacity:1;stroke:#000000;stroke-width:0.88691998;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;font-family:cmr10;-inkscape-font-specification:cmr10" />
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:cmr10;-inkscape-font-specification:cmr10"
+ x="210.31944"
+ y="434.62158"
+ id="text3320"
+ transform="matrix(0,1,1,0,0,0)"><tspan
+ sodipodi:role="line"
+ x="210.31944"
+ y="434.62158"
+ id="tspan3322">OS Kernel/Resource Schedulers</tspan></text>
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path3406"
+ d="m 903.61727,80.383072 31.43053,0"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:none;stroke:#000000;stroke-width:1.93676317;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);font-family:cmr10;-inkscape-font-specification:cmr10" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1.93676317000000009;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="m 903.61727,394.83179 31.43053,0"
+ id="path3408"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path3410"
+ d="m 903.61727,539.37402 31.43053,0"
+ style="fill:none;stroke:#000000;stroke-width:1.93676317000000009;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);-inkscape-font-specification:cmr10;font-family:cmr10;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ </g>
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2383"
+ sodipodi:version="0.32"
+ inkscape:version="0.47 r22583"
+ sodipodi:docname="negotiation-compact.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ version="1.0"
+ inkscape:export-filename="/home/wsh/frescor/doc/prezentations/contract-flow.png"
+ inkscape:export-xdpi="120"
+ inkscape:export-ydpi="120">
+ <defs
+ id="defs2385">
+ <marker
+ inkscape:stockid="Arrow1Sstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Sstart"
+ style="overflow:visible">
+ <path
+ id="path3403"
+ d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="matrix(0.2,0,0,0.2,1.2,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mstart"
+ style="overflow:visible">
+ <path
+ id="path3978"
+ d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="matrix(0.4,0,0,0.4,4,0)" />
+ </marker>
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 372.04724 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1052.3622 : 372.04724 : 1"
+ inkscape:persp3d-origin="526.18109 : 248.03149 : 1"
+ id="perspective2543" />
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mend"
+ style="overflow:visible">
+ <path
+ id="path4099"
+ d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="matrix(-0.4,0,0,-0.4,-4,0)" />
+ </marker>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.8252452"
+ inkscape:cx="367.86547"
+ inkscape:cy="732.15523"
+ inkscape:current-layer="layer2"
+ inkscape:document-units="px"
+ showgrid="false"
+ inkscape:window-width="1280"
+ inkscape:window-height="972"
+ inkscape:window-x="1680"
+ inkscape:window-y="0"
+ inkscape:object-paths="false"
+ inkscape:object-nodes="true"
+ objecttolerance="10000"
+ gridtolerance="10000"
+ guidetolerance="2"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-nodes="false"
+ showborder="true"
+ inkscape:connector-spacing="3"
+ units="cm"
+ borderlayer="false"
+ inkscape:snap-intersection-line-segments="true"
+ inkscape:snap-intersection-grid-guide="false"
+ inkscape:snap-center="true"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="false"
+ inkscape:bbox-nodes="false"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata2388">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ id="layer2"
+ inkscape:label="Contract flow"
+ style="display:inline"
+ transform="translate(-58.52032,-298.67903)">
+ <g
+ id="g3427"
+ transform="matrix(0.5954538,0,0,0.5954538,76.961864,150.61355)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ y="759.51843"
+ x="376.33038"
+ height="200.26648"
+ width="362.63376"
+ id="rect3505"
+ style="fill:#e6e6e6;fill-opacity:1;stroke:#000000;stroke-width:0.80000000999999998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ id="text3507"
+ y="773.81683"
+ x="561.25555"
+ style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,'"
+ xml:space="preserve"><tspan
+ style="font-size:12.80000019000000044px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,'"
+ y="773.81683"
+ x="561.25555"
+ id="tspan3509"
+ sodipodi:role="line">Application address space</tspan></text>
+ </g>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.47636308999999999px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="M 483.2095,715.5924 C 483.2095,750.20134 678.25615,749.2008 678.25615,714.6161"
+ id="path4261"
+ inkscape:connector-type="polyline"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.47636308999999999px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="M 506.10646,497.72189 L 537.63452,497.8978"
+ id="path4320"
+ inkscape:connector-type="polyline"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.47636308999999999px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="M 316.8469,496.20015 L 290.4941,496.11537"
+ id="path4318"
+ inkscape:connector-type="polyline"
+ inkscape:connection-start="#g3390"
+ sodipodi:nodetypes="cc" />
+ <text
+ xml:space="preserve"
+ style="font-size:9.52726172999999932px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="-556.86121"
+ y="322.73178"
+ id="text3481"
+ transform="matrix(0,-1,1,0,0,0)"><tspan
+ sodipodi:role="line"
+ id="tspan3483"
+ x="-556.86121"
+ y="322.73178"
+ style="font-size:7.62180947999999869px;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">2. negotiate_contract()</tspan></text>
+ <g
+ id="g4013"
+ transform="matrix(0.4763631,0,0,0.4763631,327.4978,400.92868)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ y="305.53189"
+ x="424.65244"
+ height="274.74731"
+ width="211.34297"
+ id="rect3553"
+ style="fill:#ffc0c0;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <g
+ id="g3333"
+ transform="translate(0,-194.88188)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="fill:#5599ff;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect2517"
+ width="189.63651"
+ height="34.305229"
+ x="437.48056"
+ y="535.75897" />
+ <text
+ id="text3313"
+ y="560.36761"
+ x="532.32324"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ y="560.36761"
+ x="532.32324"
+ id="tspan3315"
+ sodipodi:role="line">Global contract ID</tspan></text>
+ </g>
+ <g
+ id="g2611"
+ transform="matrix(1.005391,0,0,1,-2.3585736,8.081283)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3571"
+ width="188.35999"
+ height="34.305229"
+ x="437.49869"
+ y="373.50946" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="531.39551"
+ y="394.80029"
+ id="text3573"><tspan
+ id="tspan3575"
+ sodipodi:role="line"
+ x="531.39551"
+ y="394.80029">Basic params A</tspan></text>
+ </g>
+ <g
+ id="g2616"
+ transform="translate(0,4.5352319)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ y="417.76917"
+ x="437.48056"
+ height="34.305229"
+ width="189.63651"
+ id="rect3585"
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ id="text3587"
+ y="439.91254"
+ x="532.40625"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ id="tspan3589"
+ y="439.91254"
+ x="532.40625"
+ sodipodi:role="line">Timing reqs. A</tspan><tspan
+ id="tspan3591"
+ y="464.91254"
+ x="532.40625"
+ sodipodi:role="line" /></text>
+ </g>
+ <g
+ id="g2622"
+ transform="translate(0,42.5197)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3595"
+ width="189.63651"
+ height="65.525719"
+ x="437.48056"
+ y="461.21204" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="531.94727"
+ y="486.99249"
+ id="text3597"><tspan
+ sodipodi:role="line"
+ id="tspan3599"
+ x="531.94727"
+ y="486.99249">Resource specific</tspan><tspan
+ sodipodi:role="line"
+ x="531.94727"
+ y="511.99249"
+ id="tspan3601">parameters</tspan></text>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="747.26892"
+ y="541.07788"
+ id="text3329"
+ transform="translate(-152.74315,9.39647)"><tspan
+ sodipodi:role="line"
+ id="tspan3331"
+ x="747.26892"
+ y="541.07788" /></text>
+ <text
+ xml:space="preserve"
+ style="font-size:15.90077018999999936px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="436.09311"
+ y="327.21503"
+ id="text2620"><tspan
+ sodipodi:role="line"
+ id="tspan2622"
+ x="436.09311"
+ y="327.21503">Reservation contract (3)</tspan></text>
+ <g
+ transform="translate(0,45.248885)"
+ id="g3460"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3462"
+ width="189.63651"
+ height="34.305229"
+ x="437.48056"
+ y="417.76917" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="532.40625"
+ y="439.91254"
+ id="text3464"><tspan
+ sodipodi:role="line"
+ x="532.40625"
+ y="439.91254"
+ id="tspan3468">Spare capacity p.</tspan></text>
+ </g>
+ <rect
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3456"
+ width="188.96213"
+ height="187.66902"
+ x="437.49866"
+ y="381.58847" />
+ </g>
+ <g
+ id="g4037"
+ transform="matrix(0.4763631,0,0,0.4763631,320.96455,349.39121)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="fill:#ffc0c0;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3913"
+ width="213.33945"
+ height="354.60593"
+ x="684.65247"
+ y="334.42914" />
+ <text
+ xml:space="preserve"
+ style="font-size:15.60244750999999930px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="696.33472"
+ y="360.93271"
+ id="text3915"><tspan
+ sodipodi:role="line"
+ id="tspan3917"
+ x="696.33472"
+ y="360.93271">Schedulable contract (4)</tspan></text>
+ <g
+ id="g3323"
+ transform="translate(0,79.544194)"
+ style="stroke:#000000;stroke-width:0.50000000000000000;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="fill:#ffcc00;fill-opacity:0.71428575999999999;stroke:#000000;stroke-width:0.50000000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3957"
+ width="188.37726"
+ height="65.525719"
+ x="697.48059"
+ y="533.21204" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.50000000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="791.25415"
+ y="558.99249"
+ id="text3959"><tspan
+ sodipodi:role="line"
+ x="791.25415"
+ y="558.99249"
+ id="tspan3963">Scheduling</tspan><tspan
+ sodipodi:role="line"
+ x="791.25415"
+ y="583.99249"
+ id="tspan3967">parameters</tspan></text>
+ </g>
+ <g
+ style="display:inline;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="g3472"
+ transform="translate(259.88268,-157.07189)">
+ <rect
+ style="fill:#5599ff;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3474"
+ width="189.63651"
+ height="34.305229"
+ x="437.48056"
+ y="535.75897" />
+ <text
+ id="text3476"
+ y="560.36761"
+ x="532.32324"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ y="560.36761"
+ x="532.32324"
+ id="tspan3478"
+ sodipodi:role="line">Global contract ID</tspan></text>
+ </g>
+ <g
+ style="display:inline;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="g3480"
+ transform="matrix(1.005391,0,0,1,257.5241,45.891266)">
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3482"
+ width="188.35999"
+ height="34.305229"
+ x="437.49869"
+ y="373.50946" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="531.39551"
+ y="394.80029"
+ id="text3484"><tspan
+ id="tspan3486"
+ sodipodi:role="line"
+ x="531.39551"
+ y="394.80029">Basic params A</tspan></text>
+ </g>
+ <g
+ style="display:inline;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="g3488"
+ transform="translate(259.88268,42.345216)">
+ <rect
+ y="417.76917"
+ x="437.48056"
+ height="34.305229"
+ width="189.63651"
+ id="rect3490"
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ id="text3492"
+ y="439.91254"
+ x="532.40625"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ id="tspan3494"
+ y="439.91254"
+ x="532.40625"
+ sodipodi:role="line">Timing reqs. A</tspan><tspan
+ id="tspan3496"
+ y="464.91254"
+ x="532.40625"
+ sodipodi:role="line" /></text>
+ </g>
+ <g
+ style="display:inline;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="g3498"
+ transform="translate(259.88268,80.329696)">
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3500"
+ width="189.63651"
+ height="65.525719"
+ x="437.48056"
+ y="461.21204" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="531.94727"
+ y="486.99249"
+ id="text3502"><tspan
+ sodipodi:role="line"
+ id="tspan3504"
+ x="531.94727"
+ y="486.99249">Resource specific</tspan><tspan
+ sodipodi:role="line"
+ x="531.94727"
+ y="511.99249"
+ id="tspan3506">parameters</tspan></text>
+ </g>
+ <g
+ style="display:inline;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ transform="translate(259.88268,83.058866)"
+ id="g3508">
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3510"
+ width="189.63651"
+ height="34.305229"
+ x="437.48056"
+ y="417.76917" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="532.40625"
+ y="439.91254"
+ id="text3512"><tspan
+ sodipodi:role="line"
+ x="532.40625"
+ y="439.91254"
+ id="tspan3514">Spare capacity p.</tspan></text>
+ </g>
+ <rect
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3458"
+ width="188.4765"
+ height="258.83881"
+ x="697.38135"
+ y="419.40076" />
+ </g>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.42908930999999995;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:8.57453555000000023, 1.42908925000000009;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="M 330.04602,625.19606 L 330.04602,510.13004"
+ id="path4065"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.42908943000000010;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="M 359.54326,702.46863 L 452.47718,702.46863"
+ id="path2548" />
+ <g
+ id="g3373"
+ transform="matrix(0.4763631,0,0,0.4763631,362.27455,420.76288)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:#000000;stroke-width:1.99999988000000006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect5280"
+ width="127.94772"
+ height="57.947727"
+ x="-111.62925"
+ y="560.96991" />
+ <text
+ id="text5388"
+ y="595.46136"
+ x="-102.25348"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ y="595.46136"
+ x="-102.25348"
+ id="tspan5390"
+ sodipodi:role="line">Application</tspan></text>
+ </g>
+ <path
+ id="path5392"
+ d="M 359.54326,493.41506 L 452.47718,493.41506"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.42908930999999995;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:8.57453557999999916, 1.42908926000000003;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.42908930999999995;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:8.57453568999999938, 1.42908926999999997;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="M 343.36819,510.42154 L 343.36819,622.68001"
+ id="path3413"
+ sodipodi:nodetypes="cc" />
+ <g
+ id="g3390"
+ transform="matrix(0.4763631,0,0,0.4763631,145.25374,215.24581)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ y="560.96991"
+ x="361.21506"
+ height="57.947727"
+ width="93.416237"
+ id="rect5272"
+ style="fill:#5599ff;fill-opacity:1;stroke:#000000;stroke-width:1.99999975999999990;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="407.6058"
+ y="584.72406"
+ id="text5394"><tspan
+ sodipodi:role="line"
+ id="tspan5396"
+ x="407.6058"
+ y="584.72406">Contract</tspan><tspan
+ sodipodi:role="line"
+ x="407.6058"
+ y="609.72406"
+ id="tspan3523">Broker</tspan></text>
+ </g>
+ <g
+ style="display:inline;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="g3425"
+ transform="matrix(0.4763631,0,0,0.4763631,25.525213,544.62735)">
+ <g
+ transform="translate(250.45708,-530.3578)"
+ style="display:inline;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="g3465">
+ <rect
+ style="fill:#5599ff;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3467"
+ width="229.64906"
+ height="34.305229"
+ x="430.49289"
+ y="535.75897" />
+ <text
+ id="text3469"
+ y="559.19086"
+ x="545.62018"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ y="559.19086"
+ x="545.62018"
+ id="tspan3471"
+ sodipodi:role="line">Global contract ID (5)</tspan></text>
+ </g>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-size:7.62180947999999869px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="408.68024"
+ y="488.01498"
+ id="text3485"><tspan
+ sodipodi:role="line"
+ x="408.68024"
+ y="488.01498"
+ id="tspan3511">3. reserve(), commit()</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:9.52726172999999932px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="422.27255"
+ y="523.69208"
+ id="text3489"><tspan
+ sodipodi:role="line"
+ id="tspan3491"
+ x="422.27255"
+ y="523.69208"
+ style="font-size:7.62180947999999869px;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">4. change_vreses()</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:9.52726172999999932px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="406.25461"
+ y="501.40305"
+ id="text3493"><tspan
+ sodipodi:role="line"
+ id="tspan3495"
+ x="406.25461"
+ y="501.40305"
+ style="font-size:7.62180947999999869px;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">return</tspan></text>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.42908930999999995;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:8.57453557999999916, 1.42908926000000003;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="M 457.39999,503.9605 L 366.70714,503.9605 C 349.09843,503.9605 349.76964,526.25788 365.92299,526.25788 L 487.1958,526.25788 C 496.52274,526.25788 503.75825,533.10997 503.75825,545.0135 L 503.75825,684.45307"
+ id="path5398"
+ sodipodi:nodetypes="czzczs" />
+ <g
+ id="g3406"
+ transform="matrix(0.4763631,0,0,0.4763631,142.65481,215.24581)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ y="560.96991"
+ x="656.11176"
+ height="57.947727"
+ width="109.46667"
+ id="rect5284"
+ style="fill:#ffcc00;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ id="text5400"
+ y="582.65375"
+ x="663.74652"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ y="582.65375"
+ x="663.74652"
+ id="tspan5402"
+ sodipodi:role="line">Resource</tspan><tspan
+ id="tspan5404"
+ y="607.65375"
+ x="663.74652"
+ sodipodi:role="line">Manager</tspan></text>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-size:9.52726172999999932px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="-553.63196"
+ y="340.21844"
+ id="text4245"
+ transform="matrix(0,-1,1,0,0,0)"
+ inkscape:transform-center-x="-317.0049"
+ inkscape:transform-center-y="3.2899481"><tspan
+ sodipodi:role="line"
+ id="tspan4247"
+ x="-553.63196"
+ y="340.21844"
+ style="font-size:7.62180947999999869px;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">5. return</tspan></text>
+ <g
+ transform="matrix(0.3607983,0,0,0.3607983,189.68291,617.78923)"
+ id="g2550"
+ style="display:inline;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <g
+ id="g2552"
+ style="display:inline;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ transform="translate(230.65252,-527.05704)">
+ <rect
+ y="535.75897"
+ x="452.6459"
+ height="34.305229"
+ width="177.30452"
+ id="rect2554"
+ style="fill:#5599ff;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="541.60089"
+ y="559.18109"
+ id="text2556"><tspan
+ sodipodi:role="line"
+ id="tspan2558"
+ x="541.60089"
+ y="559.18109">G. contract ID (6)</tspan></text>
+ </g>
+ </g>
+ <text
+ id="text2560"
+ y="697.48553"
+ x="410.1301"
+ style="font-size:9.52726172999999932px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,'"
+ xml:space="preserve"><tspan
+ style="font-size:7.62180947999999958px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,'"
+ y="697.48553"
+ x="410.1301"
+ id="tspan2562"
+ sodipodi:role="line">8. frsh_XXX_bind()</tspan></text>
+ <g
+ transform="matrix(0.4763631,0,0,0.4763631,362.27455,357.44204)"
+ id="g2573"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ y="560.96991"
+ x="-111.62925"
+ height="57.947727"
+ width="127.94772"
+ id="rect2575"
+ style="fill:#afafaf;fill-opacity:1;stroke:#000000;stroke-width:1.99999988000000006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="-103.43176"
+ y="582.86591"
+ id="text2577"><tspan
+ sodipodi:role="line"
+ id="tspan2579"
+ x="-103.43176"
+ y="582.86591">FRSH/FRES</tspan><tspan
+ sodipodi:role="line"
+ x="-103.43176"
+ y="607.86591"
+ id="tspan3521">library</tspan></text>
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path3357"
+ d="M 330.04602,687.66345 L 330.04602,654.11871"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.42908930999999995;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <path
+ id="path3363"
+ d="M 369.95492,635.36686 L 470.75974,635.63787 C 484.11795,635.67378 491.23141,639.45009 491.23151,655.6582 L 491.23168,684.31307"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.42908943000000010;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ sodipodi:nodetypes="czzc" />
+ <text
+ xml:space="preserve"
+ style="font-size:9.52726172999999932px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,'"
+ x="404.52786"
+ y="631.53864"
+ id="text3367"><tspan
+ sodipodi:role="line"
+ id="tspan3370"
+ x="404.52786"
+ y="631.53864"
+ style="font-size:7.62180947999999958px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,'">6. get_vres_id()</tspan></text>
+ <g
+ transform="matrix(0.3810905,0,0,0.3810905,-20.22729,446.44756)"
+ id="g3372"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ y="560.96991"
+ x="973.93732"
+ height="32.448402"
+ width="142.25151"
+ id="rect3374"
+ style="fill:#fff6d5;fill-opacity:1;stroke:#000000;stroke-width:1.25000000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ id="text3376"
+ y="584.59222"
+ x="981.74658"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ id="tspan3383"
+ y="584.59222"
+ x="981.74658"
+ sodipodi:role="line">VRes ID (ptr)</tspan></text>
+ </g>
+ <use
+ x="0"
+ y="0"
+ xlink:href="#g3372"
+ id="use3415"
+ transform="translate(29.523691,45.928408)"
+ width="1052.3622"
+ height="744.09448"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ transform="matrix(0,-1,1,0,0,0)"
+ id="text3417"
+ y="322.73178"
+ x="-670.06396"
+ style="font-size:9.52726172999999932px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ style="font-size:7.62180947999999869px;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ y="322.73178"
+ x="-670.06396"
+ id="tspan3420"
+ sodipodi:role="line">1.</tspan></text>
+ <path
+ sodipodi:nodetypes="cszzzc"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.42908955000000004;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Mstart);marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="M 344.64882,685.68987 C 344.64882,669.16434 345.18789,700.59065 345.18789,651.15483 C 345.18789,644.50636 345.60277,644.65891 352.20187,644.66925 L 462.75154,644.84261 C 475.04856,644.86189 481.59693,647.95056 481.59699,661.16448 L 481.59714,690.59927"
+ id="path3432" />
+ <g
+ id="g3355"
+ transform="matrix(0.4763631,0,0,0.4763631,-7.5546504,420.76288)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="fill:#fff6d5;fill-opacity:1;stroke:#ffcc00;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect5306"
+ width="109.46667"
+ height="57.947727"
+ x="973.93732"
+ y="560.96991" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="981.74658"
+ y="584.59222"
+ id="text5408"><tspan
+ sodipodi:role="line"
+ id="tspan5410"
+ x="981.74658"
+ y="584.59222">Resource</tspan><tspan
+ sodipodi:role="line"
+ x="981.74658"
+ y="609.59222"
+ id="tspan5412">Allocator</tspan></text>
+ </g>
+ <text
+ id="text4753"
+ y="642.81793"
+ x="391.36038"
+ style="font-size:9.52726172999999932px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ style="font-size:7.62180947999999869px;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ y="642.81793"
+ x="391.36038"
+ id="tspan4755"
+ sodipodi:role="line">7. return</tspan></text>
+ <g
+ transform="matrix(0.4763631,0,0,0.4763631,86.926338,420.76288)"
+ id="g2594"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#92dd00;fill-opacity:1;stroke:#000000;stroke-width:1.99999988000000006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,'"
+ id="rect3104"
+ width="107.16644"
+ height="64.848404"
+ x="972.78717"
+ y="559.81976" />
+ <text
+ id="text2598"
+ y="584.72406"
+ x="1028.0212"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ id="tspan2602"
+ y="584.72406"
+ x="1028.0212"
+ sodipodi:role="line">Resource</tspan><tspan
+ y="609.72406"
+ x="1028.0212"
+ sodipodi:role="line"
+ id="tspan2606">Scheduler</tspan></text>
+ </g>
+ <g
+ id="g3501"
+ transform="translate(12.107325,-18.786453)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <g
+ transform="matrix(1.0741238,0,0,1.0741238,-92.503899,-62.038615)"
+ id="g3489"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.33046985000000006;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:7.98281936999999875, 1.33046989999999998;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="M 213.53652,774.75731 L 248.1864,774.75731"
+ id="path3340" />
+ <text
+ xml:space="preserve"
+ style="font-size:8.86979866000000072px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="259.10632"
+ y="778.06403"
+ id="text3349"><tspan
+ sodipodi:role="line"
+ id="tspan3351"
+ x="259.10632"
+ y="778.06403">FORB invocation</tspan></text>
+ </g>
+ <g
+ transform="matrix(1.0741238,0,0,1.0741238,55.978984,-77.503795)"
+ id="g3484"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <path
+ id="path3342"
+ d="M 213.87154,789.15531 L 247.54476,789.15531"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.33046997000000000;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ xml:space="preserve"
+ style="font-size:8.86979866000000072px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="259.10632"
+ y="792.46198"
+ id="text3357"><tspan
+ sodipodi:role="line"
+ id="tspan3359"
+ x="259.10632"
+ y="792.46198">Local invocation</tspan></text>
+ </g>
+ <text
+ id="text3361"
+ y="772.77502"
+ x="91.289024"
+ style="font-size:9.52726172999999932px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ y="772.77502"
+ x="91.289024"
+ id="tspan3363"
+ sodipodi:role="line">Legend:</tspan></text>
+ <g
+ transform="matrix(1.0741238,0,0,1.0741238,203.01043,-93.699715)"
+ id="g3477"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.33046997000000000;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:1.33046997999999994, 1.33046997999999994;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="M 213.87154,804.23356 L 247.54476,804.23356"
+ id="path4957" />
+ <text
+ id="text4959"
+ y="806.68054"
+ x="259.10632"
+ style="font-size:8.86979866000000072px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ y="806.68054"
+ x="259.10632"
+ sodipodi:role="line"
+ id="tspan4969">System call or other resource specific communication</tspan></text>
+ </g>
+ </g>
+ <g
+ id="g2646"
+ transform="matrix(1.0741238,0,0,1.0741238,-26.000656,-15.297279)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <g
+ transform="matrix(0.4434899,0,0,0.4434899,140.52427,361.25256)"
+ id="g3969"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ y="334.42914"
+ x="24.652443"
+ height="436.59048"
+ width="330.51944"
+ id="rect3260"
+ style="fill:#ffc0c0;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3525"
+ width="297.75656"
+ height="56.853191"
+ x="37.179413"
+ y="414.17316" />
+ <rect
+ style="opacity:1;fill:#ff5b5b;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3337"
+ width="297.75662"
+ height="207.17691"
+ x="37.179413"
+ y="477.86197" />
+ <text
+ id="text3262"
+ y="360.68256"
+ x="39.372852"
+ style="font-size:17.50000000000000000px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ y="360.68256"
+ x="39.372852"
+ id="tspan3264"
+ sodipodi:role="line">User contract (1, 2)</tspan></text>
+ <g
+ id="g3400"
+ transform="translate(-64,24)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ y="513.60602"
+ x="112.74278"
+ height="128.1606"
+ width="133.94228"
+ id="rect3394"
+ style="opacity:1;fill:#ffc0c0;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ id="text3396"
+ y="530.95105"
+ x="145.58307"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ style="font-size:15px;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ y="530.95105"
+ x="145.58307"
+ id="tspan3398"
+ sodipodi:role="line">Variant A</tspan></text>
+ </g>
+ <rect
+ y="572.97998"
+ x="57.890869"
+ height="34.305229"
+ width="115.63361"
+ id="rect3266"
+ style="fill:#ff5b5b;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ id="text3268"
+ y="594.27081"
+ x="115.03018"
+ style="font-size:15px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ y="594.27081"
+ x="115.03018"
+ sodipodi:role="line"
+ id="tspan3372">Basic params A</tspan></text>
+ <text
+ id="text3272"
+ y="446.84567"
+ x="41.997498"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ style="font-size:14px;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="tspan3276"
+ y="446.84567"
+ x="41.997498"
+ sodipodi:role="line">resource_type</tspan><tspan
+ style="font-size:14px;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="tspan3278"
+ y="464.34567"
+ x="41.997498"
+ sodipodi:role="line">resource_id</tspan></text>
+ <rect
+ style="fill:#ff5b5b;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3282"
+ width="115.63361"
+ height="34.305229"
+ x="57.070892"
+ y="617.23969" />
+ <text
+ xml:space="preserve"
+ style="font-size:15px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="114.96826"
+ y="639.38306"
+ id="text3284"><tspan
+ sodipodi:role="line"
+ x="114.96826"
+ y="639.38306"
+ id="tspan3382">Timing reqs. A</tspan><tspan
+ sodipodi:role="line"
+ x="114.96826"
+ y="658.13306"
+ id="tspan3384" /></text>
+ <g
+ id="g3421"
+ transform="translate(-64,4)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="fill:#ff5b5b;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3290"
+ width="297.75656"
+ height="65.525719"
+ x="101.17941"
+ y="688.48181" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="249.70613"
+ y="714.26227"
+ id="text3292"><tspan
+ sodipodi:role="line"
+ id="tspan3294"
+ x="249.70613"
+ y="714.26227">Resource specific</tspan><tspan
+ sodipodi:role="line"
+ x="249.70613"
+ y="739.26227"
+ id="tspan3296">parameters</tspan></text>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="70.64624"
+ y="498.77039"
+ id="text3339"><tspan
+ sodipodi:role="line"
+ id="tspan3341"
+ x="70.64624"
+ y="498.77039">Spare capacity params</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="53.560852"
+ y="520.47931"
+ id="text3348"><tspan
+ sodipodi:role="line"
+ id="tspan3350"
+ x="53.560852"
+ y="520.47931"
+ style="font-size:15px;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">discrete</tspan></text>
+ <g
+ id="g3405"
+ transform="translate(76,24)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="opacity:1;fill:#ffc0c0;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3407"
+ width="133.94228"
+ height="128.1606"
+ x="112.74278"
+ y="513.60602" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="145.58307"
+ y="530.95105"
+ id="text3409"><tspan
+ sodipodi:role="line"
+ id="tspan3411"
+ x="145.58307"
+ y="530.95105"
+ style="font-size:15px;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">Variant B</tspan></text>
+ </g>
+ <rect
+ style="fill:#ff5b5b;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect3360"
+ width="115.63361"
+ height="34.305229"
+ x="195.92944"
+ y="572.93213" />
+ <text
+ xml:space="preserve"
+ style="font-size:15px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="253.53751"
+ y="594.27081"
+ id="text3362"><tspan
+ sodipodi:role="line"
+ x="253.53751"
+ y="594.27081"
+ id="tspan3376">Basic params B</tspan></text>
+ <rect
+ y="618.09229"
+ x="195.08798"
+ height="34.305229"
+ width="115.63361"
+ id="rect3366"
+ style="fill:#ff5b5b;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ id="text3368"
+ y="639.38306"
+ x="253.4541"
+ style="font-size:15px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ y="639.38306"
+ x="253.4541"
+ sodipodi:role="line"
+ id="tspan3378">Timing reqs. B</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="183.70613"
+ y="436.26227"
+ id="text3527"><tspan
+ sodipodi:role="line"
+ x="183.70613"
+ y="436.26227"
+ id="tspan3531">Resource</tspan></text>
+ <rect
+ y="373.7507"
+ x="37.179413"
+ height="33.910725"
+ width="297.75656"
+ id="rect3317"
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <text
+ id="text3319"
+ y="398.16211"
+ x="186.12117"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><tspan
+ y="398.16211"
+ x="186.12117"
+ id="tspan3321"
+ sodipodi:role="line">User Label</tspan></text>
+ <rect
+ y="373.74121"
+ x="37.165554"
+ height="384.27328"
+ width="297.7424"
+ id="rect2666"
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ </g>
+ <text
+ transform="matrix(0,-1,1,0,0,0)"
+ xml:space="preserve"
+ style="font-size:8.86979866000000072px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="-649.34003"
+ y="127.1926"
+ id="text2603"><tspan
+ sodipodi:role="line"
+ id="tspan2605"
+ x="-649.34003"
+ y="127.1926">Contract blocks</tspan></text>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path2609"
+ d="M 157.01296,537.20224 L 130.44192,611.93306"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.55436242000000002;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Mstart);marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path2611"
+ d="m 157.01296,614.27945 -26.54745,-2.28727"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.55393987000000000;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Mstart);marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.55436242000000002;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Mstart);marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="M 156.92224,678.28967 L 130.42787,611.89784"
+ id="path11031"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.55436242000000002;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Mstart);marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ d="M 156.86722,561.32573 L 130.42787,611.95998"
+ id="path11033"
+ sodipodi:nodetypes="cc" />
+ </g>
+ <g
+ id="g3407"
+ transform="matrix(1.0741238,0,0,1.0741238,-26.795674,-44.019516)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <g
+ transform="matrix(0.4434899,0,0,0.4434899,125.32407,247.8848)"
+ id="g4282"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.90854108000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect4253"
+ width="325.08121"
+ height="81.66011"
+ x="66.632133"
+ y="547.97308"
+ ry="0"
+ rx="0" />
+ <flowRoot
+ xml:space="preserve"
+ id="flowRoot3073"
+ style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,'"
+ transform="matrix(2.0992392,0,0,2.0992392,-29.686109,330.30941)"><flowRegion
+ id="flowRegion3075"><rect
+ id="rect3077"
+ width="141.13908"
+ height="34.515854"
+ x="52.628136"
+ y="105.05572"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" /></flowRegion><flowPara
+ id="flowPara3079"
+ style="font-size:7px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,'">Negotiates contracts with formerly registered res. managers and schedulers</flowPara><flowPara
+ style="font-size:7px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,'"
+ id="flowPara3087">Rebalances transactions</flowPara><flowPara
+ style="font-size:7px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,'"
+ id="flowPara3089">Redistributes spare capacity</flowPara><flowPara
+ id="flowPara3081"
+ style="font-size:7px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,'" /><flowPara
+ id="flowPara3083"
+ style="font-size:7px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,'" /></flowRoot> </g>
+ <path
+ transform="translate(58.52032,298.67903)"
+ id="path2615"
+ d="M 235.01858,192.18843 L 240.56193,197.73177"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.40000001000000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ </g>
+ <g
+ id="g3431"
+ transform="matrix(1.0741238,0,0,1.0741238,-26.000656,-62.304953)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <g
+ transform="matrix(0.4434899,0,0,0.4434899,137.05888,225.00832)"
+ id="g4297"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ rx="0"
+ ry="0"
+ y="635.33441"
+ x="855.0788"
+ height="62.92033"
+ width="219.66969"
+ id="rect4255"
+ style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.88779538999999985;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ <flowRoot
+ transform="translate(-0.7312164,1.8877766)"
+ id="flowRoot2636"
+ style="font-size:15px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ xml:space="preserve"><flowRegion
+ id="flowRegion2638"><use
+ height="1052.3622"
+ width="744.09448"
+ id="use2640"
+ xlink:href="#rect4255"
+ y="0"
+ x="0" /></flowRegion><flowPara
+ id="flowPara2642">Executes admission test (schedulability analysis)</flowPara><flowPara
+ id="flowPara2644">Assigns priorities etc.</flowPara></flowRoot> </g>
+ <path
+ id="path3418"
+ d="M 607.87444,506.78658 L 613.41779,512.32992"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.40000001000000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ </g>
+ <g
+ id="g3422"
+ transform="matrix(1.0741238,0,0,1.0741238,-26.398165,-69.223313)"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <g
+ transform="matrix(0.4434899,0,0,0.4434899,329.31354,244.78855)"
+ id="g4292"
+ style="-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">
+ <rect
+ style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
+ id="rect4257"
+ width="278.76849"
+ height="60.381516"
+ x="606.09998"
+ y="1034.057"
+ ry="0"
+ rx="0" />
+ <text
+ xml:space="preserve"
+ style="font-size:15px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Times New Roman;-inkscape-font-specification:'Times New Roman,';font-stretch:normal;font-variant:normal"
+ x="745.43298"
+ y="1051.2797"
+ id="text3415"><tspan
+ sodipodi:role="line"
+ x="745.43298"
+ y="1051.2797"
+ id="tspan3419">Interface to resource scheduler</tspan><tspan
+ id="tspan4971"
+ sodipodi:role="line"
+ x="745.43298"
+ y="1070.0297">Responsible for creating/changing</tspan><tspan
+ id="tspan4977"
+ sodipodi:role="line"
+ x="745.43298"
+ y="1088.7797">virtual resources (VRES)</tspan></text>
+ </g>
+ <path
+ id="path3420"
+ d="M 715.91709,703.46442 L 721.46044,709.00776"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.40000001000000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ </g>
+ <path
+ id="path2610"
+ d="M 510.82952,702.46863 L 549.29635,702.46863"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.42908930999999995;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:1.42908923000000021, 1.42908923000000021;stroke-dashoffset:0;stroke-opacity:1;-inkscape-font-specification:'Times New Roman,';font-family:Times New Roman;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal" />
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="1052.3622"
+ height="744.09448"
+ id="svg2383"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docname="negotiation.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ version="1.0"
+ inkscape:export-filename="/home/wsh/frescor/doc/prezentations/contract-flow.png"
+ inkscape:export-xdpi="120"
+ inkscape:export-ydpi="120">
+ <defs
+ id="defs2385">
+ <marker
+ inkscape:stockid="Arrow1Sstart"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Sstart"
+ style="overflow:visible">
+ <path
+ id="path3403"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+ transform="scale(0.2) translate(6,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mstart"
+ style="overflow:visible">
+ <path
+ id="path3978"
+ d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="matrix(0.4,0,0,0.4,4,0)" />
+ </marker>
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 372.04724 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1052.3622 : 372.04724 : 1"
+ inkscape:persp3d-origin="526.18109 : 248.03149 : 1"
+ id="perspective2543" />
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mend"
+ style="overflow:visible">
+ <path
+ id="path4099"
+ d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="matrix(-0.4,0,0,-0.4,-4,0)" />
+ </marker>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.81845615"
+ inkscape:cx="526.1811"
+ inkscape:cy="378.51376"
+ inkscape:current-layer="layer2"
+ inkscape:document-units="px"
+ showgrid="false"
+ inkscape:window-width="1270"
+ inkscape:window-height="963"
+ inkscape:window-x="1682"
+ inkscape:window-y="0"
+ inkscape:object-paths="false"
+ inkscape:object-nodes="true"
+ objecttolerance="10000"
+ gridtolerance="10000"
+ guidetolerance="2"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-nodes="true"
+ showborder="true"
+ inkscape:connector-spacing="3"
+ units="cm"
+ borderlayer="false"
+ inkscape:snap-intersection-line-segments="true"
+ inkscape:snap-intersection-grid-guide="false"
+ inkscape:snap-center="true"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="false"
+ inkscape:bbox-nodes="false" />
+ <metadata
+ id="metadata2388">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ id="layer2"
+ inkscape:label="Contract flow"
+ style="display:inline"
+ transform="translate(-58.52032,-298.67903)">
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path2626"
+ d="M 571.20898,695.28325 L 560.23175,680.12009 L 571.20898,667.83906 L 571.20898,695.28325 z"
+ style="fill:#ececec;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:0;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" />
+ <path
+ style="fill:#ececec;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:0;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
+ d="M 477.54254,911.7526 L 537.85861,727.83495 L 477.54254,563.43876 L 477.54254,911.7526 z"
+ id="path3400"
+ sodipodi:nodetypes="cccc" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path3398"
+ d="M 869.15503,603.18356 L 829.58941,721.38487 L 869.15503,886.8683 L 869.15503,603.18356 z"
+ style="fill:#ececec;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:0;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" />
+ <path
+ style="fill:#ececec;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:0;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
+ d="M 594.99419,528.00887 L 672.84522,577.51265 L 764.06857,528.00887 L 594.99419,528.00887 z"
+ id="path2613"
+ sodipodi:nodetypes="cccc" />
+ <g
+ id="g3427"
+ transform="translate(112.83129,1.814797)">
+ <rect
+ y="759.51843"
+ x="376.33038"
+ height="200.26648"
+ width="362.63376"
+ id="rect3505"
+ style="fill:#e6e6e6;fill-opacity:1;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ id="text3507"
+ y="773.81683"
+ x="561.25555"
+ style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ style="font-size:12.80000019px"
+ y="773.81683"
+ x="561.25555"
+ id="tspan3509"
+ sodipodi:role="line">Application's address space</tspan></text>
+ </g>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 835.61819,564.41454 L 849.46814,526.34285"
+ id="path4320"
+ inkscape:connector-type="polyline" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="M 535.41028,558.33358 L 505.91644,519.99757"
+ id="path4318"
+ inkscape:connector-type="polyline"
+ inkscape:connection-start="#g3390" />
+ <text
+ xml:space="preserve"
+ style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans"
+ x="-684.0636"
+ y="525.57513"
+ id="text3481"
+ transform="matrix(0,-1,1,0,0,0)"><tspan
+ sodipodi:role="line"
+ id="tspan3483"
+ x="-684.0636"
+ y="525.57513"
+ style="font-size:12.80000019px">2. negotiate_contract()</tspan></text>
+ <g
+ id="g3969"
+ transform="matrix(0.8,0,0,0.8,193.40503,295.89545)">
+ <rect
+ style="fill:#ffc0c0;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3260"
+ width="330.51944"
+ height="436.59048"
+ x="24.652443"
+ y="334.42914" />
+ <rect
+ y="414.17316"
+ x="37.179413"
+ height="56.853191"
+ width="297.75656"
+ id="rect3525"
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <rect
+ y="477.86197"
+ x="37.179413"
+ height="207.17691"
+ width="297.75662"
+ id="rect3337"
+ style="opacity:1;fill:#ff5b5b;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ xml:space="preserve"
+ style="font-size:17.5px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="39.372852"
+ y="360.68256"
+ id="text3262"><tspan
+ sodipodi:role="line"
+ id="tspan3264"
+ x="39.372852"
+ y="360.68256">User contract</tspan></text>
+ <g
+ transform="translate(-64,24)"
+ id="g3400">
+ <rect
+ style="opacity:1;fill:#ffc0c0;fill-opacity:1;stroke:#000000;stroke-width:1.00000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3394"
+ width="133.94228"
+ height="128.1606"
+ x="112.74278"
+ y="513.60602" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="145.58307"
+ y="530.95105"
+ id="text3396"><tspan
+ sodipodi:role="line"
+ id="tspan3398"
+ x="145.58307"
+ y="530.95105"
+ style="font-size:15px">Variant A</tspan></text>
+ </g>
+ <rect
+ style="fill:#ff5b5b;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3266"
+ width="115.63361"
+ height="34.305229"
+ x="57.890869"
+ y="572.97998" />
+ <text
+ xml:space="preserve"
+ style="font-size:15px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="115.03018"
+ y="594.27081"
+ id="text3268"><tspan
+ id="tspan3372"
+ sodipodi:role="line"
+ x="115.03018"
+ y="594.27081">Basic params A</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="41.997498"
+ y="446.84567"
+ id="text3272"><tspan
+ sodipodi:role="line"
+ x="41.997498"
+ y="446.84567"
+ id="tspan3276"
+ style="font-size:14px">resource_type</tspan><tspan
+ sodipodi:role="line"
+ x="41.997498"
+ y="464.34567"
+ id="tspan3278"
+ style="font-size:14px">resource_id</tspan></text>
+ <rect
+ y="617.23969"
+ x="57.070892"
+ height="34.305229"
+ width="115.63361"
+ id="rect3282"
+ style="fill:#ff5b5b;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ id="text3284"
+ y="639.38306"
+ x="114.96826"
+ style="font-size:15px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ id="tspan3382"
+ y="639.38306"
+ x="114.96826"
+ sodipodi:role="line">Timing reqs. A</tspan><tspan
+ id="tspan3384"
+ y="658.13306"
+ x="114.96826"
+ sodipodi:role="line" /></text>
+ <g
+ transform="translate(-64,4)"
+ id="g3421">
+ <rect
+ y="688.48181"
+ x="101.17941"
+ height="65.525719"
+ width="297.75656"
+ id="rect3290"
+ style="fill:#ff5b5b;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ id="text3292"
+ y="714.26227"
+ x="249.70613"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ y="714.26227"
+ x="249.70613"
+ id="tspan3294"
+ sodipodi:role="line">Resource specific</tspan><tspan
+ id="tspan3296"
+ y="739.26227"
+ x="249.70613"
+ sodipodi:role="line">parameters</tspan></text>
+ </g>
+ <text
+ id="text3339"
+ y="498.77039"
+ x="70.64624"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ y="498.77039"
+ x="70.64624"
+ id="tspan3341"
+ sodipodi:role="line">Spare capacity params</tspan></text>
+ <text
+ id="text3348"
+ y="520.47931"
+ x="53.560852"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ style="font-size:15px"
+ y="520.47931"
+ x="53.560852"
+ id="tspan3350"
+ sodipodi:role="line">discrete</tspan></text>
+ <g
+ transform="translate(76,24)"
+ id="g3405">
+ <rect
+ y="513.60602"
+ x="112.74278"
+ height="128.1606"
+ width="133.94228"
+ id="rect3407"
+ style="opacity:1;fill:#ffc0c0;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ id="text3409"
+ y="530.95105"
+ x="145.58307"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ style="font-size:15px"
+ y="530.95105"
+ x="145.58307"
+ id="tspan3411"
+ sodipodi:role="line">Variant B</tspan></text>
+ </g>
+ <rect
+ y="572.93213"
+ x="195.92944"
+ height="34.305229"
+ width="115.63361"
+ id="rect3360"
+ style="fill:#ff5b5b;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ id="text3362"
+ y="594.27081"
+ x="253.53751"
+ style="font-size:15px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ id="tspan3376"
+ y="594.27081"
+ x="253.53751"
+ sodipodi:role="line">Basic params B</tspan></text>
+ <rect
+ style="fill:#ff5b5b;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3366"
+ width="115.63361"
+ height="34.305229"
+ x="195.08798"
+ y="618.09229" />
+ <text
+ xml:space="preserve"
+ style="font-size:15px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="253.4541"
+ y="639.38306"
+ id="text3368"><tspan
+ id="tspan3378"
+ sodipodi:role="line"
+ x="253.4541"
+ y="639.38306">Timing reqs. B</tspan></text>
+ <text
+ id="text3527"
+ y="436.26227"
+ x="183.70613"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ id="tspan3531"
+ y="436.26227"
+ x="183.70613"
+ sodipodi:role="line">Resource</tspan></text>
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3317"
+ width="297.75656"
+ height="33.910725"
+ x="37.179413"
+ y="373.7507" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="186.12117"
+ y="398.16211"
+ id="text3319"><tspan
+ sodipodi:role="line"
+ id="tspan3321"
+ x="186.12117"
+ y="398.16211">User Label</tspan></text>
+ <rect
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect2666"
+ width="297.7424"
+ height="384.27328"
+ x="37.165554"
+ y="373.74121" />
+ </g>
+ <g
+ id="g4013"
+ transform="matrix(0.8,0,0,0.8,255.27224,63.785517)">
+ <rect
+ y="305.53189"
+ x="424.65244"
+ height="274.74731"
+ width="211.34297"
+ id="rect3553"
+ style="fill:#ffc0c0;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <g
+ id="g3333"
+ transform="translate(0,-194.88188)">
+ <rect
+ style="fill:#5599ff;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect2517"
+ width="189.63651"
+ height="34.305229"
+ x="437.48056"
+ y="535.75897" />
+ <text
+ id="text3313"
+ y="560.36761"
+ x="532.32324"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ y="560.36761"
+ x="532.32324"
+ id="tspan3315"
+ sodipodi:role="line">Global contract ID</tspan></text>
+ </g>
+ <g
+ id="g2611"
+ transform="matrix(1.005391,0,0,1,-2.3585736,8.081283)">
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3571"
+ width="188.35999"
+ height="34.305229"
+ x="437.49869"
+ y="373.50946" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="531.39551"
+ y="394.80029"
+ id="text3573"><tspan
+ id="tspan3575"
+ sodipodi:role="line"
+ x="531.39551"
+ y="394.80029">Basic params A</tspan></text>
+ </g>
+ <g
+ id="g2616"
+ transform="translate(0,4.5352319)">
+ <rect
+ y="417.76917"
+ x="437.48056"
+ height="34.305229"
+ width="189.63651"
+ id="rect3585"
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ id="text3587"
+ y="439.91254"
+ x="532.40625"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ id="tspan3589"
+ y="439.91254"
+ x="532.40625"
+ sodipodi:role="line">Timing reqs. A</tspan><tspan
+ id="tspan3591"
+ y="464.91254"
+ x="532.40625"
+ sodipodi:role="line" /></text>
+ </g>
+ <g
+ id="g2622"
+ transform="translate(0,42.5197)">
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3595"
+ width="189.63651"
+ height="65.525719"
+ x="437.48056"
+ y="461.21204" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="531.94727"
+ y="486.99249"
+ id="text3597"><tspan
+ sodipodi:role="line"
+ id="tspan3599"
+ x="531.94727"
+ y="486.99249">Resource specific</tspan><tspan
+ sodipodi:role="line"
+ x="531.94727"
+ y="511.99249"
+ id="tspan3601">parameters</tspan></text>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="747.26892"
+ y="541.07788"
+ id="text3329"
+ transform="translate(-152.74315,9.39647)"><tspan
+ sodipodi:role="line"
+ id="tspan3331"
+ x="747.26892"
+ y="541.07788" /></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.5px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans"
+ x="435.93616"
+ y="327.00418"
+ id="text2620"><tspan
+ sodipodi:role="line"
+ id="tspan2622"
+ x="435.93616"
+ y="327.00418">Reservation contract</tspan></text>
+ <g
+ transform="translate(0,45.248885)"
+ id="g3460">
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3462"
+ width="189.63651"
+ height="34.305229"
+ x="437.48056"
+ y="417.76917" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="532.40625"
+ y="439.91254"
+ id="text3464"><tspan
+ sodipodi:role="line"
+ x="532.40625"
+ y="439.91254"
+ id="tspan3468">Spare capacity p.</tspan></text>
+ </g>
+ <rect
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3456"
+ width="188.96213"
+ height="187.66902"
+ x="437.49866"
+ y="381.58847" />
+ </g>
+ <g
+ id="g4037"
+ transform="matrix(0.8,0,0,0.8,321.43306,335.64025)">
+ <rect
+ style="fill:#ffc0c0;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3913"
+ width="213.33945"
+ height="354.60593"
+ x="684.65247"
+ y="334.42914" />
+ <text
+ xml:space="preserve"
+ style="font-size:17.5px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="790.51447"
+ y="360.68256"
+ id="text3915"><tspan
+ sodipodi:role="line"
+ id="tspan3917"
+ x="790.51447"
+ y="360.68256">Schedulable contract</tspan></text>
+ <g
+ id="g3323"
+ transform="translate(0,79.544194)"
+ style="stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">
+ <rect
+ style="fill:#ffcc00;fill-opacity:0.71428576;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3957"
+ width="188.37726"
+ height="65.525719"
+ x="697.48059"
+ y="533.21204" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="791.25415"
+ y="558.99249"
+ id="text3959"><tspan
+ sodipodi:role="line"
+ x="791.25415"
+ y="558.99249"
+ id="tspan3963">Scheduling</tspan><tspan
+ sodipodi:role="line"
+ x="791.25415"
+ y="583.99249"
+ id="tspan3967">parameters</tspan></text>
+ </g>
+ <g
+ style="display:inline"
+ id="g3472"
+ transform="translate(259.88268,-157.07189)">
+ <rect
+ style="fill:#5599ff;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3474"
+ width="189.63651"
+ height="34.305229"
+ x="437.48056"
+ y="535.75897" />
+ <text
+ id="text3476"
+ y="560.36761"
+ x="532.32324"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ y="560.36761"
+ x="532.32324"
+ id="tspan3478"
+ sodipodi:role="line">Global contract ID</tspan></text>
+ </g>
+ <g
+ style="display:inline"
+ id="g3480"
+ transform="matrix(1.005391,0,0,1,257.5241,45.891266)">
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3482"
+ width="188.35999"
+ height="34.305229"
+ x="437.49869"
+ y="373.50946" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="531.39551"
+ y="394.80029"
+ id="text3484"><tspan
+ id="tspan3486"
+ sodipodi:role="line"
+ x="531.39551"
+ y="394.80029">Basic params A</tspan></text>
+ </g>
+ <g
+ style="display:inline"
+ id="g3488"
+ transform="translate(259.88268,42.345216)">
+ <rect
+ y="417.76917"
+ x="437.48056"
+ height="34.305229"
+ width="189.63651"
+ id="rect3490"
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ id="text3492"
+ y="439.91254"
+ x="532.40625"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ id="tspan3494"
+ y="439.91254"
+ x="532.40625"
+ sodipodi:role="line">Timing reqs. A</tspan><tspan
+ id="tspan3496"
+ y="464.91254"
+ x="532.40625"
+ sodipodi:role="line" /></text>
+ </g>
+ <g
+ style="display:inline"
+ id="g3498"
+ transform="translate(259.88268,80.329696)">
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3500"
+ width="189.63651"
+ height="65.525719"
+ x="437.48056"
+ y="461.21204" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="531.94727"
+ y="486.99249"
+ id="text3502"><tspan
+ sodipodi:role="line"
+ id="tspan3504"
+ x="531.94727"
+ y="486.99249">Resource specific</tspan><tspan
+ sodipodi:role="line"
+ x="531.94727"
+ y="511.99249"
+ id="tspan3506">parameters</tspan></text>
+ </g>
+ <g
+ style="display:inline"
+ transform="translate(259.88268,83.058866)"
+ id="g3508">
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3510"
+ width="189.63651"
+ height="34.305229"
+ x="437.48056"
+ y="417.76917" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="532.40625"
+ y="439.91254"
+ id="text3512"><tspan
+ sodipodi:role="line"
+ x="532.40625"
+ y="439.91254"
+ id="tspan3514">Spare capacity p.</tspan></text>
+ </g>
+ <rect
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3458"
+ width="188.4765"
+ height="258.83881"
+ x="697.38135"
+ y="419.40076" />
+ </g>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.4000001;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:14.39999995, 2.39999999;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 537.8586,798.82449 L 537.8586,605.58365"
+ id="path4065"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.40000033;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 587.39602,928.59538 L 743.46842,928.59538"
+ id="path2548" />
+ <g
+ id="g3373"
+ transform="matrix(0.8,0,0,0.8,591.98292,455.50121)">
+ <rect
+ style="fill:#ff5f5f;fill-opacity:1;stroke:#000000;stroke-width:1.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect5280"
+ width="127.94772"
+ height="57.947727"
+ x="-111.62925"
+ y="560.96991" />
+ <text
+ id="text5388"
+ y="595.46136"
+ x="-102.25348"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ y="595.46136"
+ x="-102.25348"
+ id="tspan5390"
+ sodipodi:role="line">Application</tspan></text>
+ </g>
+ <path
+ id="path5392"
+ d="M 587.39602,577.51266 L 743.46842,577.51266"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.4000001;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:14.4, 2.4;stroke-dashoffset:0;stroke-opacity:1" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.4000001;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:14.40000018, 2.40000002;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 560.23176,606.07317 L 560.23176,794.59907"
+ id="path3413"
+ sodipodi:nodetypes="cc" />
+ <g
+ id="g3390"
+ transform="matrix(0.8,0,0,0.8,227.52007,110.35765)">
+ <rect
+ y="560.96991"
+ x="361.21506"
+ height="57.947727"
+ width="93.416237"
+ id="rect5272"
+ style="fill:#5599ff;fill-opacity:1;stroke:#000000;stroke-width:1.99999976;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="366.05945"
+ y="596.43793"
+ id="text5394"><tspan
+ sodipodi:role="line"
+ id="tspan5396"
+ x="366.05945"
+ y="596.43793">CB/DTM</tspan></text>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-size:16px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="29.907341"
+ y="523.52795"
+ id="text6492"><tspan
+ sodipodi:role="line"
+ id="tspan6494"
+ x="29.907341"
+ y="523.52795" /></text>
+ <g
+ id="g4292"
+ transform="matrix(0.8,0,0,0.8,223.15545,144.35765)">
+ <rect
+ rx="22.661722"
+ ry="22.661724"
+ y="1034.057"
+ x="606.09998"
+ height="60.381516"
+ width="278.76849"
+ id="rect4257"
+ style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" />
+ <text
+ id="text3415"
+ y="1051.2797"
+ x="745.43298"
+ style="font-size:15px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ id="tspan3419"
+ y="1051.2797"
+ x="745.43298"
+ sodipodi:role="line">Interface to resource scheduler</tspan><tspan
+ y="1070.0297"
+ x="745.43298"
+ sodipodi:role="line"
+ id="tspan4971">Responsible for creating/changing</tspan><tspan
+ y="1088.7797"
+ x="745.43298"
+ sodipodi:role="line"
+ id="tspan4977">virtual resources (vres)</tspan></text>
+ </g>
+ <g
+ style="display:inline"
+ id="g3425"
+ transform="matrix(0.8,0,0,0.8,26.449024,663.51813)">
+ <g
+ transform="translate(250.45708,-530.3578)"
+ style="display:inline"
+ id="g3465">
+ <rect
+ style="fill:#5599ff;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3467"
+ width="193.98927"
+ height="34.305229"
+ x="430.49289"
+ y="535.75897" />
+ <text
+ id="text3469"
+ y="560.36761"
+ x="527.85864"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ y="560.36761"
+ x="527.85864"
+ id="tspan3471"
+ sodipodi:role="line">Global contract ID</tspan></text>
+ </g>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-size:12.80000019px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans"
+ x="669.91626"
+ y="568.44385"
+ id="text3485"><tspan
+ sodipodi:role="line"
+ x="669.91626"
+ y="568.44385"
+ id="tspan3511">3. reserve(), commit()</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans"
+ x="692.74304"
+ y="628.35968"
+ id="text3489"><tspan
+ sodipodi:role="line"
+ id="tspan3491"
+ x="692.74304"
+ y="628.35968"
+ style="font-size:12.80000019px">4. change_vreses()</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans"
+ x="665.84265"
+ y="590.92767"
+ id="text3493"><tspan
+ sodipodi:role="line"
+ id="tspan3495"
+ x="665.84265"
+ y="590.92767"
+ style="font-size:12.80000019px">return</tspan></text>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.4000001;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:14.4, 2.4;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 751.73574,595.22257 L 599.42698,595.22257 C 569.85507,595.22257 570.98228,632.6686 598.11008,632.6686 L 801.77457,632.6686 C 817.43814,632.6686 829.58941,644.17594 829.58941,664.16661 L 829.58941,898.34021"
+ id="path5398"
+ sodipodi:nodetypes="czzczs" />
+ <g
+ id="g3406"
+ transform="matrix(0.8,0,0,0.8,223.15546,110.35765)">
+ <rect
+ y="560.96991"
+ x="656.11176"
+ height="57.947727"
+ width="109.46667"
+ id="rect5284"
+ style="fill:#ffcc00;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ id="text5400"
+ y="582.65375"
+ x="663.74652"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ y="582.65375"
+ x="663.74652"
+ id="tspan5402"
+ sodipodi:role="line">Resource</tspan><tspan
+ id="tspan5404"
+ y="607.65375"
+ x="663.74652"
+ sodipodi:role="line">Manager</tspan></text>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans"
+ x="-678.64044"
+ y="554.94214"
+ id="text4245"
+ transform="matrix(0,-1,1,0,0,0)"
+ inkscape:transform-center-x="-483.5567"
+ inkscape:transform-center-y="-21.37086"><tspan
+ sodipodi:role="line"
+ id="tspan4247"
+ x="-678.64044"
+ y="554.94214"
+ style="font-size:12.80000019px">5. return</tspan></text>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 795.08,950.63533 L 818.65609,971.20325"
+ id="path4261"
+ inkscape:connector-type="polyline" />
+ <g
+ id="g4297"
+ transform="matrix(0.8,0,0,0.8,198.94973,32.277362)">
+ <rect
+ style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
+ id="rect4255"
+ width="95.179222"
+ height="150.52023"
+ x="784.10681"
+ y="471.83047"
+ ry="22.661724"
+ rx="22.66172" />
+ <text
+ id="text5414"
+ y="494.69073"
+ x="832.28235"
+ style="font-size:15px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ y="494.69073"
+ x="832.28235"
+ id="tspan5416"
+ sodipodi:role="line">Executes</tspan><tspan
+ id="tspan3423"
+ y="513.44073"
+ x="832.28235"
+ sodipodi:role="line">Admission</tspan><tspan
+ id="tspan5418"
+ y="532.19073"
+ x="832.28235"
+ sodipodi:role="line">Test</tspan><tspan
+ y="550.94073"
+ x="832.28235"
+ sodipodi:role="line"
+ id="tspan2545" /><tspan
+ y="569.69073"
+ x="832.28235"
+ sodipodi:role="line"
+ id="tspan2547">Assigns</tspan><tspan
+ y="588.44073"
+ x="832.28235"
+ sodipodi:role="line"
+ id="tspan2549">priorities</tspan><tspan
+ y="607.19073"
+ x="832.28235"
+ sodipodi:role="line"
+ id="tspan2551">etc.</tspan></text>
+ </g>
+ <g
+ id="g4282"
+ transform="matrix(0.8,0,0,0.8,165.98578,91.394295)">
+ <rect
+ rx="22.661722"
+ ry="22.661722"
+ y="287.68723"
+ x="308.04492"
+ height="255.69772"
+ width="125.77255"
+ id="rect4253"
+ style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" />
+ <text
+ xml:space="preserve"
+ style="font-size:15px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans"
+ x="370.56497"
+ y="307.76181"
+ id="text5480"><tspan
+ sodipodi:role="line"
+ x="370.56497"
+ y="307.76181"
+ id="tspan5484">Negotiates</tspan><tspan
+ sodipodi:role="line"
+ x="372.95267"
+ y="326.51181"
+ id="tspan4973">contracts with </tspan><tspan
+ sodipodi:role="line"
+ x="370.56497"
+ y="345.26181"
+ id="tspan4975">formerly</tspan><tspan
+ sodipodi:role="line"
+ x="370.56497"
+ y="364.01181"
+ id="tspan3367">registered res.</tspan><tspan
+ sodipodi:role="line"
+ x="370.56497"
+ y="382.76181"
+ id="tspan3369"> managers and</tspan><tspan
+ sodipodi:role="line"
+ x="370.56497"
+ y="401.51181"
+ id="tspan3381">schedulers</tspan><tspan
+ sodipodi:role="line"
+ x="370.56497"
+ y="420.26181"
+ id="tspan3371" /><tspan
+ sodipodi:role="line"
+ x="370.56497"
+ y="439.01181"
+ id="tspan3365">Rebalances</tspan><tspan
+ id="tspan5488"
+ sodipodi:role="line"
+ x="370.56497"
+ y="457.76181">transactions</tspan><tspan
+ id="tspan5490"
+ sodipodi:role="line"
+ x="370.56497"
+ y="476.51181" /><tspan
+ id="tspan5496"
+ sodipodi:role="line"
+ x="370.56497"
+ y="495.26181">Redistributes</tspan><tspan
+ id="tspan5492"
+ sodipodi:role="line"
+ x="370.56497"
+ y="514.01184">spare</tspan><tspan
+ id="tspan5494"
+ sodipodi:role="line"
+ x="370.56497"
+ y="532.76178">capacity</tspan></text>
+ </g>
+ <g
+ transform="matrix(0.6059216,0,0,0.6059216,302.13402,786.38554)"
+ id="g2550"
+ style="display:inline">
+ <g
+ id="g2552"
+ style="display:inline"
+ transform="translate(230.65252,-527.05704)">
+ <rect
+ y="535.75897"
+ x="452.6459"
+ height="34.305229"
+ width="149.68324"
+ id="rect2554"
+ style="fill:#5599ff;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="527.85864"
+ y="560.36761"
+ id="text2556"><tspan
+ sodipodi:role="line"
+ id="tspan2558"
+ x="527.85864"
+ y="560.36761">G. contract ID</tspan></text>
+ </g>
+ </g>
+ <text
+ id="text2560"
+ y="920.22693"
+ x="672.35114"
+ style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ style="font-size:12.80000019px"
+ y="920.22693"
+ x="672.35114"
+ id="tspan2562"
+ sodipodi:role="line">8. frsh_XXX_bind()</tspan></text>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.4000001;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:14.40000102, 2.40000018;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 130.77624,357.66538 L 193.28028,357.66538"
+ id="path3340" />
+ <path
+ id="path3342"
+ d="M 131.38058,383.63755 L 192.12284,383.63755"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.40000033;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <text
+ xml:space="preserve"
+ style="font-size:16px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="212.97842"
+ y="363.63025"
+ id="text3349"><tspan
+ sodipodi:role="line"
+ id="tspan3351"
+ x="212.97842"
+ y="363.63025">FORB invocation</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="216.86403"
+ y="384.88309"
+ id="text3353"><tspan
+ sodipodi:role="line"
+ id="tspan3355"
+ x="216.86403"
+ y="384.88309" /></text>
+ <text
+ xml:space="preserve"
+ style="font-size:16px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="212.97842"
+ y="389.60242"
+ id="text3357"><tspan
+ sodipodi:role="line"
+ id="tspan3359"
+ x="212.97842"
+ y="389.60242">Local invocation</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:16px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="131.38058"
+ y="335.34155"
+ id="text3361"><tspan
+ sodipodi:role="line"
+ id="tspan3363"
+ x="131.38058"
+ y="335.34155">Legend:</tspan></text>
+ <g
+ transform="matrix(0.8,0,0,0.8,591.98292,349.16076)"
+ id="g2573">
+ <rect
+ y="560.96991"
+ x="-111.62925"
+ height="57.947727"
+ width="127.94772"
+ id="rect2575"
+ style="fill:#afafaf;fill-opacity:1;stroke:#000000;stroke-width:1.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="-103.43176"
+ y="595.46136"
+ id="text2577"><tspan
+ sodipodi:role="line"
+ id="tspan2579"
+ x="-103.43176"
+ y="595.46136">FRSH/FRES</tspan></text>
+ </g>
+ <path
+ sodipodi:nodetypes="cc"
+ id="path3357"
+ d="M 537.8586,903.73171 L 537.8586,847.39696"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.4000001;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <path
+ id="path3363"
+ d="M 604.88126,815.90527 L 774.17199,816.36039 C 796.60566,816.4207 808.55195,822.76259 808.55211,849.98235 L 808.55239,898.1051"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.40000033;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="czzc" />
+ <text
+ xml:space="preserve"
+ style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans"
+ x="662.94281"
+ y="809.47626"
+ id="text3367"><tspan
+ sodipodi:role="line"
+ id="tspan3370"
+ x="662.94281"
+ y="809.47626"
+ style="font-size:12.80000019px">6. get_vres_id()</tspan></text>
+ <g
+ transform="matrix(0.64,0,0,0.64,-50.387324,498.63585)"
+ id="g3372">
+ <rect
+ y="560.96991"
+ x="973.93732"
+ height="32.448402"
+ width="142.25151"
+ id="rect3374"
+ style="fill:#fff6d5;fill-opacity:1;stroke:#000000;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ id="text3376"
+ y="584.59222"
+ x="981.74658"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ id="tspan3383"
+ y="584.59222"
+ x="981.74658"
+ sodipodi:role="line">VRes ID (ptr)</tspan></text>
+ </g>
+ <use
+ x="0"
+ y="0"
+ xlink:href="#g3372"
+ id="use3415"
+ transform="translate(49.581828,77.131765)"
+ width="1052.3622"
+ height="744.09448" />
+ <text
+ transform="matrix(0,-1,1,0,0,0)"
+ id="text3417"
+ y="525.57513"
+ x="-874.17529"
+ style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ style="font-size:12.80000019px"
+ y="525.57513"
+ x="-874.17529"
+ id="tspan3420"
+ sodipodi:role="line">1.</tspan></text>
+ <path
+ sodipodi:nodetypes="cszzzc"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.40000057;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Mstart);marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 562.38242,900.41728 C 562.38242,872.66445 563.28773,925.44152 563.28773,842.41945 C 563.28773,831.25406 563.98448,831.51024 575.06695,831.52762 L 760.72311,831.81874 C 781.37461,831.85112 792.37186,837.03822 792.37198,859.22955 L 792.37224,908.66208"
+ id="path3432" />
+ <path
+ id="path2610"
+ d="M 841.46482,928.59538 L 906.06569,928.59538"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.4000001;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2.39999994, 2.39999994;stroke-dashoffset:0;stroke-opacity:1" />
+ <g
+ id="g3355"
+ transform="matrix(0.8,0,0,0.8,-29.105004,455.50121)">
+ <rect
+ style="fill:#fff6d5;fill-opacity:1;stroke:#ffcc00;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect5306"
+ width="109.46667"
+ height="57.947727"
+ x="973.93732"
+ y="560.96991" />
+ <text
+ xml:space="preserve"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="981.74658"
+ y="584.59222"
+ id="text5408"><tspan
+ sodipodi:role="line"
+ id="tspan5410"
+ x="981.74658"
+ y="584.59222">Resource</tspan><tspan
+ sodipodi:role="line"
+ x="981.74658"
+ y="609.59222"
+ id="tspan5412">Allocator</tspan></text>
+ </g>
+ <text
+ id="text4753"
+ y="828.41858"
+ x="640.82941"
+ style="font-size:16px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ style="font-size:12.80000019px"
+ y="828.41858"
+ x="640.82941"
+ id="tspan4755"
+ sodipodi:role="line">7. return</tspan></text>
+ <g
+ transform="matrix(0.8,0,0,0.8,129.56554,455.50121)"
+ id="g2594">
+ <rect
+ y="560.96991"
+ x="973.93732"
+ height="57.947727"
+ width="109.46667"
+ id="rect2596"
+ style="fill:#fff6d5;fill-opacity:1;stroke:#ffcc00;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ id="text2598"
+ y="584.72406"
+ x="1028.0212"
+ style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ id="tspan2602"
+ y="584.72406"
+ x="1028.0212"
+ sodipodi:role="line">Resource</tspan><tspan
+ y="609.72406"
+ x="1028.0212"
+ sodipodi:role="line"
+ id="tspan2606">Scheduler</tspan></text>
+ </g>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.40000033;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:2.40000033, 2.40000033;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 131.38058,410.83682 L 192.12284,410.83682"
+ id="path4957" />
+ <text
+ id="text4959"
+ y="416.80173"
+ x="212.97842"
+ style="font-size:16px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ y="416.80173"
+ x="212.97842"
+ id="tspan4961"
+ sodipodi:role="line">System call or other</tspan><tspan
+ y="436.80173"
+ x="212.97842"
+ sodipodi:role="line"
+ id="tspan4965">resource specific</tspan><tspan
+ y="456.80173"
+ x="212.97842"
+ sodipodi:role="line"
+ id="tspan4969">communication</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:URW Bookman L;-inkscape-font-specification:URW Bookman L"
+ x="95.197464"
+ y="224.39403"
+ id="text2599"
+ transform="translate(58.52032,298.67903)"><tspan
+ sodipodi:role="line"
+ id="tspan2601"
+ x="95.197464"
+ y="224.39403" /></text>
+ <text
+ id="text2603"
+ y="169.35637"
+ x="-815.56897"
+ style="font-size:16px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="matrix(0,-1,1,0,0,0)"><tspan
+ y="169.35637"
+ x="-815.56897"
+ id="tspan2605"
+ sodipodi:role="line">Contract blocks</tspan></text>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);stroke-miterlimit:4;stroke-dasharray:none;marker-mid:none;marker-end:none"
+ d="M 164.62823,314.6075 L 116.69742,449.41249"
+ id="path2609"
+ transform="translate(58.52032,298.67903)"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);stroke-miterlimit:4;stroke-dasharray:none;marker-mid:none;marker-end:none"
+ d="M 164.62823,453.64507 L 164.62823,453.64507 L 116.73997,449.51912"
+ id="path2611"
+ transform="translate(58.52032,298.67903)"
+ sodipodi:nodetypes="ccc" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path11031"
+ d="M 222.9849,867.79048 L 175.19238,748.02798"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Mstart);marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path11033"
+ d="M 222.88565,656.80227 L 175.19238,748.14008"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Mstart);marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+</svg>
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+SUBDIRS=contract synchobj sharedobj cbroker resmng resalloc
+
+ifneq ($(QTDIR),)
+SUBDIRS += frm_gui
+endif
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+bin_PROGRAMS += fcb
+
+CFLAGS += --std=gnu99 #--save-temps
+
+fcb_SOURCES = fcb.c contract_log.c
+fcb_LIBS = contract fosa forb pthread rt ulut frm_client fra_client
+fcb_LIBS += frsh # For frsh_strerror
+fcb_SERVER_IDL = fcb.idl
+
+lib_LIBRARIES += fcb_client
+fcb_client_CLIENT_IDL = fcb.idl
+
+include_GEN_HEADERS += fcb.h
+include_HEADERS += fcb_contact_info.h
+
+default_CONFIG = CONFIG_FCB_INET=y
+default_CONFIG += CONFIG_FCB=y # Hack to let FORB automatically register reference to FCB.
+
+LOCAL_CONFIG_H = fcb_config.h
+
+# include-pass_HOOKS = fcb_contract_gavl.inc
+
+# fcb_contract_gavl.inc: $(SOURCES_DIR)/fcb_contract_gavl.c
+# $(c_o_COMPILE) -E -P $< | indent | sed -e '0,/__cut_here__/d' > $@
--- /dev/null
+/**
+ * @file contract_log.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Mon Aug 10 13:00:20 2009
+ *
+ * @brief
+ *
+ *
+ */
+
+#include <ul_log.h>
+#include "contract_log.h"
+#include <ul_logreg.h>
+
+static UL_LOG_CUST(ulogd);
+static ul_log_domain_t ulogd = {UL_LOGL_MSG, "contract_log"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(init_ulogd_contract_log, ulogd);
+
+void
+log_contract(const char *prefix, int index, const struct fres_contract *c)
+{
+ if (ul_log_cond(&ulogd, UL_LOGL_DEB)) {
+ /* Dump contract contract */
+ char str[1000];
+ fres_contract_to_string2(str, sizeof(str), c, 4, 0);
+ ul_logdeb("%s #%d:\n%s", prefix, index, str);
+ }
+ else {
+ char res_name[10] = "";
+ frsh_contract_label_t label = "";
+ fres_block_resource *block_res;
+ fres_block_label *block_label;
+ char *p;
+ block_res = fres_contract_get_resource(c);
+ if (block_res)
+ fres_block_to_string(res_name, sizeof(res_name),
+ FRES_BLOCK_RESOURCE, block_res);
+ block_label = fres_contract_get_label(c);
+ if (block_label)
+ strcpy(label, block_label->label);
+
+ for (p=res_name; *p!='\n' && *p!=0; p++);
+ *p = 0;
+
+ ul_logmsg("%s: %s %s\n", prefix, res_name, label);
+ }
+}
--- /dev/null
+#ifndef CONTRACT_LOG_H
+#define CONTRACT_LOG_H
+
+#include <fres_contract.h>
+
+void
+log_contract(const char *prefix, int index, const struct fres_contract *c);
+
+
+#endif
--- /dev/null
+#ifndef _DTM_IDL
+#define _DTM_IDL
+
+#include "contract/fres_contract_idl.idl"
+
+module cm {
+ interface transaction {
+ void add_contract(in contract_t contract);
+ void negotiate();
+ };
+ typedef unsigned long resource_type;
+ interface dtm {
+ transaction new_transaction();
+ long get_contract(in contract_handle_t handle);
+ void negotiate_contract(inout contract_t contract);
+ void register_manager(in resource_type restype, in resource_manager m);
+ void register_allocator(in resource_type restype, in resource_allocator r);
+ };
+};
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file fcb.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Mon Oct 20 18:00:18 2008
+ *
+ * @brief FRESCOR Contract Broker
+ *
+ *
+ */
+#define WITH_C99 /* For ul_gsa.h iterators */
+#include <semaphore.h>
+#include <getopt.h>
+#include <forb.h>
+#include <forb/config.h>
+#include <fcb.h>
+#include <fcb_contact_info.h>
+#include <error.h>
+#include <errno.h>
+#include <stdio.h>
+#include <ul_gavlcust.h>
+#include <ul_gsacust.h>
+#include <string.h>
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <forb/server_id.h>
+#include <fres_contract.h>
+#include "fcb_config.h"
+#include <fosa_clocks_and_timers.h>
+#include "contract_log.h"
+#if CONFIG_FCB_INET && !CONFIG_FORB_PROTO_INET_DEFAULT
+#include <forb/proto_inet.h>
+#endif
+
+#define COMPILE_TIME_ASSERT(cond, msg) \
+ typedef char msg[(cond) ? 1 : -1]
+
+
+UL_LOG_CUST(ulogd_fcb);
+ul_log_domain_t ulogd_fcb = {UL_LOGL_MSG, "main"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(init_ulogd_fcb, ulogd_fcb);
+
+bool opt_daemon = false;
+char *opt_pidfile = NULL;
+fosa_abs_time_t start_time;
+
+/** List of contracts to be newly reserved or changed by resource manager */
+struct reservation_list {
+ ul_list_head_t fcb_contracts;
+ unsigned length;
+};
+
+/**
+ * Resource identification
+ */
+struct res_key {
+ frsh_resource_type_t type;
+ frsh_resource_id_t id;
+};
+
+/**
+ * Registered resource
+ */
+struct resource {
+ gavl_node_t node;
+ struct res_key key;
+ char *name;
+ fres_resource_manager mng; /**< Object reference of the resource manager */
+ gavl_cust_root_field_t allocators; /**< Registered allocators for this resource (from multiple applications/nodes) */
+ ul_list_head_t sc_contracts; /**< Negotiated contracts with spare capacity for this resource */
+ struct reservation_list rl; /**< Temporary list of contracts to be reserved on this resource */
+};
+
+/**
+ * Resource allocator registered in different nodes/applications
+ */
+struct res_alloc {
+ gavl_node_t node;
+ forb_server_id app;
+ fres_resource_allocator ra;
+};
+
+struct fcb_transaction;
+
+struct fcb_contract {
+ fres_contract_id_t id;
+ struct res_alloc *ra; /**< Allocator for this contract TODO: Remove contract if allocator is destroyed */
+ gavl_node_t node_fcb;
+ ul_list_node_t node_sc;
+ ul_list_node_t node_reservation;
+ struct fcb_transaction *transaction;
+ struct {
+ int initial;
+ int try;
+ } sc_variant;
+ fosa_abs_time_t end_of_stability_period;
+ struct fres_contract *user_contract; /* The contract sent by user. Set after sucessfull neotiation. */
+ struct fres_contract *requested_contract; /* User request for the contract. Set by prepare_reservation_requests() in the beginning of negotiation. */
+ struct fres_contract *to_be_reserved_contract;
+ struct fres_contract *schedulable_contract;
+};
+
+struct fcb_transaction {
+ char *name;
+ gavl_node_t node;
+ gsa_array_field_t contracts;
+};
+
+/**
+ * Contract broker data
+ */
+struct fcb {
+ fres_contract_id_t contract_counter;
+ gavl_cust_root_field_t resources; /**< Registered resources */
+ gavl_cust_root_field_t contracts; /**< Contracts negotiated by this FCB */
+ gavl_cust_root_field_t transactions; /**< Transactions negotiated by this FCB */
+};
+
+struct fcb_contract *fcb_contract_new(fres_contract_id_t *id)
+{
+ struct fcb_contract *fcb_contract;
+
+ fcb_contract = malloc(sizeof(*fcb_contract));
+ if (!fcb_contract) {
+ return NULL;
+ }
+ memset(fcb_contract, 0, sizeof(*fcb_contract));
+ fcb_contract->id = *id;
+
+ return fcb_contract;
+}
+
+void fcb_contract_destroy(struct fcb_contract *fcb_contract)
+{
+ if (fcb_contract->user_contract) {
+ fres_contract_destroy(fcb_contract->user_contract);
+ }
+ if (fcb_contract->to_be_reserved_contract) {
+ fres_contract_destroy(fcb_contract->to_be_reserved_contract);
+ }
+ if (fcb_contract->requested_contract) {
+ fres_contract_destroy(fcb_contract->requested_contract);
+ }
+ if (fcb_contract->schedulable_contract) {
+ fres_contract_destroy(fcb_contract->requested_contract);
+ }
+ free(fcb_contract);
+}
+
+static inline int
+unsorted(const void *a, const void *b)
+{ abort(); }
+
+/* Unordered dynamic array of contracts in transaction */
+GSA_CUST_DEC(tran_contract /* cust_prefix */,
+ struct fcb_transaction /* cust_array_t */,
+ struct fcb_contract/* cust_item_t */,
+ fres_contract_id_t /* cust_key_t */,
+ contracts /* cust_array_field */,
+ id /* cust_item_key */,
+ unsorted /* cust_cmp_fnc */);
+
+GSA_CUST_IMP(tran_contract /* cust_prefix */,
+ struct fcb_transaction /* cust_array_t */,
+ struct fcb_contract/* cust_item_t */,
+ fres_contract_id_t /* cust_key_t */,
+ contracts /* cust_array_field */,
+ id /* cust_item_key */,
+ unsorted /* cust_cmp_fnc */,
+ true /* cust_ins_fl */);
+
+struct fcb_transaction *fcb_transaction_new(char *name)
+{
+ struct fcb_transaction *fcb_transaction;
+
+ fcb_transaction = malloc(sizeof(*fcb_transaction));
+ if (!fcb_transaction) {
+ return NULL;
+ }
+ memset(fcb_transaction, 0, sizeof(*fcb_transaction));
+ fcb_transaction->name = strdup(name);
+
+ tran_contract_init_array_field(fcb_transaction);
+
+ return fcb_transaction;
+}
+
+void fcb_transaction_destroy(struct fcb_transaction *fcb_transaction)
+{
+ free(fcb_transaction->name);
+ free(fcb_transaction);
+}
+
+static inline int res_key_cmp(const struct res_key *a,
+ const struct res_key *b)
+{
+ if (a->type < b->type) {
+ return -1;
+ } else if (a->type > b->type) {
+ return +1;
+ } else if (a->id < b->id) {
+ return -1;
+ } else if (a->id > b->id) {
+ return +1;
+ } else {
+ return 0;
+ }
+}
+
+/* Container for registered resources */
+GAVL_CUST_NODE_INT_DEC(fcb_resource /* cust_prefix */, \
+ struct fcb /* cust_root_t */, \
+ struct resource/* cust_item_t */, \
+ struct res_key /* cust_key_t */, \
+ resources /* cust_root_node */, \
+ node /* cust_item_node */, \
+ key /* cust_item_key */, \
+ res_key_cmp /* cust_cmp_fnc */);
+
+GAVL_CUST_NODE_INT_IMP(fcb_resource /* cust_prefix */, \
+ struct fcb /* cust_root_t */, \
+ struct resource/* cust_item_t */, \
+ struct res_key /* cust_key_t */, \
+ resources /* cust_root_node */, \
+ node /* cust_item_node */, \
+ key /* cust_item_key */, \
+ res_key_cmp /* cust_cmp_fnc */);
+
+/* Container for allocators registered for a given resource */
+GAVL_CUST_NODE_INT_DEC(fcb_alloc /* cust_prefix */, \
+ struct resource /* cust_root_t */, \
+ struct res_alloc /* cust_item_t */, \
+ forb_server_id /* cust_key_t */, \
+ allocators /* cust_root_node */, \
+ node /* cust_item_node */, \
+ app /* cust_item_key */, \
+ fres_contract_id_cmp /* cust_cmp_fnc */);
+
+GAVL_CUST_NODE_INT_IMP(fcb_alloc /* cust_prefix */, \
+ struct resource /* cust_root_t */, \
+ struct res_alloc /* cust_item_t */, \
+ forb_server_id /* cust_key_t */, \
+ allocators /* cust_root_node */, \
+ node /* cust_item_node */, \
+ app /* cust_item_key */, \
+ forb_server_id_cmp /* cust_cmp_fnc */);
+
+/* Container for contracts with spare capacity negotiated for a given resource */
+UL_LIST_CUST_DEC(sc_contracts /* cust_prefix */, \
+ struct resource /* cust_head_t */, \
+ struct fcb_contract /* cust_item_t */, \
+ sc_contracts /* cust_head_field */, \
+ node_sc /* cust_node_field */);
+
+UL_LIST_CUST_DEC(reservation_list /* cust_prefix */, \
+ struct reservation_list /* cust_head_t */, \
+ struct fcb_contract /* cust_item_t */, \
+ fcb_contracts /* cust_head_field */, \
+ node_reservation /* cust_node_field */);
+
+/* Container for negotiated contracts */
+GAVL_CUST_NODE_INT_DEC(fcb_contract /* cust_prefix */, \
+ struct fcb /* cust_root_t */, \
+ struct fcb_contract /* cust_item_t */, \
+ fres_contract_id_t /* cust_key_t */, \
+ contracts /* cust_root_node */, \
+ node_fcb /* cust_item_node */, \
+ id /* cust_item_key */, \
+ fres_contract_id_cmp /* cust_cmp_fnc */);
+
+#if 1
+GAVL_CUST_NODE_INT_IMP(fcb_contract /* cust_prefix */, \
+ struct fcb /* cust_root_t */, \
+ struct fcb_contract /* cust_item_t */, \
+ fres_contract_id_t /* cust_key_t */, \
+ contracts /* cust_root_node */, \
+ node_fcb /* cust_item_node */, \
+ id /* cust_item_key */, \
+ fres_contract_id_cmp /* cust_cmp_fnc */);
+#else
+#include "fcb_contract_gavl.inc"
+#endif
+
+static inline int
+fcb_transaction_cmp(char * const *a, char * const *b)
+{ return strcmp(*a, *b); }
+
+GAVL_CUST_NODE_INT_DEC(fcb_transaction /* cust_prefix */, \
+ struct fcb /* cust_root_t */, \
+ struct fcb_transaction /* cust_item_t */, \
+ char* /* cust_key_t */, \
+ transactions /* cust_root_node */, \
+ node /* cust_item_node */, \
+ name /* cust_item_key */, \
+ fcb_transaction_cmp /* cust_cmp_fnc */);
+
+GAVL_CUST_NODE_INT_IMP(fcb_transaction /* cust_prefix */, \
+ struct fcb /* cust_root_t */, \
+ struct fcb_transaction /* cust_item_t */, \
+ char* /* cust_key_t */, \
+ transactions /* cust_root_node */, \
+ node /* cust_item_node */, \
+ name /* cust_item_key */, \
+ fcb_transaction_cmp /* cust_cmp_fnc */);
+
+struct res_array {
+ gsa_array_field_t array;
+};
+
+GSA_CUST_DEC(res_array /* cust_prefix */,
+ struct res_array /* cust_array_t */,
+ struct resource /* cust_item_t */,
+ struct res_key /* cust_key_t */,
+ array /* cust_array_field */,
+ key /* cust_item_key */,
+ res_key_cmp /* cust_cmp_fnc */);
+
+GSA_CUST_IMP(res_array /* cust_prefix */,
+ struct res_array /* cust_array_t */,
+ struct resource /* cust_item_t */,
+ struct res_key /* cust_key_t */,
+ array /* cust_array_field */,
+ key /* cust_item_key */,
+ res_key_cmp /* cust_cmp_fnc */,
+ true /* cust_ins_fl */);
+
+
+
+#define o2fcb(o) (struct fcb*)forb_instance_data(o)
+
+static struct res_key*
+get_res_key(const struct fres_contract *contract, struct res_key *key)
+{
+ fres_block_resource *block_res;
+
+ block_res = fres_contract_get_resource(contract);
+ if (!block_res) {
+ ul_logerr("No resource specified\n");
+ return NULL;
+ } else {
+ key->type = block_res->resource_type;
+ key->id = block_res->resource_id;
+ }
+ return key;
+}
+
+static struct res_key*
+get_fc_res_key(const struct fcb_contract *fc, struct res_key *key)
+{
+ if (fc->user_contract)
+ get_res_key(fc->user_contract, key);
+ else
+ get_res_key(fc->requested_contract, key);
+ return key;
+}
+
+/**
+ * Fills in an array of fcb_contracts according to requests submited
+ * by an application through negotiate_contracts() or
+ * negotiate_transaction(). For every contract in @a contracts, there
+ * is allocated one fcb_contract in @a fcb_contracts array.
+ *
+ * @param fcb
+ * @param fcb_contracts Where to store pointers to fcb_contracts
+ * @param contracts Contracts submited for negotiation
+ * @param num Number of contracts in contracts (which is the same as the number in fcb_contracts).
+ *
+ * @return Zero on success, non-zero error code on error.
+ */
+static int
+prepare_fcb_contracts(struct fcb *fcb, struct fcb_contract *fcb_contracts[],
+ struct fres_contract *contracts[], int num)
+{
+ unsigned i;
+ struct fcb_contract *fc;
+
+ for (i=0; i<num; i++) {
+ struct fres_contract *c = contracts[i];
+
+ if (fres_contract_id_is_empty(&c->id)) {
+ /* Normal negotiation request */
+ COMPILE_TIME_ASSERT(sizeof(c->id) == sizeof(fcb->contract_counter),
+ wrong_size_of_contract_id);
+ c->id = ++fcb->contract_counter;
+ fc = fcb_contract_new(&c->id);
+ if (!fc)
+ return errno;
+ fcb_contracts[i] = fc;
+ log_contract("Negotiation request", i, c);
+ } else {
+ fc = fcb_contract_find(fcb, &c->id);
+ if (!fc) {
+ char str[60];
+ fres_contract_id_to_string(str, &c->id, sizeof(str));
+ ul_logerr("Attempt to change unknown contract %s\n", str);
+ return FRES_ERR_NOTHING_TO_RENEGOTIATE;
+ } else {
+ fcb_contracts[i] = fc;
+ if (fres_contract_get_num_blocks(c) == 0) {
+ /* Cancelation */
+ log_contract("Cancelation request", i, fc->user_contract);
+ } else {
+ /* Renegotiation */
+ log_contract("Renegotiation request", i, fc->user_contract);
+ }
+ }
+ }
+ fc->requested_contract = c;
+ }
+ return 0;
+}
+
+/**
+ * Ensure that all contracts belong to the same resource and find
+ * resource allocators for the contracts.
+ *
+ * @param fcb
+ * @param fcb_contracts Array of fcb_contracts prepared by prepare_fcb_contracts()
+ * @param num Number of contracts in @a fcb_contracts
+ * @param resource Resource for which negotiation is being done.
+ * @param app Application which requests negotiation
+ */
+static int
+check_and_setup_resource(struct fcb *fcb, struct fcb_contract *fcb_contracts[],
+ struct resource **resource,
+ forb_server_id *app,
+ int num)
+{
+ unsigned i;
+ struct res_alloc *ra;
+ struct res_key key, key2 = {-1,-1};
+
+ for (i=0; i<num; i++) {
+ struct fcb_contract *fc = fcb_contracts[i];
+
+ if (!get_fc_res_key(fc, &key))
+ return FRSH_ERR_RESOURCE_ID_INVALID;
+
+ /* Check that all contracts are for the same resource */
+ if (i==0) {
+ key2 = key;
+ *resource = fcb_resource_find(fcb, &key);
+ if (!*resource) {
+ ul_logerr("No resource manager for %d.%d registered\n",
+ key.type, key.id);
+ return FRES_ERR_NO_RESOURCE_MANAGER;
+ }
+ /* Find allocator for this request */
+ ra = fcb_alloc_find(*resource, app);
+ if (!ra) {
+ char str[60];
+ forb_server_id_to_string(str, app, sizeof(str));
+ ul_logerr("No resource allocator found for %d.%d and %s\n",
+ (*resource)->key.type, (*resource)->key.id, str);
+ return FRES_ERR_NO_RESOURCE_ALLOCATOR;
+ }
+ }
+ else if (key.type != key2.type ||
+ key.id != key2.id) {
+ ul_logerr("Contract #%d differs in resource!\n", i);
+ return FRSH_ERR_RESOURCE_ID_INVALID;
+ }
+ fc->ra = ra;
+ }
+ return 0;
+}
+
+/**
+ * Prepares a list of contracts to pass to resource manager for (re)reserving.
+ *
+ * @todo Needs to be changed for compatibility with transactions.
+ *
+ * @param resource Resource for which to rebalance capacity and negotiate new contracts
+ * @param fcb_contract New requests to negotiate
+ * @param num The number of elements in @a fcb_contract
+ * @param[out] rl List with changed contracts to be commited
+ */
+static void
+prepare_reservation_list(struct resource *resource,
+ struct fcb_contract *fcb_contract[], int num)
+{
+ int i;
+ fosa_abs_time_t now;
+ struct fcb_contract *fc;
+
+ reservation_list_init_head(&resource->rl);
+ resource->rl.length = 0;
+ for (i=0; i<num; i++) {
+ assert(fcb_contract[i]->requested_contract != NULL);
+ reservation_list_insert(&resource->rl, fcb_contract[i]);
+ resource->rl.length++;
+ }
+ fosa_clock_get_time(CLOCK_REALTIME, &now);
+ ul_list_for_each(sc_contracts, resource, fc) {
+ if (fosa_abs_time_smaller(fc->end_of_stability_period, now) &&
+ fc->requested_contract == NULL) /* Do not insert contract inserted above */
+ {
+ reservation_list_insert(&resource->rl, fc);
+ resource->rl.length++;
+ }
+ }
+}
+
+static int
+reserve_resource(struct resource *resource)
+{
+ int ret, i;
+ fres_contract_ptr_seq contracts;
+ struct fres_contract *c;
+ struct fcb_contract *fc;
+ CORBA_Environment ev;
+
+ if (!forb_sequence_alloc_buf(&contracts, resource->rl.length)) {
+ ret = errno;
+ goto err;
+ }
+ forb_sequence_length(&contracts) = resource->rl.length;
+
+ i=0;
+ /* Prepare FORB sequence */
+ ul_list_for_each(reservation_list, &resource->rl, fc) {
+ c = NULL;
+ if (fc->to_be_reserved_contract)
+ /* Contract without spare capacity */
+ c = fc->to_be_reserved_contract;
+ else if (fc->requested_contract)
+ c = fc->requested_contract;
+ assert(c);
+ forb_sequence_elem(&contracts, i++) = c;
+ }
+
+ /* Reserve contract */
+ ret = fres_resource_manager_reserve_contracts(resource->mng, &contracts, &ev);
+ if (forb_exception_occurred(&ev)) {
+ ret = fres_forbex2err(&ev);
+ ul_logerr("FORB exception when reserving contracts\n");
+ goto err_free;
+ }
+ if (ret < 0) {
+ ul_logerr("Contract reservation error %d\n", ret);
+ ret = FRES_ERR_ADMISSION_TEST;
+ goto err_free;
+ } else if (ret == 0)
+ ret = FRSH_NO_ERROR;
+ else if (ret == 1)
+ ret = FRSH_ERR_CONTRACT_REJECTED;
+ else
+ assert(false);
+err_free:
+ forb_sequence_free_buf(&contracts, forb_no_destructor);
+err:
+ return ret;
+}
+
+/**
+ *
+ *
+ * @param resource Resource for which to rebalance capacity and negotiate new contracts
+ * @param rl List with changed contracts to be commited
+ *
+ * @return Zero on success, non-zero error code on error
+ */
+static int
+rebalance_spare_capacity_and_reserve(struct resource *resource)
+{
+ int ret;
+ struct reservation_list *rl = &resource->rl;
+ struct fcb_contract *fc;
+ fres_block_spare_capacity *s;
+
+ /* Initialize optimization */
+ ul_list_for_each(reservation_list, rl, fc) {
+ fc->to_be_reserved_contract =
+ fc->requested_contract ? fres_contract_duplicate(fc->requested_contract) :
+ fc->user_contract ? fres_contract_duplicate(fc->user_contract) :
+ NULL;
+ assert(fc->to_be_reserved_contract != NULL);
+
+ s = fres_contract_get_spare_capacity(fc->to_be_reserved_contract);
+ if (s && s->granularity == FRSH_GR_DISCRETE) {
+ fc->sc_variant.initial = s->variants._length - 1;
+ fc->sc_variant.try = fc->sc_variant.initial;
+ }
+ }
+
+ bool all_combinations_tried;
+ int criterion, best_criterion = -1;
+ struct fcb_contract *fcb_changed;
+ /* Exhaustive search. Try all combinations of spare capacity
+ * variants and find the one with best creterion. */
+ do {
+ all_combinations_tried = true;
+ fcb_changed = NULL;
+ criterion = 0;
+ /* Prepare spare capacity variant */
+ ul_list_for_each(reservation_list, rl, fc) {
+ s = fres_contract_get_spare_capacity(fc->to_be_reserved_contract);
+ /* TODO: Simulate continuous granularity by discretization */
+ if (s && s->granularity == FRSH_GR_DISCRETE) {
+ fres_container_copy(fc->to_be_reserved_contract->container,
+ forb_sequence_elem(&s->variants, fc->sc_variant.try));
+ criterion += fc->sc_variant.try;
+
+ if (fcb_changed == NULL) {
+ /* Chnage tried variant for the next round */
+ fc->sc_variant.try = fc->sc_variant.try > 0 ?
+ fc->sc_variant.try - 1 :
+ s->variants._length - 1;
+ /* Do not change other
+ * contracts unless we have
+ * tried all variants */
+ if (fc->sc_variant.try != fc->sc_variant.initial) {
+ fcb_changed = fc;
+ }
+ }
+ if (fc->sc_variant.try != fc->sc_variant.initial)
+ all_combinations_tried = false;
+ }
+ }
+
+ if (criterion > best_criterion) {
+ ret = reserve_resource(resource);
+ switch (ret) {
+ case FRSH_NO_ERROR:
+ best_criterion = criterion;
+ break;
+ case FRSH_ERR_CONTRACT_REJECTED:
+ break;
+ default:
+ goto err;
+ }
+ }
+ } while (!all_combinations_tried);
+
+ if (best_criterion == -1) {
+ ret = FRSH_ERR_CONTRACT_REJECTED;
+ } else {
+ /* At least some variant succeeded */
+ ret = 0;
+ sc_contracts_init_head(resource);
+ ul_list_for_each(reservation_list, rl, fc) {
+ s = fres_contract_get_spare_capacity(fc->to_be_reserved_contract);
+ if (s && s->granularity == FRSH_GR_DISCRETE) {
+ sc_contracts_insert(resource, fc);
+ }
+ }
+ }
+err:
+ ul_list_for_each(reservation_list, rl, fc) {
+ fres_contract_destroy(fc->to_be_reserved_contract);
+ fc->to_be_reserved_contract = NULL;
+ }
+ return ret;
+}
+
+/**
+ * Create/change VReses according to @a schedulable_contracts.
+ *
+ * There might be more allocators for schedulable contracts, so merge
+ * adjacent vreses with the same allocator together and create/change
+ * them in one step. Also the order of schedulable contracts might be
+ * different from the initial order od ids in commit_contracts()
+ * therefore we have to search for every contract.
+ */
+static int
+change_vreses(struct fcb *fcb, fres_contract_ptr_seq *schedulable_contracts)
+{
+ struct res_alloc *last_ra = NULL;
+ fres_contract_ptr_seq vreses;
+ int i, ret = 0;
+ CORBA_Environment ev;
+
+ if (!forb_sequence_alloc_buf(&vreses, schedulable_contracts->_length)) {
+ return errno;
+ }
+ vreses._length = 0;
+
+ for (i=0; i<schedulable_contracts->_length; i++) {
+ struct fcb_contract *fc;
+ struct fres_contract *sc = schedulable_contracts->_buffer[i];
+
+ log_contract("Changing VRES", i, sc);
+
+ fc = fcb_contract_find(fcb, &sc->id);
+ assert(fc != NULL);
+
+ if (true /* TODO: if the schedulable contract is changed */) {
+ if (last_ra != fc->ra) {
+ if (vreses._length) {
+ ret = fres_resource_allocator_change_vreses(last_ra->ra,
+ &vreses, &ev);
+ if (forb_exception_occurred(&ev)) {
+ ret = fres_forbex2err(&ev);
+ goto err;
+ }
+ if (ret) goto err;
+ }
+ vreses._length = 0;
+ }
+ vreses._buffer[vreses._length] = sc;
+ vreses._length++;
+ last_ra = fc->ra;
+
+ }
+ }
+ if (last_ra) {
+ ret = fres_resource_allocator_change_vreses(last_ra->ra,
+ &vreses, &ev);
+ if (forb_exception_occurred(&ev))
+ ret = fres_forbex2err(&ev);
+ }
+err:
+ forb_sequence_free_buf(&vreses, forb_no_destructor);
+ return ret;
+}
+
+void
+free_fcb_contracts(struct fcb_contract *fcb_contracts[], int num)
+{
+ int i;
+ struct fcb_contract *fc;
+ for (i=0; i<num; i++) {
+ fc = fcb_contracts[i];
+ if (fc && !fc->user_contract) {
+ fc->requested_contract = NULL; /* Destroyed by FORB */
+ fcb_contract_destroy(fc);
+ }
+ }
+ free(fcb_contracts);
+}
+
+int
+commit_resource(struct resource *resource,
+ fres_contract_ptr_seq **schedulable_contracts)
+{
+ int ret;
+ fres_contract_id_seq commit_ids;
+ int i;
+ struct fcb_contract *fc;
+ CORBA_Environment ev;
+
+ if (!forb_sequence_alloc_buf(&commit_ids, resource->rl.length)) {
+ ret = errno;
+ goto err;
+ }
+
+ commit_ids._length = resource->rl.length;
+ i=0;
+ ul_list_for_each(reservation_list, &resource->rl, fc) {
+ forb_sequence_elem(&commit_ids, i) = fc->id;
+ i++;
+ }
+
+ fres_resource_manager_commit_contracts(resource->mng, &commit_ids,
+ schedulable_contracts, &ev);
+ if (forb_exception_occurred(&ev)) {
+ ret = fres_forbex2err(&ev);
+ goto err_free;
+ }
+ return 0;
+err_free:
+ forb_sequence_free_buf(&commit_ids, forb_no_destructor);
+err:
+ return ret;
+}
+
+int cancel_reservations(struct resource *resource)
+{
+ int ret;
+ fres_contract_id_seq commit_ids;
+ int i;
+ struct fcb_contract *fc;
+ CORBA_Environment ev;
+
+ if (!forb_sequence_alloc_buf(&commit_ids, resource->rl.length)) {
+ ret = errno;
+ goto err;
+ }
+
+ commit_ids._length = resource->rl.length;
+ i=0;
+ ul_list_for_each(reservation_list, &resource->rl, fc) {
+ forb_sequence_elem(&commit_ids, i) = fc->id;
+ i++;
+ }
+
+ fres_resource_manager_cancel_reservations(resource->mng, &commit_ids, &ev);
+ if (forb_exception_occurred(&ev)) {
+ ret = fres_forbex2err(&ev);
+ goto err_free;
+ }
+
+ return 0;
+err_free:
+ forb_sequence_free_buf(&commit_ids, forb_no_destructor);
+err:
+ return ret;
+}
+
+/* Add new contracts to our fcb database for later
+ * reference. Canceled contracts are removed below. */
+int
+fcb_remember_contracts(struct fcb *fcb,
+ struct fcb_contract **fcb_contracts, int num)
+{
+ struct fcb_contract *fc;
+ int i;
+
+ for (i=0; i<num; i++) {
+ fc = fcb_contracts[i];
+
+ if (fc->user_contract) {
+ if (fres_contract_get_num_blocks(fc->requested_contract) > 0) {
+ /* Renegotiation */
+ fres_contract_destroy(fc->user_contract);
+ fc->user_contract = fres_contract_duplicate(fc->requested_contract);
+ /* Note: requested_contract is also
+ * pointed by contracts parameter and
+ * will be freed by FORB. */
+ fc->requested_contract = NULL;
+ }
+ } else {
+ /* Insert new contracts */
+ fcb_contract_insert(fcb, fcb_contracts[i]);
+ fc->user_contract = fres_contract_duplicate(fc->requested_contract);
+ fc->requested_contract = NULL;
+ /* See the note above. */
+ }
+ }
+ return 0;
+}
+
+int
+fcb_remember_schedulable_contracts(struct fcb *fcb,
+ fres_contract_ptr_seq *schedulable_contracts)
+{
+ struct fcb_contract *fc;
+ int i;
+ for (i=0; i<schedulable_contracts->_length; i++) {
+ struct fres_contract *sc = schedulable_contracts->_buffer[i];
+ fc = fcb_contract_find(fcb, &sc->id);
+ assert(fc != NULL);
+ fres_contract_destroy(fc->schedulable_contract);
+ fc->schedulable_contract = fres_contract_duplicate(sc);
+ assert(fc->schedulable_contract);
+ }
+ return 0;
+}
+
+static int
+reject_transactions(struct fcb_contract *fcb_contracts[], int num)
+{
+ int i;
+ for (i = 0; i < num; i++) {
+ if (fcb_contracts[i]->transaction)
+ return FRES_ERR_VRES_PART_OF_TRANSACTION;
+ }
+ return 0;
+}
+
+CORBA_long
+negotiate_contracts(fres_contract_broker obj,
+ const fres_contract_ptr_seq* contracts,
+ fres_contract_id_seq** ids_out,
+ CORBA_Environment *ev)
+{
+ struct fcb *fcb = o2fcb(obj);
+ struct resource *resource = NULL;
+ int ret = 0;
+ forb_server_id app;
+ fres_contract_ptr_seq *schedulable_contracts;
+ struct fcb_contract **fcb_contracts;
+ unsigned i;
+ int num = contracts->_length;
+
+ /* Prepare output sequence for the case we return eariler with
+ * an error */
+ forb_sequence_alloc(*ids_out, 0);
+ if (!*ids_out) {
+ ev->major = FORB_EX_NO_MEMORY;
+ goto err;
+ }
+ CORBA_sequence_set_release(*ids_out, CORBA_TRUE);
+
+ forb_get_req_source(obj, &app);
+
+ fcb_contracts = malloc(sizeof(fcb_contracts[0])*num);
+ if (!fcb_contracts) {
+ ret = errno;
+ goto err;
+ }
+ memset(fcb_contracts, 0, sizeof(fcb_contracts[0])*num);
+
+ ret = prepare_fcb_contracts(fcb, fcb_contracts,
+ contracts->_buffer, num);
+ if (ret)
+ goto err_free_fcb_contracts;
+
+ ret = reject_transactions(fcb_contracts, num);
+ if (ret)
+ goto err_free_fcb_contracts;
+ ret = check_and_setup_resource(fcb, fcb_contracts, &resource,
+ &app, num);
+ if (ret)
+ goto err_free_fcb_contracts;
+
+ prepare_reservation_list(resource, fcb_contracts, num);
+
+ /* Reserve contracts */
+ ret = rebalance_spare_capacity_and_reserve(resource);
+ if (ret) {
+ if (ret == FRSH_ERR_CONTRACT_REJECTED) {
+ ul_logmsg("Contract(s) was/were rejected\n");
+ } else {
+ char msg[100];
+ fres_strerror(ret, msg, sizeof(msg));
+ ul_logerr("Reservation error: %s\n", msg);
+ }
+ goto err_free_fcb_contracts;
+ }
+
+ /* Commit contracts */
+ ret = commit_resource(resource, &schedulable_contracts);
+ if (ret)
+ goto err_cancel_reservation;
+
+ fcb_remember_contracts(fcb, fcb_contracts, num);
+ fcb_remember_schedulable_contracts(fcb, schedulable_contracts);
+
+ ret = change_vreses(fcb, schedulable_contracts);
+ if (ret)
+ goto err_cancel_reservation;
+
+ forb_sequence_free(schedulable_contracts, fres_contract_ptr_destroy);
+ if (ret != 0) {
+ ul_logerr("VRes was not created\n");
+ goto err_cancel_contracts;
+ }
+
+
+ /* Return IDs and delete canceled contracts from out database */
+ if (!forb_sequence_alloc_buf(*ids_out, num)) {
+ ev->major = FORB_EX_NO_MEMORY;
+ goto err_cancel_contracts;
+ }
+ (*ids_out)->_length = num;
+ for (i=0; i<num; i++) {
+ struct fcb_contract *fc = fcb_contracts[i];
+ forb_sequence_elem(*ids_out, i) = fc->id;
+
+ if (fc->requested_contract &&
+ fres_contract_get_num_blocks(fc->requested_contract) == 0) {
+ fcb_contract_delete(fcb, fc);
+ /* Note: requested_contract is also pointed by
+ * contracts parameter and will be freed by FORB. */
+ fc->requested_contract = NULL;
+ fcb_contract_destroy(fc);
+ }
+ }
+ return 0;
+
+err_cancel_contracts:
+ /* TODO */
+ goto err_free_fcb_contracts;
+err_cancel_reservation:
+ cancel_reservations(resource);
+err_free_fcb_contracts:
+ free_fcb_contracts(fcb_contracts, num);
+err:
+ return ret;
+}
+
+void redistribute_spare_capacity(fres_contract_broker obj,
+ const frsh_resource_type_t restype,
+ const frsh_resource_id_t resid,
+ CORBA_Environment *ev)
+{
+ struct fcb *fcb = o2fcb(obj);
+ struct res_key key = {restype, resid };
+ struct resource *resource;
+
+ resource = fcb_resource_find(fcb, &key);
+
+ prepare_reservation_list(resource, NULL, 0);
+
+/* forb_sequence_alloc(ids, rl.length); */
+/* if (!ids || !ids->_buffer) { */
+/* ev->major = FORB_EX_NO_MEMORY; */
+/* goto err_free_fcb_contracts; */
+/* } */
+/* CORBA_sequence_set_release(ids, CORBA_TRUE); */
+/* *ids_out = ids; /\* ids is freed by FORB *\/ */
+
+
+ rebalance_spare_capacity_and_reserve(resource);
+ /* Commit */
+}
+
+CORBA_long register_resource(fres_contract_broker obj,
+ const frsh_resource_type_t restype,
+ const frsh_resource_id_t resid,
+ const fres_resource_desc *desc,
+ CORBA_Environment *ev)
+{
+ struct fcb *fcb = o2fcb(obj);
+ struct resource *res, *res2;
+
+ res = malloc(sizeof(*res));
+ if (!res) goto err;
+ memset(res, 0, sizeof(*res));
+ res->key.type = restype;
+ res->key.id = resid;
+ res2 = fcb_resource_find(fcb, &res->key);
+ if (res2) {
+ if (forb_object_is_stale(res2->mng)) {
+ ul_logmsg("Removing stale manager for resource %d.%d\n",
+ restype, resid);
+ forb_object_release(res2->mng);
+ fcb_resource_delete(fcb, res2);
+ /* TODO: Delete also all allocators associated
+ * with this stale resource manager. */
+ free(res);
+ res = res2;
+ } else {
+ ul_logerr("Resource manager %d.%d already registered\n",
+ restype, resid);
+ goto free_err;
+ }
+ }
+ res->mng = forb_object_duplicate(desc->manager);
+ res->name = desc->name;
+
+ fcb_alloc_init_root_field(res);
+ sc_contracts_init_head(res);
+ ul_logmsg("Registering manager for resource \"%s\" (%d.%d)\n",
+ res->name, restype, resid);
+ fcb_resource_insert(fcb, res);
+ return 0;
+free_err:
+ free(res);
+err:
+ return -1;
+}
+
+
+CORBA_long register_allocator(fres_contract_broker obj,
+ const frsh_resource_type_t restype,
+ const frsh_resource_id_t resid,
+ const fres_resource_allocator ra_obj,
+ CORBA_Environment *ev)
+{
+ struct fcb *fcb = o2fcb(obj);
+ struct resource *res;
+ struct res_alloc *ra;
+ struct res_key resource;
+ forb_server_id server_id;
+ char server_id_str[40];
+ int ret;
+
+ forb_get_server_id(ra_obj, &server_id);
+ forb_server_id_to_string(server_id_str, &server_id, sizeof(server_id_str));
+ ul_logmsg("Registering allocator for resource %d.%d in app %s\n",
+ restype, resid, server_id_str);
+
+ resource.type = restype;
+ resource.id = resid;
+ res = fcb_resource_find(fcb, &resource);
+ if (!res) {
+ ul_logerr("No manager found for %d.%d. Unable to register the allocator!\n",
+ restype, resid);
+ ret = FRES_ERR_NO_RESOURCE_MANAGER;
+ goto err;
+ }
+ ra = fcb_alloc_find(res, &server_id);
+ if (ra) {
+ char *str = forb_object_to_string(ra_obj);
+ ul_logerr("Allocator from already registered (%s)\n",
+ str);
+ forb_free(str);
+ ret = FRES_ERR_ALLOCATOR_ALREADY_REGISTERED;
+ goto err;
+ }
+ ra = malloc(sizeof(*ra));
+ if (!ra) {
+ ret = ENOMEM;
+ goto err;
+ }
+ ra->app = server_id;
+ ra->ra = forb_object_duplicate(ra_obj);
+ fcb_alloc_insert(res, ra);
+ return 0;
+err:
+ return ret;
+}
+
+void get_resources(fres_contract_broker obj, fres_resource_seq** resources, CORBA_Environment *ev)
+{
+ struct fcb *fcb = o2fcb(obj);
+ fres_resource_seq *seq;
+ struct resource *res;
+ int n;
+
+ seq = malloc(sizeof(*seq));
+ if (!seq) {
+ ev->major = FORB_EX_NO_MEMORY;
+ return;
+ }
+ memset(seq, 0, sizeof(*seq));
+
+ n=0;
+ gavl_cust_for_each(fcb_resource, fcb, res) {
+ n++;
+ }
+
+ seq->_buffer = CORBA_sequence_fres_resource_allocbuf(n);
+ seq->_maximum = n;
+ seq->_length = n;
+
+ n = 0;
+ gavl_cust_for_each(fcb_resource, fcb, res) {
+ seq->_buffer[n].restype = res->key.type;
+ seq->_buffer[n].resid = res->key.id;
+ seq->_buffer[n].desc.manager = res->mng;
+ seq->_buffer[n].desc.name = res->name;
+ n++;
+ }
+
+ *resources = seq;
+}
+
+static bool
+transaction_has_spare_capacity(const fres_transaction_t* transaction)
+{
+ struct fres_contract **c;
+ forb_sequence_foreach(&transaction->contracts, c)
+ if (fres_contract_get_spare_capacity(*c))
+ return true;
+ return false;
+}
+
+static int
+transaction_get_resources(struct fcb *fcb, struct fcb_contract *fc[],
+ int num, struct res_array *res_array)
+{
+ int i;
+ struct resource *resource;
+ struct res_key key;
+ int ret;
+
+ for (i = 0; i < num; i++) {
+ get_fc_res_key(fc[i], &key);
+ resource = fcb_resource_find(fcb, &key);
+ ret = res_array_insert(res_array, resource);
+ if (ret == -1) {
+ ret = FRSH_ERR_INTERNAL_ERROR;
+ goto err;
+ }
+ }
+ ret = 0;
+err:
+ return ret;
+}
+
+CORBA_long
+negotiate_transaction(fres_contract_broker _obj,
+ const fres_transaction_t* transaction,
+ CORBA_Environment *ev)
+{
+ struct fcb *fcb = o2fcb(_obj);
+ struct fcb_contract **fcb_contracts, *fc;
+ const fres_contract_ptr_seq* user_contracts = &transaction->contracts;
+ int i, ret, num = user_contracts->_length;
+ struct res_array res_array;
+ struct res_key key;
+ struct resource *resource;
+ fres_contract_ptr_seq *schedulable_contracts;
+ struct fcb_transaction *ft;
+
+ ul_logmsg("Negotiating transaction '%s' with %d contracts\n", transaction->name, num);
+ if (transaction_has_spare_capacity(transaction)) {
+ ret = FRES_ERR_SPARE_CAPACITY_NOT_SUPPORTED;
+ goto err;
+ }
+
+ fcb_contracts = malloc(sizeof(*fcb_contracts)*num);
+ if (!fcb_contracts) {
+ ret = errno;
+ goto err;
+ }
+ memset(fcb_contracts, 0, sizeof(*fcb_contracts)*num);
+
+ ret = prepare_fcb_contracts(fcb, fcb_contracts,
+ user_contracts->_buffer, num);
+ if (ret)
+ goto err_free_fcb_contracts;
+
+ res_array_init_array_field(&res_array);
+ ret = transaction_get_resources(fcb, fcb_contracts, num, &res_array);
+
+ gsa_cust_for_each(res_array, &res_array, resource) {
+ reservation_list_init_head(&resource->rl);
+ resource->rl.length = 0;
+ for (i = 0; i < num; i++) {
+ fc = fcb_contracts[i];
+ get_fc_res_key(fc, &key);
+ if (res_key_cmp(&key, &resource->key) == 0) {
+ reservation_list_insert(&resource->rl, fc);
+ resource->rl.length++;
+ }
+ }
+ }
+ gsa_cust_for_each(res_array, &res_array, resource) {
+ ret = reserve_resource(resource);
+ if (ret) {
+ ul_logerr("Reservation failed\n");
+ goto err_cancel_reservation;
+ }
+ }
+ fcb_remember_contracts(fcb, fcb_contracts, num);
+ gsa_cust_for_each(res_array, &res_array, resource) {
+ ret = commit_resource(resource, &schedulable_contracts);
+ if (ret) {
+ ul_logerr("Commit failed\n");
+ goto err_cancel_reservation;
+ }
+ fcb_remember_schedulable_contracts(fcb, schedulable_contracts);
+ forb_sequence_free(schedulable_contracts, fres_contract_ptr_destroy);
+ }
+ /* TODO: After we distinguish between APP and a real
+ * allocator, allocate VRESes (and perform mode change) here.
+ * Only if the resource allocator is not known at this point,
+ * wait with allocation the same way as it is done now. For
+ * this we will need more information about allocators i.e.
+ * its type (centralized, distributed, in app, ...). Too
+ * compilcated ;-( */
+
+ ft = fcb_transaction_new(transaction->name);
+ if (!ft) {
+ ret = errno;
+ goto err_cancel_reservation;
+ }
+ enum { NONE, CANCELATION, NEGOTIATION } op = NONE;
+ for (i = 0; i < num; i++) {
+ fc = fcb_contracts[i];
+ if (fc->requested_contract &&
+ fres_contract_get_num_blocks(fc->requested_contract) == 0) {
+ assert(i == 0 || op == CANCELATION);
+ op = CANCELATION;
+ /* TODO: Review and test transaction cancelation!!! */
+ fcb_contract_delete(fcb, fc);
+ /* Note: requested_contract is also pointed by
+ * contracts parameter and will be freed by FORB. */
+ fc->requested_contract = NULL;
+ fcb_contract_destroy(fc);
+ } else {
+ assert(i == 0 || op == NEGOTIATION);
+ op = NEGOTIATION;
+ tran_contract_insert_at(ft, fc, i);
+ fc->transaction = ft;
+ }
+ }
+ switch (op) {
+ case NEGOTIATION:
+ fcb_transaction_insert(fcb, ft);
+ break;
+ case CANCELATION:
+ fcb_transaction_delete(fcb, ft);
+ fcb_transaction_destroy(ft);
+ break;
+ default:
+ assert(false);
+ }
+ res_array_delete_all(&res_array);
+ return 0;
+err_cancel_reservation:
+ gsa_cust_for_each(res_array, &res_array, resource) {
+ cancel_reservations(resource);
+ }
+ res_array_delete_all(&res_array);
+err_free_fcb_contracts:
+ free_fcb_contracts(fcb_contracts, num);
+err:
+ return ret;
+}
+
+CORBA_long
+wait_transaction(fres_contract_broker _obj,
+ const CORBA_char * name,
+ fres_transaction_t** transaction,
+ CORBA_Environment *ev)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+CORBA_long
+allocate_transaction_vres(fres_contract_broker _obj,
+ const CORBA_char * name,
+ const CORBA_long index,
+ fres_contract_id_t *id,
+ CORBA_Environment *ev)
+{
+ struct fcb *fcb = o2fcb(_obj);
+ struct fcb_transaction *ft;
+ struct fcb_contract *fc;
+ int ret;
+ struct res_alloc *ra;
+ char * const *n = (char * const *)&name;
+ struct res_key key;
+ struct resource *resource;
+ fres_contract_ptr_seq vreses;
+ CORBA_Environment ev2;
+ forb_server_id app;
+#define GOTO(label, error) do { ret = (error); goto label; } while(0)
+
+ ul_logmsg("Allocate transaction VRES '%s'[%d]\n", name, index);
+
+ ft = fcb_transaction_find(fcb, n);
+ if (!ft) GOTO(err, FRES_ERR_TRANSACTION_NOT_FOUND);
+
+ fc = tran_contract_indx2item(ft, index);
+ if (!fc) GOTO(err, FRSH_ERR_TOO_LARGE);
+
+ /* TODO: If we allow migration of task between resources (due
+ * to spare capacity reallocation), the following check will
+ * need reworking/enhancing. */
+ if (fc->ra) GOTO(err, FRES_ERR_VRES_ALREADY_ALLOCATED);
+
+ if (!get_fc_res_key(fc, &key))
+ GOTO(err, FRSH_ERR_RESOURCE_ID_INVALID);
+ resource = fcb_resource_find(fcb, &key);
+ if (!resource)
+ GOTO(err, FRES_ERR_NO_RESOURCE_MANAGER);
+
+ forb_get_req_source(_obj, &app);
+ /* Find allocator for the requested VRES */
+ ra = fcb_alloc_find(resource, &app);
+ if (!ra) {
+ char str[60];
+ forb_server_id_to_string(str, &app, sizeof(str));
+ ul_logerr("No resource allocator found for %d.%d and %s\n",
+ resource->key.type, resource->key.id, str);
+ GOTO(err, FRES_ERR_NO_RESOURCE_ALLOCATOR);
+ }
+ fc->ra = ra;
+
+ if (!forb_sequence_alloc_buf(&vreses, 1))
+ GOTO(err, errno);
+
+ assert(fc->schedulable_contract);
+ forb_sequence_elem(&vreses, 0) = fc->schedulable_contract;
+ forb_sequence_length(&vreses) = 1;
+ ret = fres_resource_allocator_change_vreses(ra->ra, &vreses, &ev2);
+ ul_logerr("Err = %d\n", ret);
+ if (forb_exception_occurred(&ev2))
+ GOTO(err_free, fres_forbex2err(&ev2));
+ if (ret)
+ goto err_free;
+ *id = fc->id;
+
+ ret = 0;
+err_free:
+ forb_sequence_free_buf(&vreses, forb_no_destructor);
+err:
+ return ret;
+}
+
+
+#if CONFIG_FCB_INET && !CONFIG_FORB_PROTO_INET_DEFAULT
+static int register_inet_port(forb_orb orb)
+{
+ forb_port_t *port = forb_malloc(sizeof(*port));
+ int ret;
+ struct in_addr listen_on;
+
+ if (!port)
+ return -1;
+ memset(port, 0, sizeof(*port));
+ listen_on.s_addr = INADDR_ANY;
+ ret = forb_inet_port_init(&port->desc, listen_on, 0);
+ if (ret)
+ return ret;
+ ret = forb_register_port(orb, port);
+ return ret;
+}
+#endif
+
+struct forb_fres_contract_broker_impl impl = {
+ .negotiate_contracts = negotiate_contracts,
+ .register_resource = register_resource,
+ .register_allocator = register_allocator,
+ .redistribute_spare_capacity = redistribute_spare_capacity,
+ .get_resources = get_resources,
+ .negotiate_transaction = negotiate_transaction,
+ .wait_transaction = wait_transaction,
+ .allocate_transaction_vres = allocate_transaction_vres,
+};
+
+void peer_discovery_callback(const forb_orb peer_orb, const char *orb_id)
+{
+ forb_server_id server_id;
+ char server_id_str[sizeof(forb_server_id)*2+1];
+
+ forb_get_server_id(peer_orb, &server_id);
+ forb_server_id_to_string(server_id_str, &server_id, sizeof(server_id_str));
+#if 0
+ ul_logmsg("peer discovered: %s (orb_id '%s')\n", server_id_str, orb_id);
+#endif
+
+ if (orb_id == NULL)
+ return;
+
+ if (strcmp(orb_id, "org.frescor.fcb") == 0) {
+ fosa_abs_time_t now;
+ fosa_rel_time_t delay;
+ fosa_clock_get_time(CLOCK_REALTIME, &now);
+ delay = fosa_abs_time_extract_interval(start_time, now);
+ ul_logmsg("node joined: %s (time %ld ms)\n", server_id_str,
+ fosa_rel_time_to_msec(delay));
+ }
+}
+
+void peer_dead_callback(const forb_orb peer_orb, const char *orb_id)
+{
+}
+
+static struct option long_opts[] = {
+ { "daemon", optional_argument, NULL, 'd' },
+ { "loglevel", required_argument, NULL, 'l' },
+ { 0, 0, 0, 0}
+};
+
+static void
+usage(void)
+{
+ printf("usage: fcb [ options ]\n");
+ printf(" -d, --daemon [pid-file] go to background after FORB initialization\n");
+ printf(" -l, --loglevel <number>|<domain>=<number>,...\n");
+}
+
+int print_log_domain(ul_log_domain_t *domain, void *context)
+{
+ printf("%s = %d\n", domain->name, domain->level);
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ forb_orb orb;
+ struct fcb fcb_data;
+ fres_contract_broker fcb;
+ forb_executor_t executor;
+ int ret;
+ forb_init_attr_t attr = {
+ .orb_id = "org.frescor.fcb",
+ .peer_discovery_callback = peer_discovery_callback,
+ .peer_dead_callback = peer_dead_callback,
+ .fixed_tcp_port = FCB_TCP_PORT,
+#ifdef CONFIG_FORB_PROTO_INET_DEFAULT
+ .fixed_server_id = FCB_SERVER_ID,
+ .redistribute_hellos = true,
+#endif
+ };
+ int opt;
+
+ while ((opt = getopt_long(argc, argv, "d::hl:", &long_opts[0], NULL)) != EOF) {
+ switch (opt) {
+ case 'l':
+ if (*optarg == '?') {
+ ul_logreg_for_each_domain(print_log_domain, NULL);
+ exit(0);
+ }
+ {
+ int ret;
+ ret = ul_log_domain_arg2levels(optarg);
+ if (ret)
+ error(1, EINVAL, "Error parsing -l argument at char %d\n", ret);
+ }
+ break;
+ case 'd':
+ opt_daemon = true;
+ opt_pidfile = optarg;
+ break;
+ case 'h':
+ /*default:*/
+ usage();
+ exit(opt == 'h' ? 0 : 1);
+ }
+ }
+
+ memset(&fcb_data, 0, sizeof(fcb_data));
+ fosa_clock_get_time(CLOCK_REALTIME, &start_time);
+
+ if (opt_daemon)
+ forb_daemon_prepare(opt_pidfile);
+
+ orb = forb_init(&argc, &argv, &attr);
+ if (!orb) error(1, errno, "FORB initialization failed");
+
+#if CONFIG_FCB_INET && !CONFIG_FORB_PROTO_INET_DEFAULT
+ ret = register_inet_port(orb);
+ if (ret) error(0, errno, "INET port registration failed");
+#endif
+
+ fcb_resource_init_root_field(&fcb_data);
+ fcb_contract_init_root_field(&fcb_data);
+ fcb_transaction_init_root_field(&fcb_data);
+
+ fcb = forb_fres_contract_broker_new(orb, &impl, &fcb_data);
+ if (!fcb) error(1, errno, "forb_fres_contract_broker_new failed");
+
+ /* Prepare executor before we register the fcb reference,
+ * so that no reuqests are lost */
+ ret = forb_executor_init(&executor);
+ if (ret) error(1, errno, "forb_executor_init failed");
+
+ ret = forb_executor_register_object(&executor, fcb);
+ if (ret) error(1, errno, "forb_executor_register_object failed");
+
+ ret = forb_register_reference(fcb, fres_contract_broker_reg_name);
+ if (ret) error(1, errno, "forb_register_reference() failed");
+
+ ul_logmsg("Waiting for requests\n");
+ if (opt_daemon)
+ forb_daemon_ready();
+
+ ret = forb_executor_run(&executor);
+ if (ret) error(1, errno, "forb_executor_run failed");
+
+ return 0;
+}
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------------------- //
+// Copyright (C) 2006 - 2008 FRESCOR consortium partners: //
+// //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// Scuola Superiore Sant'Anna, ITALY //
+// Kaiserslautern University, GERMANY //
+// Univ. Politécnica Valencia, SPAIN //
+// Czech Technical University in Prague, CZECH REPUBLIC //
+// ENEA SWEDEN //
+// Thales Communication S.A. FRANCE //
+// Visual Tools S.A. SPAIN //
+// Rapita Systems Ltd UK //
+// Evidence ITALY //
+// //
+// See http://www.frescor.org for a link to partners' websites //
+// //
+// FRESCOR project (FP6/2005/IST/5-034026) is funded //
+// in part by the European Union Sixth Framework Programme //
+// The European Union is not liable of any use that may be //
+// made of this code. //
+// //
+// //
+// based on previous work (FSF) done in the FIRST project //
+// //
+// Copyright (C) 2005 Mälardalen University, SWEDEN //
+// Scuola Superiore S.Anna, ITALY //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// //
+// FSF API web pages: http:marte.unican.es/fsf/docs //
+// http:shark.sssup.it/contrib/first/docs/ //
+// //
+// This file is part of FORB (Frescor Object Request Broker) //
+// //
+// FORB is free software; you can redistribute it and/or modify it //
+// under terms of the GNU General Public License as published by the //
+// Free Software Foundation; either version 2, or (at your option) any //
+// later version. FORB is distributed in the hope that it will be //
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty //
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
+// General Public License for more details. You should have received a //
+// copy of the GNU General Public License along with FORB; see file //
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, //
+// Cambridge, MA 02139, USA. //
+// //
+// As a special exception, including FORB header files in a file, //
+// instantiating FORB generics or templates, or linking other files //
+// with FORB objects to produce an executable application, does not //
+// by itself cause the resulting executable application to be covered //
+// by the GNU General Public License. This exception does not //
+// however invalidate any other reasons why the executable file might be //
+// covered by the GNU Public License. //
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef _CM_IDL
+#define _CM_IDL
+
+#include "../contract/fres_contract_idl.idl"
+#include "../contract/fres_transaction_idl.idl"
+#include "../contract/fres_blocks.idl"
+#include "../resmng/frm.idl"
+#include "../resalloc/fra.idl"
+
+module fres {
+
+ /** Description of a resource */
+ struct resource_desc {
+ /** Manager */
+ resource_manager manager;
+ string name; /**< Human understandable name of the resource (used by frm_gui) */
+ };
+
+ struct resource {
+ frsh_resource_type_t restype;
+ frsh_resource_id_t resid;
+ resource_desc desc;
+ };
+
+ typedef sequence<resource> resource_seq;
+
+ interface contract_broker {
+ const string reg_name = "fcb";
+ /**
+ * Registers a resource with the contract broker
+ *
+ * @param restype
+ * @param resid
+ * @param res_desc Description of the resource
+ *
+ * @return Zero on success, non-zero error code on error.
+ */
+ long register_resource(in frsh_resource_type_t restype,
+ in frsh_resource_id_t resid,
+ in resource_desc res_desc);
+
+ /**
+ * Registers a resource allocator with the contract broker
+ *
+ * @param restype
+ * @param resid
+ * @param rs_obj
+ *
+ * @return Zero on success, non-zero error code on error.
+ */
+ long register_allocator(in frsh_resource_type_t restype,
+ in frsh_resource_id_t resid,
+ in resource_allocator rs_obj);
+
+ long deregister_allocator(in resource_allocator rs_obj);
+
+ /**
+ * This function performs a set of negotiation
+ * operations with one resource. The oprations can
+ * include: adding new contracts (neg), modifying
+ * existing vres (reneg) or cancelling existing vres
+ * (cancel). It is guarantied that either all
+ * operation will be completed or none of them.
+ *
+ * @param[in] contracts Contract(s) to negotiate,
+ * renegotiate or cancel. The operation on the
+ * contract is determined as follows:
+ * - neg: contracts without ID
+ * - cancel: contracts with an ID and without any block
+ * - reneg: contracts with ID and some blocks (the old
+ * contract will we replaced by the new one).
+ *
+ * @param[out] ids IDs of the newly negotiated
+ * contracts, if negotiation was successful. Ordering
+ * of IDs is the same as in @a contracts.
+ *
+ * @return Zero if all operations were successfully
+ * carried out, non-zero code on error or when
+ * negotiation failed.
+ */
+ long negotiate_contracts(in contract::ptr_seq contracts, out contract::id_seq ids);
+
+ /**
+ * Redistributes spare capacity for a given resource.
+ * This is meant as a support for resources with
+ * variable capacity (WiFi) as a mean for applications
+ * to adapt to the changed capacity.
+ *
+ * @param restype For which resource to perform
+ * redistribution.
+ */
+ void redistribute_spare_capacity(in frsh_resource_type_t restype,
+ in frsh_resource_id_t resid);
+
+ /**
+ * Returns sequence of registered resources.
+ *
+ * @param[out] resources
+ */
+ void get_resources(out resource_seq resources);
+
+ long negotiate_transaction(in transaction_t transaction);
+ long wait_transaction(in string name,
+ out transaction_t transaction);
+ long allocate_transaction_vres(in string name, in long index,
+ out contract::id_t cid);
+ };
+};
+
+#endif
--- /dev/null
+#ifndef FCB_CONTACT_INFO_H
+#define FCB_CONTACT_INFO_H
+
+#include <forb/types.h>
+
+#define FCB_TCP_PORT 24942
+#define FCB_SERVER_ID (forb_server_id){ .uuid = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 } }
+
+#endif
--- /dev/null
+#include <ul_gavlcust.h>
+
+___cut_here___;
+
+
+GAVL_CUST_NODE_INT_IMP(fcb_contract /* cust_prefix */, \
+ struct fcb /* cust_root_t */, \
+ struct fcb_contract /* cust_item_t */, \
+ fres_contract_id_t /* cust_key_t */, \
+ contracts /* cust_root_node */, \
+ node /* cust_item_node */, \
+ id /* cust_item_key */, \
+ fres_contract_id_cmp /* cust_cmp_fnc */);
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+shared_LIBRARIES = contract
+
+contract_SOURCES = fres_contract.c fres_container.c fres_error.c \
+ contract_func.c utils.c fres_transaction.c
+contract_CLIENT_IDL = fres_contract_idl.idl fres_blocks.idl \
+ fres_transaction_idl.idl
+
+fres_contract_idl_IDLFLAGS = --include=fres_contract_ser.h
+fres_blocks_IDLFLAGS = --include=idl_native.h
+
+include_HEADERS = fres_container.h fres_container_type.h \
+ fres_contract_type.h fres_contract_ser.h \
+ fres_container_internal.h idl_native.h \
+ fres_contract.h fres_error.h fres_transaction.h
+
+include_GEN_HEADERS = fres_contract_idl.h fres_blocks.h \
+ fres_transaction_idl.h
+
+SUBDIRS=tests
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file contract_func.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Wed Feb 18 15:35:25 2009
+ *
+ * @brief Helper contract manipulation functions
+ *
+ *
+ */
+
+
+#include <fres_contract.h>
+
+/**
+ * Convenience function to retrieve a deadline from contract.
+ *
+ * Deadline in contract can be specified directly as a interval or
+ * indirectly through contract period (d_equals_t). This functions
+ * retrieves the deadline from the correct field.
+ *
+ * @param[in] contract
+ * @param[out] deadline Where to store the deadline.
+ *
+ * @return True if the contract specifies the deadline, false if not.
+ */
+bool
+fres_contract_get_deadline(const frsh_contract_t *contract,
+ frsh_rel_time_t *deadline)
+{
+ fres_block_timing_reqs *timing;
+ bool has_deadline = false;
+
+ if (!contract || !deadline) {
+ goto error;
+ }
+
+ timing = fres_contract_get_timing_reqs(*contract);
+ if (timing) {
+ if (timing->d_equals_t) {
+ fres_block_basic *basic;
+ basic = fres_contract_get_basic(*contract);
+ *deadline = basic->period;
+ } else {
+ *deadline = timing->deadline;
+ }
+ has_deadline = true;
+ }
+error:
+ return has_deadline;
+}
+
+/**
+ * Convenience function to retrieve budget from a contract.
+ *
+ * @param[in] contract
+ * @param[out] budget Where to store the deadline.
+ *
+ * @return True if the contract specifies the budget, false if not.
+ */
+bool
+fres_contract_get_budget(const frsh_contract_t *contract,
+ frsh_rel_time_t *budget)
+{
+ fres_block_basic *basic;
+ basic = fres_contract_get_basic(*contract);
+ if (basic)
+ *budget = basic->budget;
+ return basic != NULL;
+}
+
+/**
+ * Convenience function to retrieve period from a contract.
+ *
+ * @param[in] contract
+ * @param[out] period Where to store the deadline.
+ *
+ * @return True if the contract specifies the period, false if not.
+ */
+bool
+fres_contract_get_period(const frsh_contract_t *contract,
+ frsh_rel_time_t *period)
+{
+ fres_block_basic *basic;
+ basic = fres_contract_get_basic(*contract);
+ if (basic)
+ *period = basic->period;
+ return basic != NULL;
+}
+
+frsh_contract_type_t
+fres_contract_get_type(const frsh_contract_t *contract)
+{
+ fres_block_basic *basic;
+ basic = fres_contract_get_basic(*contract);
+ if (basic)
+ return basic->contract_type;
+ else
+ return FRSH_CT_DUMMY;
+
+}
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------------------- //
+// Copyright (C) 2006 - 2008 FRESCOR consortium partners: //
+// //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// Scuola Superiore Sant'Anna, ITALY //
+// Kaiserslautern University, GERMANY //
+// Univ. Politécnica Valencia, SPAIN //
+// Czech Technical University in Prague, CZECH REPUBLIC //
+// ENEA SWEDEN //
+// Thales Communication S.A. FRANCE //
+// Visual Tools S.A. SPAIN //
+// Rapita Systems Ltd UK //
+// Evidence ITALY //
+// //
+// See http://www.frescor.org for a link to partners' websites //
+// //
+// FRESCOR project (FP6/2005/IST/5-034026) is funded //
+// in part by the European Union Sixth Framework Programme //
+// The European Union is not liable of any use that may be //
+// made of this code. //
+// //
+// //
+// based on previous work (FSF) done in the FIRST project //
+// //
+// Copyright (C) 2005 Mälardalen University, SWEDEN //
+// Scuola Superiore S.Anna, ITALY //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// //
+// FSF API web pages: http:marte.unican.es/fsf/docs //
+// http:shark.sssup.it/contrib/first/docs/ //
+// //
+// This file is part of FORB (Frescor Object Request Broker) //
+// //
+// FORB is free software; you can redistribute it and/or modify it //
+// under terms of the GNU General Public License as published by the //
+// Free Software Foundation; either version 2, or (at your option) any //
+// later version. FORB is distributed in the hope that it will be //
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty //
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
+// General Public License for more details. You should have received a //
+// copy of the GNU General Public License along with FORB; see file //
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, //
+// Cambridge, MA 02139, USA. //
+// //
+// As a special exception, including FORB header files in a file, //
+// instantiating FORB generics or templates, or linking other files //
+// with FORB objects to produce an executable application, does not //
+// by itself cause the resulting executable application to be covered //
+// by the GNU General Public License. This exception does not //
+// however invalidate any other reasons why the executable file might be //
+// covered by the GNU Public License. //
+////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @file fres_contract_idl.idl
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Sep 7 17:24:37 2008
+ *
+ * @brief Definitions of data types and constants for FRESCOR contracts.
+ *
+ */
+
+// FRSH mirrored types. For simplicity and compatibility with FRSH, we
+// use the values declared in FRSH headers instead of the values
+// declared here.
+native fosa_rel_time_t;
+native fosa_abs_time_t;
+
+enum frsh_resource_type_t {
+ FRSH_RT_PROCESSOR,
+ FRSH_RT_NETWORK,
+ FRSH_RT_MEMORY,
+ FRSH_RT_DISK
+};
+
+typedef unsigned long frsh_resource_id_t;
+
+enum frsh_workload_t {
+ FRSH_WT_BOUNDED,
+ FRSH_WT_INDETERMINATE,
+ FRSH_WT_SYNCHRONIZED
+};
+
+enum frsh_contract_type_t {
+ FRSH_CT_REGULAR,
+ FRSH_CT_BACKGROUND,
+ FRSH_CT_DUMMY
+};
+
+enum frsh_granularity_t {
+ FRSH_GR_CONTINUOUS,
+ FRSH_GR_DISCRETE
+};
+
+typedef long frsh_signal_t;
+typedef long frsh_signal_info_t;
+
+typedef struct frsh_csect_runtime {
+ long op_kind;
+ char obj_label[65];
+ fosa_rel_time_t wcet;
+ fosa_rel_time_t blocking;
+} frsh_csect_runtime_t;
+
+module fres {
+ native container_ptr;
+
+ /// Blocks from which contracts are composed
+ module block {
+ /// Contract label
+ struct label {
+ char label[32];
+ };
+
+ /// Resource for which this contract is
+ struct resource {
+ frsh_resource_type_t resource_type;
+ frsh_resource_id_t resource_id;
+ };
+
+ /// Basic contract parameters
+ struct basic {
+ // forb_contract_params_type == FORB_CONTRACT_PARAMS_BASIC
+ fosa_rel_time_t budget;
+ fosa_rel_time_t period;
+ frsh_workload_t workload;
+ frsh_contract_type_t contract_type;
+ };
+
+ /// Timing requirements
+ struct timing_reqs {
+ boolean d_equals_t;
+ fosa_rel_time_t deadline;
+ //TODO: Shall this singal info be
+ //present here, or it is better to
+ //pass is as parameter to bind.
+
+// frsh_signal_t budget_overrun_signal;
+// frsh_signal_info_t budget_overrun_siginfo;
+// frsh_signal_t deadline_miss_signal;
+// frsh_signal_info_t deadline_miss_siginfo;
+ };
+
+ /// Critical sections (for shared objects)
+ struct csects {
+ //frsh_csect_runtime_t sections;
+ sequence<frsh_csect_runtime> sections;
+ };
+
+ /// Spare capacity
+ struct spare_capacity {
+ fosa_rel_time_t budget; // FIXME: remove me after variants are fully supported
+ fosa_rel_time_t period; // FIXME: remove me after variants are fully supported
+ frsh_granularity_t granularity;
+ long importance;
+ long weight;
+ fosa_rel_time_t stability_time;
+ sequence<container_ptr> variants;
+ };
+
+ /// Power Management
+ struct power_management {
+ fosa_rel_time_t period;
+ fosa_rel_time_t max_budget[3];
+ fosa_rel_time_t min_budget[3];
+ fosa_rel_time_t min_expiration;
+ };
+
+ };
+
+};
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file fres_contract_container.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ *
+ * @brief Functions for manipulating with forb-based contracts.
+ *
+ *
+ */
+#include <fres_container.h>
+#include "fres_container_internal.h"
+#include <stdbool.h>
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <string.h>
+#include <forb/cdr.h>
+#include <stdio.h>
+#include "utils.h"
+
+UL_LOG_CUST(ulogd_fres_container);
+ul_log_domain_t ulogd_fres_container = {UL_LOGL_ERR, "fres_container"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(fres_container_logreg_domains, ulogd_fres_container);
+
+static void *
+fres_block_duplicate_spare_capacity(enum fres_block_type type, const void *block_data);
+
+#define desc_default(type) \
+ struct fres_block_desc desc_default_##type = { \
+ .name = #type, \
+ .size = sizeof(fres_block_##type), \
+ .serialize = (fres_block_serialize_fnc_t*)fres_block_##type##_serialize, \
+ .deserialize = (fres_block_deserialize_fnc_t*)fres_block_##type##_deserialize, \
+ .duplicate = fres_block_duplicate_default, \
+ .to_string = fres_block_##type##_to_string \
+ }
+
+int fres_block_label_to_string(char *dest, size_t size, enum fres_block_type type,
+ const void *block_data)
+{
+ const fres_block_label *b = block_data;
+ return snprintf(dest, size, "%s\n", b->label); /* FIXME: do not print more that 32 characters */
+}
+
+int fres_block_resource_to_string(char *dest, size_t size, enum fres_block_type type,
+ const void *block_data)
+{
+ static const char *res_names[] = {
+ [FRSH_RT_PROCESSOR] = "CPU",
+ [FRSH_RT_NETWORK] = "NET",
+ [FRSH_RT_MEMORY] = "MEM",
+ [FRSH_RT_DISK] = "DISK"
+ };
+
+ const fres_block_resource *b = block_data;
+ char res[10];
+ const char *r = NULL;
+ if (b->resource_type >= 0 &&
+ b->resource_type < sizeof(res_names)/sizeof(res_names[0]))
+ r = res_names[b->resource_type];
+ if (!r) {
+ snprintf(res, sizeof(res), "%d", b->resource_type);
+ r = res;
+ }
+ return snprintf(dest, size, "%s.%d\n", r, b->resource_id);
+}
+
+int fres_block_basic_to_string(char *dest, size_t size, enum fres_block_type type,
+ const void *block_data)
+{
+ const fres_block_basic *b = block_data;
+ return snprintf(dest, size,
+ "budget: %ld.%09ld s\n"
+ "period: %ld.%09ld s\n"
+ "workload: %d\n"
+ "type: %d\n",
+ (long)b->budget.tv_sec, (long)b->budget.tv_nsec,
+ (long)b->period.tv_sec, (long)b->period.tv_nsec,
+ b->workload,
+ b->contract_type
+ );
+ return 0;
+}
+
+int fres_block_timing_reqs_to_string(char *dest, size_t size, enum fres_block_type type,
+ const void *block_data)
+{
+ const fres_block_timing_reqs *b = block_data;
+ return snprintf(dest, size,
+ "D=T: %s\n"
+ "deadline: %ld.%09ld s\n",
+ b->d_equals_t ? "true" : "false",
+ (long)b->deadline.tv_sec, (long)b->deadline.tv_nsec
+ );
+}
+
+int fres_block_spare_capacity_to_string(char *dest, size_t size, enum fres_block_type type,
+ const void *block_data)
+{
+ int i, ret;
+ char *orig_dest = dest;
+ const fres_block_spare_capacity *s = block_data;
+ ret = snprintf(dest, size,
+ "granularity: %s\n"
+ "importance: %d\n"
+ "weight: %d\n"
+ "stability time: %g\n",
+ s->granularity == FRSH_GR_CONTINUOUS ? "continuous" :
+ s->granularity == FRSH_GR_DISCRETE ? "discrete" : "?",
+ s->importance, s->weight, fosa_rel_time_to_double(s->stability_time));
+ dest += ret;
+ size -= ret;
+ for (i=0; i < s->variants._length; i++) {
+ char tmp[1000];
+ ret = snprintf(dest, size, "Variant %d:\n", i);
+ dest += ret;
+ size -= ret;
+ ret = fres_container_to_string(tmp, sizeof(tmp),
+ forb_sequence_elem(&s->variants, i));
+ ret = fres_indent_str(dest, size, tmp, 2);
+ dest += ret;
+ size -= ret;
+ }
+ return dest - orig_dest;
+}
+
+int fres_block_csects_to_string(char *dest, size_t size, enum fres_block_type type,
+ const void *block_data)
+{
+ return snprintf(dest, size, "Coming Soon...\n");
+}
+
+int fres_block_power_management_to_string(char *dest, size_t size, enum fres_block_type type,
+ const void *block_data)
+{
+ return snprintf(dest, size, "Coming Soon...\n");
+}
+
+static const desc_default(label);
+static const desc_default(resource);
+static const desc_default(basic);
+static const desc_default(timing_reqs);
+static const desc_default(csects);
+static const desc_default(power_management);
+
+static const struct fres_block_desc desc_spare_capacity = {
+ .name = "spare_capacity",
+ .size = sizeof(fres_block_spare_capacity),
+ .serialize = (fres_block_serialize_fnc_t*)fres_block_spare_capacity_serialize, \
+ .deserialize = (fres_block_deserialize_fnc_t*)fres_block_spare_capacity_deserialize, \
+ .duplicate = fres_block_duplicate_spare_capacity,
+ .to_string = fres_block_spare_capacity_to_string
+};
+
+/**
+ * Information about various block types
+ *
+ */
+static const struct fres_block_desc *block_registry[__FRES_NUM_BLOCKS] = {
+ [FRES_BLOCK_LABEL] = &desc_default_label,
+ [FRES_BLOCK_RESOURCE] = &desc_default_resource,
+ [FRES_BLOCK_BASIC] = &desc_default_basic,
+ [FRES_BLOCK_TIMING_REQS] = &desc_default_timing_reqs,
+ [FRES_BLOCK_CSECTS] = &desc_default_csects,
+ [FRES_BLOCK_SPARE_CAPACITY] = &desc_spare_capacity,
+ [FRES_BLOCK_POWER_MANAGEMENT] = &desc_default_power_management,
+};
+
+/**
+ * Default procedure for duplicating contract blocks.
+ *
+ * It mallocs memory for the duplicate and copy memory of the original
+ * block to the allocated memory.
+ *
+ * @param type
+ * @param block_data
+ *
+ * @return Pointer to the duplicated block or NULL in case of error.
+ */
+void *
+fres_block_duplicate_default(enum fres_block_type type, const void *block_data)
+{
+ void *ret = NULL;
+ size_t size;
+ if (!FRES_BLOCK_TYPE_VALID(type) || !block_registry[type]) {
+ goto err;
+ }
+ size = block_registry[type]->size;
+
+ ret = malloc(size);
+ if (!ret) goto err;
+
+ memcpy(ret, block_data, size);
+err:
+ return ret;
+}
+
+static void *
+fres_block_duplicate_spare_capacity(enum fres_block_type type, const void *block_data)
+{
+ const fres_block_spare_capacity *sc1 = block_data;
+ fres_block_spare_capacity *sc2;
+
+ sc2 = fres_block_duplicate_default(type, block_data);
+ if (sc2) {
+ unsigned i, len = sc1->variants._length;
+ sc2->variants._buffer =
+ CORBA_sequence_fres_container_ptr_allocbuf(len);
+ sc2->variants._maximum = len;
+ sc2->variants._length = len;
+ for (i=0; i<len; i++) {
+ sc2->variants._buffer[i] =
+ fres_container_duplicate(sc1->variants._buffer[i]);
+ }
+ }
+ return sc2;
+}
+
+/**
+ * Regsiteres a custom block type.
+ *
+ * @param fres_block_type Type identifier
+ * @param desc Description of the type
+ *
+ * @return Zero on success, -1 on error.
+ */
+int
+fres_block_register(enum fres_block_type type, const struct fres_block_desc *desc)
+{
+ if (FRES_BLOCK_TYPE_VALID(type) &&
+ block_registry[type] == NULL) {
+ block_registry[type] = desc;
+ return 0;
+ }
+ return -1;
+}
+
+/**
+ * Allocates new contract container.
+ *
+ * @return Pointer to the container of NULL in case of error (errno is
+ * set appropriately).
+ */
+struct fres_container *
+fres_container_new(void)
+{
+ struct fres_container *c;
+
+ c = malloc(sizeof(*c));
+ if (c) {
+ memset(c, 0, sizeof(*c));
+ }
+ return c;
+}
+
+/**
+ * Deallocates all memory occupied by a container.
+ *
+ * @param container
+ */
+void
+fres_container_destroy(struct fres_container *container)
+{
+ enum fres_block_type i;
+ if (!container) return;
+ for (i=0; i<__FRES_NUM_BLOCKS; i++) {
+ fres_container_del_block(container, i);
+ }
+
+ free(container);
+}
+
+/**
+ * Duplicates a contract block of a given type. Calls duplication
+ * method registered with the block.
+ *
+ * @param dest Where to store the copy
+ * @param source What to copy
+ *
+ * @return Zero on success, non-zero error code on error.
+ */
+int
+fres_block_duplicate(struct fres_block *dest,
+ const struct fres_block *source,
+ enum fres_block_type type)
+{
+ dest->state = FRES_BLOCK_EMPTY;
+ switch (source->state) {
+ case FRES_BLOCK_EMPTY:
+ /* nothing to do */
+ break;
+ case FRES_BLOCK_DATA: {
+ void *dup;
+ dup = block_registry[type]->duplicate(
+ type, source->u.data);
+ if (!dup) {
+ return FRES_ERR_BLOCK_DUP;
+ }
+ dest->u.data = dup;
+ dest->state = FRES_BLOCK_DATA;
+ break;
+ }
+ case FRES_BLOCK_STREAM:
+ dest->state = FRES_BLOCK_STREAM;
+ dest->u.stream = source->u.stream;
+ dest->u.stream.data = malloc(source->u.stream.length);
+ if (!dest->u.stream.data) {
+ return errno;
+ }
+ memcpy(dest->u.stream.data, source->u.stream.data,
+ source->u.stream.length);
+ break;
+ }
+ return 0;
+}
+
+
+
+/**
+ * Duplicates a container
+ *
+ * @param source
+ *
+ * @return Pointer to the duplicated container or NULL in case of
+ * error.
+ */
+struct fres_container *
+fres_container_duplicate(const struct fres_container *source)
+{
+ struct fres_container *dest;
+ enum fres_block_type type;
+ int ret;
+ if (!source) return NULL;
+
+ dest = fres_container_new();
+ if (!dest) return NULL;
+
+ for (type=0; type<__FRES_NUM_BLOCKS; type++) {
+ ret = fres_block_duplicate(&dest->blocks[type], &source->blocks[type], type);
+ if (ret) goto free_dest_err;
+ }
+ return dest;
+free_dest_err:
+ fres_container_destroy(dest);
+ return NULL;
+}
+
+/**
+ * Adds a block of the specific type to the contract container.
+ *
+ * @param container Container to which add the block.
+ * @param type Type of the block.
+ *
+ * @param block Pointer to the block which should be a malloced
+ * area. In in most cases it will points to a structure defined in
+ * IDL.
+ *
+ * @return Zero on success, -1 on error and errno is set appropriately.
+ */
+int
+fres_container_add_block(struct fres_container *container,
+ enum fres_block_type type,
+ void *block)
+{
+ if (!FRES_BLOCK_TYPE_VALID(type) ||
+ container->blocks[type].state != FRES_BLOCK_EMPTY)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ if (!block_registry[type]) {
+ errno = FRES_ERR_BLOCK_NOT_REGISTERED;
+ return -1;
+ }
+
+ container->blocks[type].u.data = block;
+ container->blocks[type].state = FRES_BLOCK_DATA;
+ return 0;
+}
+
+/**
+ * Deletes a block from container and frees it from memory.
+ *
+ * @param container
+ * @param type
+ */
+void
+fres_container_del_block(struct fres_container *container,
+ enum fres_block_type type)
+{
+ if (FRES_BLOCK_TYPE_VALID(type)) {
+ switch (container->blocks[type].state) {
+ case FRES_BLOCK_EMPTY:
+ /* nothing to do */
+ break;
+ case FRES_BLOCK_DATA:
+ free(container->blocks[type].u.data);
+ container->blocks[type].state = FRES_BLOCK_EMPTY;
+ break;
+ case FRES_BLOCK_STREAM:
+ forb_free(container->blocks[type].u.stream.data);
+ container->blocks[type].state = FRES_BLOCK_EMPTY;
+ break;
+ }
+ }
+}
+
+/**
+ * Returns pointer to a block of a particular type.
+ *
+ * @param container
+ * @param type Type of the block to be returned.
+ *
+ * @return Pointer to the block or NULL if the block is not present or
+ * deserialized. The memory area pointed by this pointer is owned by
+ * the contract. If the user needs to store the block, it must be
+ * duplicated.
+ */
+void *
+fres_container_get_block(const struct fres_container *container,
+ enum fres_block_type type)
+{
+ if (container &&
+ FRES_BLOCK_TYPE_VALID(type) &&
+ container->blocks[type].state == FRES_BLOCK_DATA) {
+ return container->blocks[type].u.data;
+ } else {
+ return NULL;
+ }
+}
+
+static CORBA_boolean
+serialize_block(FORB_CDR_Codec *codec, enum fres_block_type type, const struct fres_block *b)
+{
+ CORBA_boolean ret;
+ CORBA_short type_short = type;
+ CORBA_unsigned_short flags;
+ CORBA_long length;
+ unsigned int wptr_of_length, wptr_tmp, wptr_of_block_beg;
+
+ switch (b->state) {
+ case FRES_BLOCK_STREAM:
+ /* Endianing of stream is the same as when it
+ * was received */
+ flags = b->u.stream.flags;
+ length = b->u.stream.length;
+ break;
+ case FRES_BLOCK_DATA:
+ /* Endianing of stream is the same as of the
+ * rest of data */
+ flags = 0;
+ flags |= (codec->data_endian == LittleEndian) ?
+ FRES_BLOCK_LITTLE_ENDIAN : 0;
+ length = 0; /* Length will be determined later */
+ break;
+ default:
+ break;
+ }
+
+ if (!(ret = CORBA_short_serialize(codec, &type_short))) goto err;
+ if (!(ret = CORBA_short_serialize(codec, &flags))) goto err;
+ wptr_of_length = codec->wptr;
+ if (!(ret = CORBA_long_serialize(codec, &length))) goto err;
+ if (!(ret = FORB_CDR_put_align(codec, 8))) goto err; /* All blocks are 8 byte aligned */
+ wptr_of_block_beg = codec->wptr;
+
+ switch (b->state) {
+ case FRES_BLOCK_DATA:
+ if (block_registry[type] &&
+ block_registry[type]->serialize) {
+ ret = block_registry[type]->serialize(codec, b->u.data);
+ } else {
+ ret = CORBA_FALSE;
+ }
+ /* Update the length field */
+ length = codec->wptr - wptr_of_block_beg;
+ wptr_tmp = codec->wptr;
+ codec->wptr = wptr_of_length;
+ CORBA_long_serialize(codec, &length);
+ codec->wptr = wptr_tmp;
+ break;
+ case FRES_BLOCK_STREAM:
+ ret = FORB_CDR_buffer_puts(codec, b->u.stream.data,
+ b->u.stream.length);
+ break;
+ default:
+ ret = CORBA_FALSE;
+ break;
+ }
+err:
+ return ret;
+}
+
+
+CORBA_boolean
+fres_container_ptr_serialize(FORB_CDR_Codec *codec, const fres_container_ptr *container_ptr)
+{
+ //CORBA_long l;
+ CORBA_long count;
+ struct fres_container *container = *container_ptr;
+ CORBA_boolean ret;
+ enum fres_block_type type;
+ if (!container) goto err;
+
+ count=0;
+ for (type=0; type<__FRES_NUM_BLOCKS; type++) {
+ if (container->blocks[type].state != FRES_BLOCK_EMPTY)
+ count++;
+ }
+
+ if (!CORBA_long_serialize(codec, &count)) goto err;
+
+ for (type=0; type<__FRES_NUM_BLOCKS; type++) {
+ struct fres_block *b = &container->blocks[type];
+ if (b->state != FRES_BLOCK_EMPTY) {
+ ret = serialize_block(codec, type, b);
+ if (!ret) goto err;
+ }
+ }
+ return CORBA_TRUE;
+err:
+ return CORBA_FALSE;
+}
+
+CORBA_boolean
+fres_container_ptr_deserialize(FORB_CDR_Codec *codec,
+ fres_container_ptr *container)
+{
+ CORBA_boolean ret;
+ struct fres_container *c;
+ CORBA_long count;
+ enum fres_block_type type;
+ CORBA_short type_short;
+ CORBA_short flags;
+ CORBA_long length;
+ int i;
+
+ c = fres_container_new();
+ if (!c) goto err;
+
+ if (!CORBA_long_deserialize(codec, &count)) goto err;
+
+ for (i=0; i<count; i++) {
+ if (!CORBA_short_deserialize(codec, &type_short)) goto free_err;
+ if (!CORBA_short_deserialize(codec, &flags)) goto free_err;
+ if (!CORBA_long_deserialize(codec, &length)) goto free_err;
+ FORB_CDR_get_align(codec, 8); /* All blocks are 8 byte aligned */
+
+ type = type_short;
+ if (!FRES_BLOCK_TYPE_VALID(type)) goto free_err;
+ if (block_registry[type] &&
+ block_registry[type]->deserialize) {
+ FORB_CDR_Endianness endian;
+ void *block;
+ block = malloc(block_registry[type]->size);
+ if (!block) goto free_err;
+ /* A block can have different endian from the rest of the message */
+ endian = codec->data_endian;
+ codec->data_endian = (flags & FRES_BLOCK_LITTLE_ENDIAN) ?
+ LittleEndian : BigEndian;
+ ret = block_registry[type]->deserialize(codec, block);
+ codec->data_endian = endian;
+ if (!ret) goto free_err;
+ fres_container_add_block(c, type, block);
+ } else {
+ /* Unknown block - store it as stream */
+ struct fres_block_stream *bs = &c->blocks[type].u.stream;
+ c->blocks[type].state = FRES_BLOCK_STREAM;
+ bs->data = malloc(length);
+ if (!bs->data) goto free_err;
+ bs->flags = flags;
+ bs->length = length;
+ FORB_CDR_buffer_gets(codec, bs->data, length);
+ }
+ }
+
+
+ *container = c;
+ return CORBA_TRUE;
+free_err:
+ fres_container_destroy(c);
+err:
+ return CORBA_FALSE;
+}
+
+int fres_block_to_string(char *dest, size_t size, enum fres_block_type type,
+ const void *block_data)
+{
+ if (block_registry[type]->to_string)
+ return block_registry[type]->to_string(dest, size, type, block_data);
+ else
+ return 0;
+}
+
+int
+fres_container_to_string(char *dest, size_t size, const struct fres_container *c)
+{
+ int ret, written = 0;
+ enum fres_block_type type;
+
+ for (type=0; type<__FRES_NUM_BLOCKS; type++) {
+ const struct fres_block *b = &c->blocks[type];
+ switch (b->state) {
+ case FRES_BLOCK_EMPTY:
+ /* nothing to do */
+ break;
+ case FRES_BLOCK_DATA: {
+ char tmp[1000];
+ ret = snprintf(dest, size, "block %s (%d)\n",
+ block_registry[type]->name, type);
+ if (ret < 0) goto err;
+ if (ret < size) {
+ written += ret;
+ size -= ret;
+ dest += ret;
+ }
+ ret = fres_block_to_string(tmp, sizeof(tmp), type, b->u.data);
+ if (ret > 0) {
+ ret = fres_indent_str(dest, size, tmp, 2);
+ written += ret;
+ size -= ret;
+ dest += ret;
+ }
+ break;
+ }
+ case FRES_BLOCK_STREAM:
+ ret = snprintf(dest, size, "unknown block (%d)\n",
+ type);
+ if (ret < 0) goto err;
+ if (ret < size) {
+ written += ret;
+ size -= ret;
+ dest += ret;
+ }
+ break;
+ }
+ }
+ ret = written;
+ *dest = 0;
+err:
+ return ret;
+}
+
+
+/**
+ * Returns the number of non-empty blocks in a container.
+ *
+ * @param c Container
+ *
+ * @return Number of non-empty blocks in container @a c.
+ */
+int
+fres_container_get_num_blocks(const struct fres_container *c)
+{
+ int num = 0;
+ enum fres_block_type type;
+
+ for (type=0; type<__FRES_NUM_BLOCKS; type++) {
+ if (c->blocks[type].state != FRES_BLOCK_EMPTY) {
+ num++;
+ }
+ }
+ return num;
+}
+
+/**
+ * Merges two block containers. Blocks present @a src and missing in
+ * @a dest are duplicated in @a dest.
+ *
+ * @param dest Destination of merge operation
+ * @param src Source of merge operation
+ *
+ * @return Zero on success, non-zero error core on error.
+ */
+int fres_container_merge(struct fres_container *dest,
+ const struct fres_container *src)
+{
+ enum fres_block_type type;
+ int ret;
+
+ for (type=0; type<__FRES_NUM_BLOCKS; type++) {
+ const struct fres_block *sb = &src->blocks[type];
+ struct fres_block *db = &dest->blocks[type];
+
+ if (sb->state != FRES_BLOCK_EMPTY &&
+ db->state == FRES_BLOCK_EMPTY) {
+ ret = fres_block_duplicate(db, sb, type);
+ if (ret) {
+ return ret;
+ }
+ }
+ }
+ return 0;
+}
+
+/**
+ * Copy blocks from a container into another one. Blocks present in
+ * both @a src and @a dest are replaced in @a dest.
+ *
+ * @param dest Destination of copy operation
+ * @param src Source of copy operation
+ *
+ * @return Zero on success, non-zero error core on error.
+ */
+int fres_container_copy(struct fres_container *dest,
+ const struct fres_container *src)
+{
+ enum fres_block_type type;
+ int ret;
+
+ for (type=0; type<__FRES_NUM_BLOCKS; type++) {
+ const struct fres_block *sb = &src->blocks[type];
+ struct fres_block *db = &dest->blocks[type];
+
+ if (sb->state != FRES_BLOCK_EMPTY) {
+ fres_container_del_block(dest, type);
+ ret = fres_block_duplicate(db, sb, type);
+ if (ret) {
+ return ret;
+ }
+ }
+ }
+ return 0;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file fres_container.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ *
+ * @brief Container for managing contract blocks.
+ *
+ *
+ */
+#ifndef FRES_CONTAINER_H
+#define FRES_CONTAINER_H
+
+
+#include <fres_container_type.h>
+#include <fres_blocks.h>
+#include <forb/basic_types.h>
+#include <forb/cdr_codec.h>
+#include <fosa_types.h>
+
+/*============================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Identification of different contract blocks.
+ *
+ * All contract blocks should define their ID here. This is the
+ * only place, where the different parameters (e.g. for different
+ * kinds of resources) share a common source file. The declaration of
+ * block struture can occur at any place (.h or better .idl).
+ *
+ */
+enum fres_block_type {
+ FRES_BLOCK_LABEL,
+ FRES_BLOCK_RESOURCE,
+ FRES_BLOCK_BASIC,
+ FRES_BLOCK_TIMING_REQS,
+ FRES_BLOCK_CSECTS,
+ FRES_BLOCK_SPARE_CAPACITY,
+ FRES_BLOCK_POWER_MANAGEMENT,
+ FRES_BLOCK_DUMMY_SCHED, /**< See resources/dummy/res_dummy_idl.idl */
+ FRES_BLOCK_DISK_SCHED, /** < See resources/disk_bfq/res_disk_idl.idl */
+ FRES_BLOCK_CLUSTER_TREE_TRAFFIC, /**< resources/cluster_tree/cluster_tree_idl.idl */
+ FRES_BLOCK_FWP_SCHED,
+ FRES_BLOCK_ITEM_NODES, /**< resources/item/item_idl.idl */
+ FRES_BLOCK_FPGA, /**< resources/fpga/res_fpga_idl.idl */
+ FRES_BLOCK_FWP,
+ __FRES_NUM_BLOCKS,
+};
+
+typedef CORBA_boolean (fres_block_serialize_fnc_t)(FORB_CDR_Codec *codec, const void *block_data);
+typedef CORBA_boolean (fres_block_deserialize_fnc_t)(FORB_CDR_Codec *codec, void **block_data);
+
+/**
+ * Description of contract blocks.
+ */
+struct fres_block_desc {
+ const char *name; /**< Name of the block for use fres_container_to_string() */
+ size_t size; /**< Size of the block (used by fres_block_duplicate_default() and fres_container_ptr_deserialize()) */
+ fres_block_serialize_fnc_t *serialize;
+ fres_block_deserialize_fnc_t *deserialize;
+ void *(*duplicate)(enum fres_block_type type, const void *block_data);
+ int (*to_string)(char *dest, size_t size, enum fres_block_type type, const void *block_data);
+};
+
+struct fres_container *
+fres_container_new(void);
+
+void
+fres_container_destroy(struct fres_container *container);
+
+struct fres_container *
+fres_container_duplicate(const struct fres_container *source);
+
+int
+fres_container_add_block(struct fres_container *container,
+ enum fres_block_type type,
+ void *block);
+
+void
+fres_container_del_block(struct fres_container *container,
+ enum fres_block_type type);
+
+void *
+fres_container_get_block(const struct fres_container *container,
+ enum fres_block_type type);
+
+int fres_block_to_string(char *dest, size_t size, enum fres_block_type type,
+ const void *block_data);
+
+/**
+ * Macro which defines type-safe container "accessor" functions for
+ * various blocks.
+ *
+ * This macro declares the following inline functions:
+ * - fres_container_add_<type>
+ * - fres_container_get_<type>
+ * - fres_container_del_<type>
+ *
+ * These functions are equivalent to fres_container_add_block(),
+ * fres_container_del_block() and fres_container_get_block() with
+ * appropriate parameters.
+ */
+#define FRES_CONTAINER_ACCESSOR(TYPE, type) \
+ static inline int \
+ fres_container_add_##type(struct fres_container *container, \
+ fres_block_##type *block) \
+ { \
+ return fres_container_add_block( \
+ container, FRES_BLOCK_##TYPE, block); \
+ } \
+ static inline fres_block_##type * \
+ fres_container_get_##type(const struct fres_container *container) \
+ { \
+ return (fres_block_##type *)fres_container_get_block( \
+ container, FRES_BLOCK_##TYPE); \
+ } \
+ static inline void \
+ fres_container_del_##type(struct fres_container *container) \
+ { \
+ fres_container_del_block(container, FRES_BLOCK_##TYPE); \
+ }
+
+FRES_CONTAINER_ACCESSOR(LABEL, label)
+FRES_CONTAINER_ACCESSOR(RESOURCE, resource)
+FRES_CONTAINER_ACCESSOR(BASIC, basic)
+FRES_CONTAINER_ACCESSOR(TIMING_REQS, timing_reqs)
+FRES_CONTAINER_ACCESSOR(CSECTS, csects)
+FRES_CONTAINER_ACCESSOR(SPARE_CAPACITY, spare_capacity)
+FRES_CONTAINER_ACCESSOR(POWER_MANAGEMENT, power_management)
+
+int
+fres_block_register(enum fres_block_type, const struct fres_block_desc *desc);
+
+void *
+fres_block_duplicate_default(enum fres_block_type type, const void *block_data);
+
+int
+fres_container_to_string(char *dest, size_t size, const struct fres_container *c);
+
+int
+fres_container_get_num_blocks(const struct fres_container *c);
+
+int fres_container_merge(struct fres_container *dest,
+ const struct fres_container *src);
+
+int fres_container_copy(struct fres_container *dest,
+ const struct fres_container *src);
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file fres_container_internal.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ *
+ * @brief Internal interface to fres_container.
+ *
+ * This header should only be included by files in frsh/fres library.
+ *
+ */
+#ifndef FRES_CONTAINER_INTERNAL_H
+#define FRES_CONTAINER_INTERNAL_H
+
+#include <fres_contract_idl.h>
+
+/** State of the block in container. */
+enum fres_block_state {
+ /** There is no such block in the container. */
+ FRES_BLOCK_EMPTY,
+ /** The container contains the block in the deserialized
+ * form. */
+ FRES_BLOCK_DATA,
+ /** The container contains the block in the serialized form
+ * (sequence of octets).*/
+ FRES_BLOCK_STREAM
+};
+
+#define FRES_BLOCK_FLAG_ENDIAN_m 0x0001
+#define FRES_BLOCK_LITTLE_ENDIAN 0x0001
+
+/** Unserialized (unknown) contracts blocks */
+typedef struct fres_block_stream {
+ void *data; /**< Serialized data */
+ CORBA_unsigned_short flags; /**< Flags: bit 1 - little endian */
+ size_t length; /**< Length of the stream */
+} fres_block_stream_t;
+
+/**
+ * Contract block.
+ *
+ */
+struct fres_block {
+ enum fres_block_state state; /**< State of the block */
+ union {
+ /** Pointer to data according to param_type
+ * (state == FRES_BLOCK_DATA) */
+ void *data;
+
+ /** Unserialized (unknown) data
+ * (state == FRES_BLOCK_STREAM) */
+ fres_block_stream_t stream;
+ } u;
+};
+
+/**
+ * Container for contract blocks.
+ *
+ * This is currently implemented as fixed size array of ::fres_block
+ * structures, which means that the container cannot contain multiple
+ * blocks of the same type.
+ */
+struct fres_container {
+ struct fres_block blocks[__FRES_NUM_BLOCKS];
+};
+
+/** Checks wheder the @a type is valid number of the block */
+#define FRES_BLOCK_TYPE_VALID(type) \
+ ((type) < __FRES_NUM_BLOCKS && \
+ (type) >= 0)
+
+int
+fres_block_duplicate(struct fres_block *dest,
+ const struct fres_block *source,
+ enum fres_block_type type);
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+#ifndef FRES_CONTAINER_TYPE_H
+#define FRES_CONTAINER_TYPE_H
+
+#include <forb/basic_types.h>
+#include <forb/cdr_codec.h>
+
+/**
+ * Data type for represenataion of contract container (incomplete declaration).
+ */
+typedef struct fres_container *fres_container_ptr;
+
+CORBA_boolean
+fres_container_ptr_serialize(FORB_CDR_Codec *codec,
+ const fres_container_ptr *container);
+
+CORBA_boolean
+fres_container_ptr_deserialize(FORB_CDR_Codec *codec,
+ fres_container_ptr *container);
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file fres_contract.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Nov 9 22:17:29 2008
+ *
+ * @brief Implementation of contract functions
+ *
+ *
+ */
+#include <fres_contract.h>
+#include <fres_container_internal.h>
+#include <string.h>
+#include <stdio.h>
+#include "utils.h"
+/**
+ * Allocates new fres_contract structure. Use fres_contract_destroy to
+ * deallocate the contract.
+ *
+ * @param contract
+ *
+ * @return Zero on succes, -1 on error and errno is set appropriately.
+ */
+struct fres_contract *
+fres_contract_new()
+{
+ struct fres_contract *c;
+
+ c = malloc(sizeof(*c));
+ if (!c) goto err;
+ memset(c, 0, sizeof(*c));
+ c->container = fres_container_new();
+ if (!c->container) goto free_err;
+ return c;
+free_err:
+ free(c);
+err:
+ return NULL;
+}
+
+void fres_contract_destroy(struct fres_contract *contract)
+{
+ if (contract) {
+ fres_container_destroy(contract->container);
+ free(contract);
+ }
+}
+
+struct fres_contract *
+fres_contract_duplicate(struct fres_contract *src)
+{
+ struct fres_contract *dst;
+
+ if (!src) goto err;
+ dst = malloc(sizeof(*dst));
+ if (!dst) goto err;
+ memcpy(dst, src, sizeof(*dst));
+ dst->container = fres_container_duplicate(src->container);
+ if (!dst->container) goto free_err;
+
+ return dst;
+free_err:
+ free(dst);
+err:
+ return NULL;
+}
+
+CORBA_boolean
+fres_contract_ptr_serialize(FORB_CDR_Codec *codec,
+ const fres_contract_ptr *contract)
+{
+ CORBA_boolean cb;
+ cb = fres_contract_id_t_serialize(codec, &(*contract)->id);
+ if (!cb) goto err;
+ cb = fres_container_ptr_serialize(codec, &(*contract)->container);
+ if (!cb) goto err;
+ return CORBA_TRUE;
+err:
+ return CORBA_FALSE;
+}
+
+CORBA_boolean
+fres_contract_ptr_deserialize(FORB_CDR_Codec *codec,
+ fres_contract_ptr *contract)
+{
+ CORBA_boolean cb;
+ struct fres_contract *c;
+
+ c = malloc(sizeof(*c));
+ if (!c) goto err;
+ memset(c, 0, sizeof(*c));
+
+ cb = fres_contract_id_t_deserialize(codec, &c->id);
+ if (!cb) goto free_err;
+ cb = fres_container_ptr_deserialize(codec, &c->container);
+ if (!cb) goto free_err;
+
+ *contract = c;
+ return CORBA_TRUE;
+free_err:
+ fres_contract_destroy(c);
+err:
+ return CORBA_FALSE;
+}
+
+void fres_contract_ptr_free(fres_contract_ptr contract)
+{
+ fres_contract_destroy(contract);
+}
+
+int
+fres_contract_to_string(char *dest, size_t size, const struct fres_contract *c)
+{
+ int ret, ret2;
+ char id[30];
+
+ if (!c)
+ return 0;
+ fres_contract_id_to_string(id, &c->id, sizeof(id));
+ ret = snprintf(dest, size, "id: %s\n", id);
+ if (ret>=0 && ret < size) {
+ dest += ret;
+ size -= ret;
+ ret2 = fres_container_to_string(dest, size, c->container);
+ if (ret2 < 0) ret = ret2;
+ else ret += ret2;
+ }
+ return ret;
+}
+
+int
+fres_contract_to_string2(char *dest, size_t size, const struct fres_contract *c, int indent, uint32_t flags)
+{
+ int ret, ret2;
+ char id[30];
+ char tmp[size]; /* C99 */
+ char *t = tmp;
+ size_t s2 = size;
+
+ if (!c)
+ return 0;
+ fres_contract_id_to_string(id, &c->id, sizeof(id));
+ ret = snprintf(t, s2, "id: %s\n", id);
+ if (ret>=0 && ret < s2) {
+ t += ret;
+ s2 -= ret;
+ ret2 = fres_container_to_string(t, s2, c->container);
+ if (ret2 < 0) ret = ret2;
+ else ret += ret2;
+ if (ret2 >= 0)
+ ret = fres_indent_str(dest, size, tmp, indent);
+ }
+
+ return ret;
+}
+
+void
+fres_contract_print(char *prefix, const struct fres_contract *c)
+{
+ char contract[1000];
+ fres_contract_to_string(contract, sizeof(contract)-1, c);
+ contract[sizeof(contract)-1] = 0;
+ printf("%s %s", prefix, contract);
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file fres_contract.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Nov 9 22:15:09 2008
+ *
+ * @brief Declaration of contract type and functions
+ *
+ *
+ */
+#ifndef FRES_CONTRACT_H
+#define FRES_CONTRACT_H
+
+#include <fres_blocks.h>
+#include <fres_container.h>
+#include <ul_gavl.h>
+#include <fres_contract_type.h>
+#include <fres_contract_idl.h>
+#include <forb/server_id.h>
+#include <stdio.h>
+#ifdef __cplusplus__
+# define __STDC_FORMAT_MACROS
+#endif
+#include <inttypes.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Contract data type.
+ *
+ */
+struct fres_contract {
+ fres_contract_id_t id; /**< Global contract ID */
+ struct fres_container *container; /**< Pointer to the block container (opaque type). */
+};
+
+static inline int fres_contract_id_cmp(const fres_contract_id_t *a,
+ const fres_contract_id_t *b)
+{
+ return forb_server_id_cmp((forb_server_id*)a,
+ (forb_server_id*)b);
+}
+
+static inline bool fres_contract_id_is_empty(const fres_contract_id_t *id)
+{
+/* bool empty = true; */
+/* unsigned i; */
+
+/* for (i=0; i<sizeof(id->byte); i++) { */
+/* if (id->byte[i] != 0) { */
+/* empty = false; */
+/* break; */
+/* } */
+/* } */
+/* return empty; */
+ return *id == 0;
+}
+
+static inline char *fres_contract_id_to_string(char *dest,
+ const fres_contract_id_t *id,
+ size_t n)
+{
+ snprintf(dest, n, "%"PRIx64, *id);
+/* return forb_server_id_to_string(dest, (forb_server_id*)id, n); */
+ return dest;
+}
+
+struct fres_contract *fres_contract_new(void);
+void fres_contract_destroy(struct fres_contract *contract);
+
+/** Destructor for easy use in forb_sequence_free() */
+static inline void fres_contract_ptr_destroy(struct fres_contract **p)
+{
+ fres_contract_destroy(*p);
+}
+
+
+struct fres_contract *fres_contract_duplicate(struct fres_contract *src);
+
+/**
+ * Adds a block of the given type to the contract.
+ *
+ * This function uses fres_container_add_block() to do its job.
+ *
+ * @param contract Where to add the @a block.
+ * @param type Type of contract being added.
+ * @param block Pointer to the malloced block of given @a type.
+ *
+ * @return Zero on success, -1 on error and errno is set appropriately.
+ */
+static inline int
+fres_contract_add_block(struct fres_contract *contract,
+ enum fres_block_type type, void *block)
+{
+ return fres_container_add_block(contract->container, type, block);
+}
+/**
+ * Deletes a block from the contract and frees it from memory.
+ *
+ * This function uses fres_container_del_block() to do its job.
+ *
+ * @param contract Where to delete the block.
+ * @param type Type of contract to delete.
+ */
+static inline void
+fres_contract_del_block(struct fres_contract *contract,
+ enum fres_block_type type)
+{
+ fres_container_del_block(contract->container, type);
+}
+
+/**
+ * Returns pointer to a contract block of a particular @a type.
+ *
+ * This function uses fres_container_get_block() to do its job.
+ *
+ * @param contract
+ * @param type Type of the block to be returned.
+ *
+ * @return Pointer to the block or NULL if the block is not present or
+ * deserialized. The memory area pointed by this pointer is owned by
+ * the contract. If the user needs to store the block, it must be
+ * duplicated.
+ */
+static inline void *
+fres_contract_get_block(struct fres_contract *contract,
+ enum fres_block_type type)
+{
+ return fres_container_get_block(contract->container, type);
+}
+
+int
+fres_contract_to_string(char *dest, size_t size, const struct fres_contract *c);
+
+/* #define FRES_C2S_FL_FMT_ONELINE */
+/* #define FRES_C2S_FL_FMT_BLOCKPERLINE */
+int
+fres_contract_to_string2(char *dest, size_t size, const struct fres_contract *c, int indent, uint32_t flags);
+
+bool
+fres_contract_get_deadline(const frsh_contract_t *contract,
+ frsh_rel_time_t *deadline);
+bool
+fres_contract_get_budget(const frsh_contract_t *contract,
+ frsh_rel_time_t *budget);
+bool
+fres_contract_get_period(const frsh_contract_t *contract,
+ frsh_rel_time_t *period);
+frsh_contract_type_t
+fres_contract_get_type(const frsh_contract_t *contract);
+
+void
+fres_contract_print(char *prefix, const struct fres_contract *c);
+
+static inline int
+fres_contract_get_num_blocks(const struct fres_contract *c)
+{
+ return fres_container_get_num_blocks(c->container);
+}
+
+static inline int
+fres_contract_merge(struct fres_contract *dest,
+ const struct fres_contract *src)
+{
+ return fres_container_merge(dest->container, src->container);
+}
+
+
+/**
+ * Macro which defines type-safe contract "accessor" functions for
+ * various blocks.
+ *
+ * This macro declares the following inline functions:
+ * - fres_contract_add_<type>
+ * - fres_contract_get_<type>
+ * - fres_contract_del_<type>
+ *
+ * The defined functions simply use the container "accessor" functions
+ * (usually defined) by #FRES_CONTAINER_ACCESSOR and are equivalent to
+ * fres_contract_add_block(), fres_contract_del_block() and
+ * fres_contract_get_block() with appropriate parameters.
+ */
+#define FRES_CONTRACT_ACCESSOR(type) \
+ static inline int \
+ fres_contract_add_##type(struct fres_contract *contract, \
+ fres_block_##type *block) \
+ { \
+ return fres_container_add_##type(contract->container, \
+ block); \
+ } \
+ static inline fres_block_##type * \
+ fres_contract_get_##type(const struct fres_contract *contract) \
+ { \
+ return fres_container_get_##type(contract->container); \
+ } \
+ static inline void \
+ fres_contract_del_##type(struct fres_contract *contract) \
+ { \
+ fres_container_del_##type(contract->container); \
+ }
+
+FRES_CONTRACT_ACCESSOR(label)
+FRES_CONTRACT_ACCESSOR(resource)
+FRES_CONTRACT_ACCESSOR(basic)
+FRES_CONTRACT_ACCESSOR(timing_reqs)
+FRES_CONTRACT_ACCESSOR(csects)
+FRES_CONTRACT_ACCESSOR(spare_capacity)
+FRES_CONTRACT_ACCESSOR(power_management)
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------------------- //
+// Copyright (C) 2006 - 2008 FRESCOR consortium partners: //
+// //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// Scuola Superiore Sant'Anna, ITALY //
+// Kaiserslautern University, GERMANY //
+// Univ. Politécnica Valencia, SPAIN //
+// Czech Technical University in Prague, CZECH REPUBLIC //
+// ENEA SWEDEN //
+// Thales Communication S.A. FRANCE //
+// Visual Tools S.A. SPAIN //
+// Rapita Systems Ltd UK //
+// Evidence ITALY //
+// //
+// See http://www.frescor.org for a link to partners' websites //
+// //
+// FRESCOR project (FP6/2005/IST/5-034026) is funded //
+// in part by the European Union Sixth Framework Programme //
+// The European Union is not liable of any use that may be //
+// made of this code. //
+// //
+// //
+// based on previous work (FSF) done in the FIRST project //
+// //
+// Copyright (C) 2005 Mälardalen University, SWEDEN //
+// Scuola Superiore S.Anna, ITALY //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// //
+// FSF API web pages: http:marte.unican.es/fsf/docs //
+// http:shark.sssup.it/contrib/first/docs/ //
+// //
+// This file is part of FORB (Frescor Object Request Broker) //
+// //
+// FORB is free software; you can redistribute it and/or modify it //
+// under terms of the GNU General Public License as published by the //
+// Free Software Foundation; either version 2, or (at your option) any //
+// later version. FORB is distributed in the hope that it will be //
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty //
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
+// General Public License for more details. You should have received a //
+// copy of the GNU General Public License along with FORB; see file //
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, //
+// Cambridge, MA 02139, USA. //
+// //
+// As a special exception, including FORB header files in a file, //
+// instantiating FORB generics or templates, or linking other files //
+// with FORB objects to produce an executable application, does not //
+// by itself cause the resulting executable application to be covered //
+// by the GNU General Public License. This exception does not //
+// however invalidate any other reasons why the executable file might be //
+// covered by the GNU Public License. //
+////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @file fres_contract_idl.idl
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sun Sep 7 17:24:37 2008
+ *
+ * @brief Definitions of data types and constants for FRESCOR contracts.
+ *
+ */
+
+#ifndef _CONTRACT_IDL
+#define _CONTRACT_IDL
+module fres {
+ module contract {
+ /// Pointer to the contract type
+ native ptr;
+
+ typedef sequence<ptr> ptr_seq;
+
+ /// Globaly unique contract ID
+ typedef unsigned long long id_t;
+// struct id_t {
+// char byte[8];
+// };
+
+ typedef sequence<id_t> id_seq;
+
+ };
+};
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file fres_contract_ser.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Wed Nov 26 13:24:47 2008
+ *
+ * @brief Prototypes of contract (de)serialization functions.
+ *
+ * This is a separate header in order to avoid inclusion of CDR codec
+ * and such types to FRSH header files. In frsh_opaque_types.h we only
+ * need the contract type and not (de)serialization.
+ */
+#ifndef FRES_CONTRACT_SER_H
+#define FRES_CONTRACT_SER_H
+
+#include <forb/basic_types.h>
+#include <forb/cdr_codec.h>
+#include "fres_contract_type.h"
+
+CORBA_boolean
+fres_contract_ptr_serialize(FORB_CDR_Codec *codec,
+ const fres_contract_ptr *contract);
+
+CORBA_boolean
+fres_contract_ptr_deserialize(FORB_CDR_Codec *codec,
+ fres_contract_ptr *contract);
+
+void fres_contract_ptr_free(fres_contract_ptr contract);
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+#ifndef FRES_CONTRACT_TYPE_H
+#define FRES_CONTRACT_TYPE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Data type for represenataion of contract (imcomplete declaration).
+ */
+typedef struct fres_contract *fres_contract_ptr;
+
+void fres_contract_ptr_free(fres_contract_ptr contract);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2008 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#include <string.h>
+#include "fres_error.h"
+#include <frsh_error.h>
+
+/**
+ * fres_strerror()
+ *
+ * This function converts an error code to an error message that is
+ * stored in the buffer starting at the location pointed to by
+ * message. The size of this buffer is specified by the size
+ * argument. If the error message is longer than size-1, it is
+ * truncated to that length. Regardless of whether the message is
+ * truncated or not, a final zero character that marks the end of the
+ * string is stored in the buffer. The function fails if the error
+ * code passed does not correspond to any of the fres error codes.
+ * [@return:
+ * FRSH_ERR_BAD_ARGUMENT : error is not a valid value
+ * ]
+ **/
+int fres_strerror (int error, char *message, size_t size)
+{
+ char *s = NULL;
+ enum fres_error e = error;
+
+#define MSG(error) case FRES_ERR_##error: s = #error; break
+
+ switch (e) {
+ MSG(FCB_NOT_RUNNING);
+ MSG(FORB_EXCEPTION);
+ MSG(BLOCK_NOT_REGISTERED);
+ MSG(NEEDS_MORE_DATA_IN_CONTRACT);
+ MSG(NOTHING_TO_RENEGOTIATE);
+ MSG(BLOCK_DUP);
+ MSG(NO_RESOURCE_ALLOCATOR);
+ MSG(ADMISSION_TEST);
+ MSG(KERNEL_SUPPORT_MISSING);
+ MSG(FORB_EX_BAD_PARAM);
+ MSG(FORB_EX_NO_MEMORY);
+ MSG(FORB_EX_IMP_LIMIT);
+ MSG(FORB_EX_COMM_FAILURE);
+ MSG(FORB_EX_INV_OBJREF);
+ MSG(FORB_EX_NO_PERMISSION);
+ MSG(FORB_EX_INTERNAL);
+ MSG(FORB_EX_MARSHAL);
+ MSG(FORB_EX_INITIALIZE);
+ MSG(FORB_EX_NO_IMPLEMENT);
+ MSG(FORB_EX_BAD_OPERATION);
+ MSG(FORB_EX_NO_RESOURCES);
+ MSG(FORB_EX_NO_RESPONSE);
+ MSG(FORB_EX_TRANSIENT);
+ MSG(FORB_EX_FREE_MEM);
+ MSG(FORB_EX_INV_IDENT);
+ MSG(FORB_EX_INV_FLAG);
+ MSG(FORB_EX_DATA_CONVERSION);
+ MSG(FORB_EX_OBJECT_NOT_EXIST);
+ MSG(FORB_EX_TIMEOUT);
+ MSG(FORB_EX_APPLICATION);
+ MSG(NO_RESOURCE_MANAGER);
+ MSG(ALLOCATOR_ALREADY_REGISTERED);
+ MSG(VRES_ALREADY_ALLOCATED);
+ MSG(VRES_PART_OF_TRANSACTION);
+ MSG(SPARE_CAPACITY_NOT_SUPPORTED);
+ MSG(TRANSACTION_NOT_FOUND);
+ }
+
+ if (s == NULL) return FRSH_ERR_BAD_ARGUMENT;
+
+ if (message != NULL && size > 0) {
+ strncpy(message, s, size);
+ message[size-1] = '\0';
+ }
+
+ return 0;
+}
+
+int fres_forbex2err(CORBA_Environment *env)
+{
+ int ret = FRES_ERR_FORB_EXCEPTION;
+#define MAP(id) case FORB_EX_##id: ret = FRES_ERR_FORB_EX_##id; break
+ switch (env->major) {
+ case FORB_EX_NONE: ret = 0; break;
+ case FORB_EX_UNKNOWN: ret = FRES_ERR_FORB_EXCEPTION; break;
+ MAP(BAD_PARAM);
+ MAP(NO_MEMORY);
+ MAP(IMP_LIMIT);
+ MAP(COMM_FAILURE);
+ MAP(INV_OBJREF);
+ MAP(NO_PERMISSION);
+ MAP(INTERNAL);
+ MAP(MARSHAL);
+ MAP(INITIALIZE);
+ MAP(NO_IMPLEMENT);
+ MAP(BAD_OPERATION);
+ MAP(NO_RESOURCES);
+ MAP(NO_RESPONSE);
+ MAP(TRANSIENT);
+ MAP(FREE_MEM);
+ MAP(INV_IDENT);
+ MAP(INV_FLAG);
+ MAP(DATA_CONVERSION);
+ MAP(OBJECT_NOT_EXIST);
+ MAP(TIMEOUT);
+ MAP(APPLICATION);
+ }
+ return ret;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file fres_error.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Wed Feb 18 15:38:41 2009
+ *
+ * @brief Error constants and helper functions
+ *
+ */
+
+#ifndef FRES_ERROR_H
+#define FRES_ERROR_H
+
+#include <forb/object_type.h>
+
+#define FRES_ERR_BASE_VALUE 0x02008000
+
+enum fres_error {
+ FRES_ERR_FCB_NOT_RUNNING = FRES_ERR_BASE_VALUE,
+ FRES_ERR_FORB_EXCEPTION,
+ FRES_ERR_BLOCK_NOT_REGISTERED,
+ FRES_ERR_NEEDS_MORE_DATA_IN_CONTRACT,
+ FRES_ERR_NOTHING_TO_RENEGOTIATE,
+ FRES_ERR_BLOCK_DUP,
+ FRES_ERR_NO_RESOURCE_ALLOCATOR,
+ FRES_ERR_ADMISSION_TEST,
+ FRES_ERR_KERNEL_SUPPORT_MISSING,
+ FRES_ERR_FORB_EX_BAD_PARAM,
+ FRES_ERR_FORB_EX_NO_MEMORY,
+ FRES_ERR_FORB_EX_IMP_LIMIT,
+ FRES_ERR_FORB_EX_COMM_FAILURE,
+ FRES_ERR_FORB_EX_INV_OBJREF,
+ FRES_ERR_FORB_EX_NO_PERMISSION,
+ FRES_ERR_FORB_EX_INTERNAL,
+ FRES_ERR_FORB_EX_MARSHAL,
+ FRES_ERR_FORB_EX_INITIALIZE,
+ FRES_ERR_FORB_EX_NO_IMPLEMENT,
+ FRES_ERR_FORB_EX_BAD_OPERATION,
+ FRES_ERR_FORB_EX_NO_RESOURCES,
+ FRES_ERR_FORB_EX_NO_RESPONSE,
+ FRES_ERR_FORB_EX_TRANSIENT,
+ FRES_ERR_FORB_EX_FREE_MEM,
+ FRES_ERR_FORB_EX_INV_IDENT,
+ FRES_ERR_FORB_EX_INV_FLAG,
+ FRES_ERR_FORB_EX_DATA_CONVERSION,
+ FRES_ERR_FORB_EX_OBJECT_NOT_EXIST,
+ FRES_ERR_FORB_EX_TIMEOUT,
+ FRES_ERR_FORB_EX_APPLICATION,
+ FRES_ERR_NO_RESOURCE_MANAGER,
+ FRES_ERR_ALLOCATOR_ALREADY_REGISTERED,
+ FRES_ERR_VRES_ALREADY_ALLOCATED,
+ FRES_ERR_VRES_PART_OF_TRANSACTION,
+ FRES_ERR_SPARE_CAPACITY_NOT_SUPPORTED,
+ FRES_ERR_TRANSACTION_NOT_FOUND,
+ // Elisp function to update .c: (update-fres-error-c)
+};
+
+int fres_strerror (int error, char *message, size_t size);
+
+int fres_forbex2err(CORBA_Environment *env);
+
+#endif
--- /dev/null
+/**
+ * @file fres_transaction.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Mon Jun 21 16:34:00 2010
+ *
+ * @brief Distributed transaction manipulation
+ */
+
+#include <fres_transaction.h>
+
+/**
+ * Allocates new transaction.
+ *
+ * @return Pointer to the newly allocated transaction or NULL in case
+ * of error.
+ */
+fres_transaction_t*
+fres_transaction_new()
+{
+ fres_transaction_t *t;
+
+ t = malloc(sizeof(*t));
+ if (!t)
+ goto err;
+ memset(t, 0, sizeof(*t));
+ CORBA_sequence_set_release(&t->contracts, CORBA_TRUE);
+ return t;
+err:
+ return NULL;
+}
+
+void
+fres_transaction_destroy(fres_transaction_t *t)
+{
+ if (t) {
+ forb_sequence_free_buf(&t->contracts, fres_contract_ptr_destroy);
+ free(t->name);
+ free(t);
+ }
+}
+
+fres_transaction_t *
+fres_transaction_duplicate(fres_transaction_t *src)
+{
+ fres_transaction_t *dst;
+ int i;
+
+ if (!src)
+ goto err;
+ dst = malloc(sizeof(*dst));
+ /* Copy all static mambers */
+ memcpy(dst, src, sizeof(*dst));
+ /* And now the dynamic ones */
+ if (src->name)
+ dst->name = strdup(src->name);
+ forb_sequence_alloc_buf(&dst->contracts,
+ fres_transaction_num_contracts(src));
+ for (i = 0; i < fres_transaction_num_contracts(src); i++) {
+ struct fres_contract *c;
+ c = fres_transaction_get_contract(src, i);
+ fres_transaction_add_contract(dst, fres_contract_duplicate(c));
+ }
+ return dst;
+err:
+ return NULL;
+}
+
+int
+fres_transaction_add_contract(fres_transaction_t *t,
+ struct fres_contract *c)
+{
+ void *ptr;
+ unsigned num = forb_sequence_length(&t->contracts);
+ ptr = forb_sequence_ensure_allocated(&t->contracts, num+1);
+ if (!ptr)
+ goto err;
+ forb_sequence_elem(&t->contracts, num) = c;
+ forb_sequence_length(&t->contracts)++;
+ return num;
+err:
+ return -1;
+}
--- /dev/null
+#ifndef FRES_TRANSACTION_H
+#define FRES_TRANSACTION_H
+
+#include <fres_transaction_idl.h>
+#include <fres_contract.h>
+
+fres_transaction_t*
+fres_transaction_new(void);
+
+void
+fres_transaction_destroy(fres_transaction_t *t);
+
+fres_transaction_t *
+fres_transaction_duplicate(fres_transaction_t *t);
+
+int
+fres_transaction_add_contract(fres_transaction_t *t,
+ struct fres_contract *c);
+
+static inline unsigned
+fres_transaction_num_contracts(fres_transaction_t *t)
+{
+ return forb_sequence_length(&t->contracts);
+}
+
+
+static inline struct fres_contract*
+fres_transaction_get_contract(fres_transaction_t *t, unsigned index)
+{
+ if (index < fres_transaction_num_contracts(t))
+ return forb_sequence_elem(&t->contracts, index);
+ else
+ return NULL;
+}
+
+
+#endif
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------------------- //
+// Copyright © 2010 Michal Sojka //
+// //
+// This file is part of FRSH/FORB. //
+// //
+// FRSH/FORB is free software; you can redistribute it and/or modify it //
+// under terms of the GNU General Public License as published by the //
+// Free Software Foundation; either version 2, or (at your option) any //
+// later version. FORB is distributed in the hope that it will be //
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty //
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
+// General Public License for more details. You should have received a //
+// copy of the GNU General Public License along with FORB; see file //
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, //
+// Cambridge, MA 02139, USA. //
+// //
+// As a special exception, including FRSH/FORB header files in a file, //
+// instantiating FRSH/FORB generics or templates, or linking other files //
+// with FRSH/FORB objects to produce an executable application, does not //
+// by itself cause the resulting executable application to be covered //
+// by the GNU General Public License. This exception does not //
+// however invalidate any other reasons why the executable file might be //
+// covered by the GNU Public License. //
+////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @file fres_transaction_idl.idl
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ *
+ * @brief Definitions of data types and constants for FRSH distributed
+ * transactions.
+ *
+ */
+
+#ifndef _TRANSACTION_IDL
+#define _TRANSACTION_IDL
+
+#include "fres_contract_idl.idl"
+
+module fres {
+ struct transaction_t {
+ string name;
+ contract::ptr_seq contracts;
+ boolean consistent_spare_capacity;
+ };
+};
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file idl_native.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Wed Feb 18 15:40:19 2009
+ *
+ * @brief (De)Serialization of IDL native types
+ *
+ *
+ */
+
+
+#ifndef IDL_NATIVE_H
+#define IDL_NATIVE_H
+
+#include <fosa.h>
+#include <fres_container_type.h>
+#include <frsh_core_types.h>
+#include <forb/cdr.h>
+
+static inline CORBA_boolean
+fosa_rel_time_t_serialize(FORB_CDR_Codec *codec, const struct timespec *ts)
+{
+ CORBA_long sec = ts->tv_sec;
+ CORBA_long nsec = ts->tv_nsec;
+ if (!CORBA_long_serialize(codec, &sec)) return CORBA_FALSE;
+ if (!CORBA_long_serialize(codec, &nsec)) return CORBA_FALSE;
+ return CORBA_TRUE;
+}
+
+static inline CORBA_boolean
+fosa_rel_time_t_deserialize(FORB_CDR_Codec *codec, struct timespec *ts)
+{
+ CORBA_long sec, nsec;
+ if (!CORBA_long_deserialize(codec, &sec)) return CORBA_FALSE;
+ if (!CORBA_long_deserialize(codec, &nsec)) return CORBA_FALSE;
+ ts->tv_sec = sec;
+ ts->tv_nsec = nsec;
+ return CORBA_TRUE;
+}
+
+#define fosa_abs_time_t_serialize(codec,ts) fosa_rel_time_t_serialize((codec), (ts))
+#define fosa_abs_time_t_deserialize(codec,ts) fosa_rel_time_t_deserialize((codec), (ts))
+
+/* HACK: These types are declared in both .idl and FRSH .h files. To
+ * use the C types instead of IDL types with the same name, we defines
+ * the "protecting" defines here. Since this file is included in the
+ * beginning of IDL generated header, we efectively disable the IDL
+ * declarations. */
+#define _frsh_resource_type_t_defined 1
+#define _frsh_resource_id_t_defined 1
+#define _frsh_workload_t_defined 1
+#define _frsh_contract_type_t_defined 1
+#define _frsh_granularity_t_defined 1
+#define _frsh_signal_t_defined 1
+#define _frsh_signal_info_t_defined 1
+
+#define _frsh_csect_runtime_t_defined 1
+typedef FRSH_CSECT_RUNTIME_T_OPAQUE frsh_csect_runtime_t;
+
+#define frsh_resource_type_t_serialize(codec, val) CORBA_unsigned_long_serialize(codec, val)
+#define frsh_resource_type_t_deserialize(codec, val) CORBA_unsigned_long_deserialize(codec, val)
+#define frsh_resource_id_t_serialize(x,y) CORBA_unsigned_long_serialize((x),(y))
+#define frsh_resource_id_t_deserialize(x,y) CORBA_unsigned_long_deserialize((x),(y))
+#define frsh_workload_t_serialize(codec, val) CORBA_unsigned_long_serialize(codec, val)
+#define frsh_workload_t_deserialize(codec, val) CORBA_unsigned_long_deserialize(codec, val)
+#define frsh_contract_type_t_serialize(codec, val) CORBA_unsigned_long_serialize(codec, val)
+#define frsh_contract_type_t_deserialize(codec, val) CORBA_unsigned_long_deserialize(codec, val)
+#define frsh_granularity_t_serialize(codec, val) CORBA_unsigned_long_serialize(codec, val)
+#define frsh_granularity_t_deserialize(codec, val) CORBA_unsigned_long_deserialize(codec, val)
+#define frsh_signal_t_serialize(x,y) CORBA_long_serialize((x),(y))
+#define frsh_signal_t_deserialize(x,y) CORBA_long_deserialize((x),(y))
+#define frsh_signal_info_t_serialize(x,y) CORBA_long_serialize((x),(y))
+#define frsh_signal_info_t_deserialize(x,y) CORBA_long_deserialize((x),(y))
+
+
+static inline CORBA_boolean
+frsh_csect_runtime_t_serialize
+ (FORB_CDR_Codec *codec,
+ const frsh_csect_runtime_t *c)
+{
+ CORBA_long op_kind;
+ op_kind = c->op_kind;
+ if (!CORBA_long_serialize(codec, &op_kind))
+ return CORBA_FALSE;
+ if (!CORBA_string_serialize(codec, &c->obj_label))
+ return CORBA_FALSE;
+ if (!fosa_rel_time_t_serialize(codec, &c->wcet))
+ return CORBA_FALSE;
+ if (!fosa_rel_time_t_serialize(codec, &c->blocking))
+ return CORBA_FALSE;
+ return CORBA_TRUE;
+}
+
+static inline CORBA_boolean
+frsh_csect_runtime_t_deserialize
+ (FORB_CDR_Codec *codec,
+ frsh_csect_runtime_t *c)
+{
+ CORBA_long op_kind;
+ if (!CORBA_long_deserialize(codec, &op_kind))
+ return CORBA_FALSE;
+ c->op_kind = (frsh_csect_op_kind_t) op_kind;
+ if (!CORBA_string_deserialize(codec, (CORBA_char**) &c->obj_label))
+ return CORBA_FALSE;
+ if (!fosa_rel_time_t_deserialize(codec, &c->wcet))
+ return CORBA_FALSE;
+ if (!fosa_rel_time_t_deserialize(codec, &c->blocking))
+ return CORBA_FALSE;
+ return CORBA_TRUE;
+}
+
+#endif
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+wvtest_PROGRAMS:=$(addprefix fres-,$(basename $(notdir $(wildcard $(SOURCES_DIR)/*.c))))
+
+CFLAGS += -DWVTEST_CONFIGURED
+
+$(foreach t,$(wvtest_PROGRAMS),\
+$(eval $(t)_SOURCES = $(t:fres-%=%).c)\
+$(eval $(t)_LIBS = fosa m contract rt forb ulut wvtest)\
+)
--- /dev/null
+#include <fres_contract.h>
+#include <error.h>
+#include <errno.h>
+#include <fres_blocks.h>
+#include <string.h>
+#include <fres_contract_type.h>
+#include <stdio.h>
+#include <forb/cdr.h>
+#include <wvtest.h>
+
+void cmp(struct fres_contract *c1, struct fres_contract *c2, const char *msg)
+{
+ int ret;
+ if (!WVPASS((ret = strcmp(fres_contract_get_label(c1)->label,
+ fres_contract_get_label(c2)->label)) == 0))
+ error(1, 0, "%s: label cmp failed %d", msg, ret);
+
+ if (!WVPASS((ret = memcmp(fres_contract_get_resource(c1),
+ fres_contract_get_resource(c2),
+ sizeof(fres_block_resource))) == 0))
+ error(1, 0, "%s: resource cmp failed %d", msg, ret);
+
+ if (!WVPASS((ret = memcmp(fres_contract_get_basic(c1),
+ fres_contract_get_basic(c2),
+ sizeof(fres_block_basic))) == 0))
+ error(1, 0, "%s: basic cmp failed %d", msg, ret);
+
+ if (!WVPASS((ret = memcmp(fres_contract_get_timing_reqs(c1),
+ fres_contract_get_timing_reqs(c2),
+ sizeof(fres_block_timing_reqs))) == 0))
+ error(1, 0, "%s: timing_reqs cmp failed %d", msg, ret);
+
+ /*ret = memcmp(fres_contract_get_csects(c1),
+ fres_contract_get_csects(c2),
+ sizeof(fres_block_csects));
+ if (ret) error(1, 0, "%s: critical_sects cmp failed %d", msg, ret);*/
+}
+
+WVTEST_MAIN("contract manipulation")
+{
+ struct fres_contract *c, *c2;
+ fres_block_label *label;
+ fres_block_resource *resource;
+ fres_block_basic *basic;
+ fres_block_timing_reqs *timing_reqs;
+ //fres_block_csects *critical_sects;
+
+ if (!WVPASS(c = fres_contract_new()))
+ error(1, errno, "fres_contract_new");
+
+ if (!WVPASS(label = malloc(sizeof(*label))))
+ error(1, errno, "cannot allocate memory for label");
+ strcpy(label->label, "TestLabel");
+ if (!WVPASS(fres_contract_add_label(c, label) == 0))
+ error(1, errno, "fres_contract_add_label");
+
+ if (!WVPASS(resource = malloc(sizeof(*resource))))
+ error(1, errno, "cannot allocate memory for resource");
+ resource->resource_type = FRSH_RT_NETWORK;
+ resource->resource_id = 12;
+ if (!WVPASS(fres_contract_add_resource(c, resource) == 0))
+ error(1, errno, "fres_contract_add_resource");
+
+ if (!WVPASS(basic = malloc(sizeof(*basic))))
+ error(1, errno, "cannot allocate memory for basic");
+ basic->budget = fosa_msec_to_rel_time(10);
+ basic->period = fosa_msec_to_rel_time(100);
+ basic->workload = FRSH_WT_SYNCHRONIZED;
+ basic->contract_type = FRSH_CT_REGULAR;
+ if (!WVPASS(fres_contract_add_basic(c, basic) == 0))
+ error(1, errno, "fres_contract_add_basic");
+
+ if (!WVPASS(timing_reqs = malloc(sizeof(*timing_reqs))))
+ error(1, errno, "cannot allocate memory for timing_reqs");
+ timing_reqs->d_equals_t = CORBA_FALSE;
+ timing_reqs->deadline = fosa_msec_to_rel_time(50);
+ if (!WVPASS(fres_contract_add_timing_reqs(c, timing_reqs) == 0))
+ error(1, errno, "fres_contract_add_timing_reqs");
+#if 0
+ if (!WVPASS(critical_sects = malloc(sizeof(*critical_sects))))
+ error(1, errno, "cannot allocate memory for critical_sects");
+ //criticacl_sects->;
+ if (!WVPASS(fres_contract_add_csects(c, critical_sects) == 0))
+ error(1, errno, "fres_contract_add_csects");
+#endif
+ if (!WVPASS(c2 = fres_contract_duplicate(c)))
+ error(1, errno, "fres_contract_duplicate");
+ cmp(c, c2, "cmp after fres_contract_duplicate");
+
+ fres_contract_destroy(c2);
+
+ {
+ FORB_CDR_Codec codec;
+ CORBA_boolean cb;
+ FORB_CDR_codec_init_static(&codec, NULL);
+ cb = FORB_CDR_buffer_init(&codec, 4000, 0);
+ if (!cb) error(1, errno, "CDR_buffer_init");
+
+ cb = fres_contract_ptr_serialize(&codec, &c);
+ if (!cb) error(1, 0, "fres_contract_ptr_serialize failed");
+ cb = fres_contract_ptr_deserialize(&codec, &c2);
+ if (!cb) error(1, 0, "fres_contract_ptr_deserialize failed");
+
+ cmp(c, c2, "cmp after serialize/desearialize");
+
+ fres_contract_destroy(c2);
+ }
+ fres_contract_destroy(c);
+}
--- /dev/null
+#include <fres_transaction.h>
+#include <error.h>
+#include <errno.h>
+#include <wvtest.h>
+
+void cmp(struct fres_contract *c1, struct fres_contract *c2, const char *msg)
+{
+ int ret;
+ if (!WVPASS((ret = strcmp(fres_contract_get_label(c1)->label,
+ fres_contract_get_label(c2)->label)) == 0))
+ error(1, 0, "%s: label cmp failed %d", msg, ret);
+
+ if (!WVPASS((ret = memcmp(fres_contract_get_resource(c1),
+ fres_contract_get_resource(c2),
+ sizeof(fres_block_resource))) == 0))
+ error(1, 0, "%s: resource cmp failed %d", msg, ret);
+
+ if (!WVPASS((ret = memcmp(fres_contract_get_basic(c1),
+ fres_contract_get_basic(c2),
+ sizeof(fres_block_basic))) == 0))
+ error(1, 0, "%s: basic cmp failed %d", msg, ret);
+
+ if (!WVPASS((ret = memcmp(fres_contract_get_timing_reqs(c1),
+ fres_contract_get_timing_reqs(c2),
+ sizeof(fres_block_timing_reqs))) == 0))
+ error(1, 0, "%s: timing_reqs cmp failed %d", msg, ret);
+
+ /*ret = memcmp(fres_contract_get_csects(c1),
+ fres_contract_get_csects(c2),
+ sizeof(fres_block_csects));
+ if (ret) error(1, 0, "%s: critical_sects cmp failed %d", msg, ret);*/
+}
+
+WVTEST_MAIN("transaction manipulation")
+{
+ fres_transaction_t *t1, *t2;
+ struct fres_contract *c;
+
+ WVPASS(t1 = fres_transaction_new());
+ WVPASS(fres_transaction_num_contracts(t1) == 0);
+ WVFAIL(fres_transaction_get_contract(t1, 0));
+ WVPASS(c = fres_contract_new());
+ WVPASS(fres_transaction_add_contract(t1, c) >= 0);
+ WVPASS(fres_transaction_num_contracts(t1) == 1);
+ WVPASS(fres_transaction_get_contract(t1, 0) == c);
+
+ WVPASS(t2 = fres_transaction_duplicate(t1));
+ WVPASS(fres_transaction_num_contracts(t2) == 1);
+ WVPASS(fres_transaction_get_contract(t2, 0) != NULL);
+ WVPASS(fres_transaction_get_contract(t2, 0) != c);
+
+ fres_transaction_destroy(t1);
+}
--- /dev/null
+#include "utils.h"
+
+size_t fres_indent_str(char *dest, size_t size, char *src, unsigned indent_by)
+{
+ char *p = src;
+ size_t written = 0;
+ while (*p && size > 1) {
+ if (p == src || *(p-1) == '\n') { /* indent */
+ int i;
+ for (i=0; i<indent_by; i++) {
+ *dest++ = ' ';
+ written++;
+ size--;
+ }
+ }
+ *dest++ = *p++;
+ written++;
+ size--;
+ }
+ *dest = 0;
+ return written;
+}
--- /dev/null
+#ifndef FRES_UTILS_H
+#define FRES_UTILS_H
+
+#include <stddef.h>
+
+size_t fres_indent_str(char *dest, size_t size, char *src, unsigned indent_by);
+
+#endif
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+QT_PROJECTS = frm_gui.pro
--- /dev/null
+#include "contractlistmodel.h"
+#include <fres_contract.h>
+#include <QByteArray>
+#include <stdio.h>
+
+ContractListModel::ContractListModel(QObject *parent) :
+ QAbstractListModel(parent), contracts(0)
+{
+}
+
+int ContractListModel::rowCount(const QModelIndex &parent) const
+{
+ if (contracts && !parent.isValid())
+ return contracts->_length;
+ else
+ return 0;
+}
+
+QVariant ContractListModel::data(const QModelIndex &index, int role) const
+{
+ if (index.isValid() && contracts) {
+ switch (role) {
+ case Qt::DisplayRole: {
+ QByteArray buf(100, 0);
+ struct fres_contract *c;
+ fres_block_label *l;
+ char id[100];
+ c = contracts->_buffer[index.row()];
+ l = fres_contract_get_label(c);
+ buf.data()[0] = 0;
+ fres_contract_id_to_string(id, &c->id, sizeof(id));
+ if (l) {
+ snprintf(buf.data(), buf.size(), "%s (%s)", l->label, id);
+ } else {
+ snprintf(buf.data(), buf.size(), "%s", id);
+ }
+ return QVariant(buf);
+ }
+ case ContractRole:
+ struct fres_contract *c;
+ c = contracts->_buffer[index.row()];
+ return qVariantFromValue((void*)c);
+
+ }
+ }
+ return QVariant();
+}
+
+int ContractListModel::update(fres_resource_manager frm, int &utilization)
+{
+ CORBA_Environment ev;
+ fres_contract_ptr_seq *contracts_new;
+
+ if (frm) {
+ fres_resource_manager_get_contracts(frm, &contracts_new, &utilization, &ev);
+ if (!forb_exception_occurred(&ev)) {
+ if (contracts) {
+ forb_sequence_free(contracts, fres_contract_ptr_destroy);
+ }
+ contracts = contracts_new;
+ } else {
+ contracts = 0;
+ }
+ reset();
+ }
+ return 0;
+}
+
+Qt::ItemFlags ContractListModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return 0;
+
+ return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+ }
--- /dev/null
+#ifndef CONTRACTLISTMODEL_H
+#define CONTRACTLISTMODEL_H
+
+#include <QAbstractListModel>
+#include <forb.h>
+#include <QStringList>
+#include <frm.h>
+
+const int ContractRole = Qt::UserRole+2;
+
+class ContractListModel : public QAbstractListModel
+{
+public:
+ ContractListModel(QObject *parent);
+ int rowCount(const QModelIndex &parent) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ int update(fres_resource_manager frm, int &utilization);
+private:
+ forb_orb orb;
+ fres_contract_ptr_seq *contracts;
+};
+
+#endif // CONTRACTLISTMODEL_H
--- /dev/null
+#include "dialog.h"
+#include "ui_dialog.h"
+#include <forb.h>
+#include <QTimer>
+#include <iostream>
+#include <fres_contract.h>
+
+using namespace std;
+
+Dialog::Dialog(QWidget *parent)
+ : QDialog(parent), ui(new Ui::DialogClass), frm(0)
+{
+ ui->setupUi(this);
+ forb_init_attr_t attr;
+ memset(&attr, 0, sizeof(attr));
+ attr.orb_id = "org.frescor.frm_gui";
+ orb = forb_init(0, NULL, &attr);
+ resourcesModel = new ResourceListModel(this, orb);
+ contractsModel = new ContractListModel(this);
+ ui->resources->setModel(resourcesModel);
+ ui->contracts->setModel(contractsModel);
+
+ timer = new QTimer();
+ connect(timer, SIGNAL(timeout()), this, SLOT(updateData()));
+ timer->start(1000);
+ ui->status->setText("");
+}
+
+Dialog::~Dialog()
+{
+ delete ui;
+}
+
+void Dialog::on_contracts_clicked(QModelIndex index)
+{
+ QByteArray str(1000, 0);
+ fres_contract *c;
+ c = (fres_contract *)contractsModel->data(index, ContractRole).value<void*>();
+ fres_contract_to_string(str.data(), str.size(), c);
+ ui->contractText->setText(QString(str));
+}
+
+void Dialog::updateResource()
+{
+ int utilization;
+ contractsModel->update(frm, utilization);
+ ui->utilization->setEnabled(utilization >= 0);
+ if (utilization >= 0)
+ ui->utilization->setValue(utilization);
+ else
+ ui->utilization->setValue(0);
+
+}
+
+void Dialog::updateData()
+{
+ int ret;
+ bool ok;
+ ret = resourcesModel->update();
+ ok = (ret == 0);
+ this->setEnabled(ok);
+ ui->status->setText(ok ? "FCB contacted" : "FCB not found!");
+ if (ok) {
+ if (ui->resources->currentIndex() == -1 &&
+ resourcesModel->rowCount(QModelIndex()) > 0) {
+ ui->resources->setCurrentIndex(0);
+ }
+ updateResource();
+ }
+}
+
+void Dialog::on_resources_currentIndexChanged(int index)
+{
+ frm = (fres_resource_manager)resourcesModel->data(resourcesModel->index(index,0), ObjRefRole).value<void*>();
+ updateResource();
+}
--- /dev/null
+#ifndef DIALOG_H
+#define DIALOG_H
+
+#include <QtGui/QDialog>
+#include <QTimer>
+#include <QModelIndex>
+#include <forb.h>
+#include <frm.h>
+#include "contractlistmodel.h"
+#include "resourcelistmodel.h"
+
+namespace Ui
+{
+ class DialogClass;
+}
+
+class Dialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ Dialog(QWidget *parent = 0);
+ ~Dialog();
+
+private:
+ Ui::DialogClass *ui;
+ forb_orb orb;
+ ResourceListModel *resourcesModel;
+ ContractListModel *contractsModel;
+ QTimer *timer;
+ ContractListModel *contracts;
+ fres_resource_manager frm;
+
+private slots:
+ void on_resources_currentIndexChanged(int index);
+ void on_contracts_clicked(QModelIndex index);
+ void updateData();
+ void updateResource();
+
+};
+
+#endif // DIALOG_H
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DialogClass</class>
+ <widget class="QDialog" name="DialogClass">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>FRESCOR Resource Manager Inspector</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <layout class="QHBoxLayout" name="contentLayout">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>&Resource:</string>
+ </property>
+ <property name="buddy">
+ <cstring>resources</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="resources"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>&Contracts:</string>
+ </property>
+ <property name="buddy">
+ <cstring>contracts</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListView" name="contracts"/>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Utilization:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QProgressBar" name="utilization">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="contractText">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>10</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Contract details</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="status">
+ <property name="text">
+ <string>Status:</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+ <slots>
+ <slot>showContractDetail(QModelIndex)</slot>
+ </slots>
+</ui>
--- /dev/null
+# -------------------------------------------------
+# Project created by QtCreator 2009-02-09T12:54:33
+# -------------------------------------------------
+TARGET = frm_gui
+TEMPLATE = app
+SOURCES += main.cpp \
+ dialog.cpp \
+ contractlistmodel.cpp \
+ resourcelistmodel.cpp
+HEADERS += dialog.h \
+ contractlistmodel.h \
+ resourcelistmodel.h
+FORMS += dialog.ui
+DEFINES += AQuoSA
+LIBS += -lpthread -lfrsh -lfrm_client -lforb -lcontract
+QMAKE_CXXFLAGS += -D__STDC_FORMAT_MACROS # Needed for fres_contract.h
--- /dev/null
+#include <QtGui/QApplication>
+#include "dialog.h"
+#include <getopt.h>
+#include <ul_logreg.h>
+#include <stdio.h>
+
+static struct option long_opts[] = {
+ { "loglevel", 1, 0, 'l' },
+ { 0, 0, 0, 0}
+};
+
+static void
+usage(void)
+{
+ printf("usage: frm_gui [ options ]\n");
+ printf(" -l, --loglevel <number>|<domain>=<number>,...\n");
+}
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ Dialog w;
+ char opt;
+
+ while ((opt = getopt_long(argc, argv, "l:", &long_opts[0], NULL)) != EOF) {
+ switch (opt) {
+ case 'l':
+ ul_log_domain_arg2levels(optarg);
+ break;
+ case 'h':
+ /*default:*/
+ usage();
+ exit(opt == 'h' ? 0 : 1);
+ }
+ }
+
+ w.show();
+ return a.exec();
+}
--- /dev/null
+#include <QMessageBox>
+#include "resourcelistmodel.h"
+#include <iostream>
+using namespace std;
+
+QString resTypeNames[] = {
+ "CPU",
+ "NET",
+ "MEM",
+ "DISK",
+ "FPGA"
+};
+
+QString restype2str(unsigned type)
+{
+ if (type < sizeof(resTypeNames)/sizeof(*resTypeNames)) {
+ return resTypeNames[type];
+ } else
+ return QString("%1").arg(type);
+}
+
+ResourceListModel::ResourceListModel(QObject *parent, forb_orb aorb) :
+ QAbstractListModel(parent),
+ orb(aorb), resources(0)
+{
+}
+
+int ResourceListModel::update()
+{
+ fres_contract_broker fcb;
+ CORBA_Environment ev;
+ fres_resource_seq *old;
+ unsigned i;
+
+ fcb = forb_resolve_reference(orb, fres_contract_broker_reg_name);
+ if (!fcb) {
+ //QMessageBox::warning(0, tr("Warning"), tr("Could not find contract broker."));
+ return -1;
+ }
+
+ old = resources;
+ fres_contract_broker_get_resources(fcb, &resources, &ev);
+ forb_object_release(fcb);
+ if (forb_exception_occurred(&ev)) {
+ return -1;
+ }
+
+ if (!old) {
+ reset();
+ } else {
+ for (i=0; i<resources->_length && i<old->_length; i++) {
+ if (resources->_buffer[i].restype != old->_buffer[i].restype ||
+ resources->_buffer[i].resid != old->_buffer[i].resid) {
+ dataChanged(createIndex(i, 0), createIndex(i, 0));
+ }
+ }
+ if (old->_length != resources->_length) {
+// dataChanged(createIndex(min(old->_length, resources->_length), 0),
+// createIndex(max(old->_length, resources->_length), 0));
+ reset();
+ }
+ forb_free(old->_buffer);
+ forb_free(old);
+ }
+
+ return 0;
+}
+
+int ResourceListModel::rowCount(const QModelIndex &parent) const
+{
+ if (resources && !parent.isValid()) {
+ return resources->_length;
+ } else
+ return 0;
+}
+
+QVariant ResourceListModel::data(const QModelIndex &index, int role) const
+{
+ if (resources && index.isValid())
+ {
+ switch (role) {
+ case Qt::DisplayRole:
+ case Qt::EditRole:
+ return QVariant(QString("%1 (%2.%3)")
+ .arg(resources->_buffer[index.row()].desc.name)
+ .arg(restype2str(resources->_buffer[index.row()].restype))
+ .arg(resources->_buffer[index.row()].resid));
+ case ObjRefRole:
+ return qVariantFromValue((void*)resources->_buffer[index.row()].desc.manager);
+ }
+ }
+ return QVariant();
+}
+
+
+Qt::ItemFlags ResourceListModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return 0;
+
+ return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+ }
--- /dev/null
+#ifndef RESOURCELISTMODEL_H
+#define RESOURCELISTMODEL_H
+
+#include <QAbstractListModel>
+#include <forb.h>
+#include <fcb.h>
+
+const int ObjRefRole = Qt::UserRole+1;
+
+class ResourceListModel : public QAbstractListModel
+{
+public:
+ ResourceListModel(QObject *parent, forb_orb aorb);
+ int update();
+ int rowCount(const QModelIndex &parent) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+private:
+ forb_orb orb;
+ fres_resource_seq *resources;
+};
+
+#endif // RESOURCELISTMODEL_H
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+shared_LIBRARIES += fra
+fra_SOURCES = fra_generic.c fra_registry.c fres_vres.c
+fra_SERVER_IDL = fra.idl
+include_GEN_HEADERS += fra.h
+include_HEADERS = fra_generic.h fres_vres.h
+
+lib_LIBRARIES += fra_client
+fra_client_CLIENT_IDL = fra.idl
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------------------- //
+// Copyright (C) 2006 - 2008 FRESCOR consortium partners: //
+// //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// Scuola Superiore Sant'Anna, ITALY //
+// Kaiserslautern University, GERMANY //
+// Univ. Politécnica Valencia, SPAIN //
+// Czech Technical University in Prague, CZECH REPUBLIC //
+// ENEA SWEDEN //
+// Thales Communication S.A. FRANCE //
+// Visual Tools S.A. SPAIN //
+// Rapita Systems Ltd UK //
+// Evidence ITALY //
+// //
+// See http://www.frescor.org for a link to partners' websites //
+// //
+// FRESCOR project (FP6/2005/IST/5-034026) is funded //
+// in part by the European Union Sixth Framework Programme //
+// The European Union is not liable of any use that may be //
+// made of this code. //
+// //
+// //
+// based on previous work (FSF) done in the FIRST project //
+// //
+// Copyright (C) 2005 Mälardalen University, SWEDEN //
+// Scuola Superiore S.Anna, ITALY //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// //
+// FSF API web pages: http:marte.unican.es/fsf/docs //
+// http:shark.sssup.it/contrib/first/docs/ //
+// //
+// This file is part of FORB (Frescor Object Request Broker) //
+// //
+// FORB is free software; you can redistribute it and/or modify it //
+// under terms of the GNU General Public License as published by the //
+// Free Software Foundation; either version 2, or (at your option) any //
+// later version. FORB is distributed in the hope that it will be //
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty //
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
+// General Public License for more details. You should have received a //
+// copy of the GNU General Public License along with FORB; see file //
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, //
+// Cambridge, MA 02139, USA. //
+// //
+// As a special exception, including FORB header files in a file, //
+// instantiating FORB generics or templates, or linking other files //
+// with FORB objects to produce an executable application, does not //
+// by itself cause the resulting executable application to be covered //
+// by the GNU General Public License. This exception does not //
+// however invalidate any other reasons why the executable file might be //
+// covered by the GNU Public License. //
+////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @file fra.idl
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Thu Nov 13 14:05:39 2008
+ *
+ * @brief FORB interface to resource allocator
+ *
+ *
+ */
+#ifndef _FRA_IDL
+#define _FRA_IDL
+
+#include "../contract/fres_contract_idl.idl"
+
+module fres {
+ /**
+ * Interface to the allocator
+ *
+ */
+ interface resource_allocator {
+ /**
+ * Creates or changes VRESes.
+ *
+ * This method is called after the contracts are
+ * negotiated with the resource manager. The manager
+ * together with the contract broker ensure that the
+ * state after applying the changes specified by @a
+ * schedulable_contracts parameter is schedulable. It
+ * is up to the allocator to apply the changes in such
+ * way that schedulability is maintained during the
+ * change. The changes are received in the same order
+ * as returned by the manager, so if the manager
+ * already prepares the order of aplying changes, the
+ * allocator can use it.
+ *
+ * @param schedulable_contracts Contracts for VRESes
+ * to be created, changed (if they already exist) or
+ * canceled (if they contain no blocks).
+ *
+ * @return Zero on success, non-zero error number in
+ * case of error.
+ */
+ long change_vreses(in contract::ptr_seq schedulable_contracts);
+ };
+};
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file fra_generic.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Thu Oct 23 15:26:19 2008
+ *
+ * @brief FORB interface of FRES Resource Allocator
+ *
+ *
+ */
+#include <forb.h>
+#include <fra.h>
+#include <fcb.h>
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include "fra_generic.h"
+
+UL_LOG_CUST(ulogd_fra);
+ul_log_domain_t ulogd_fra = {UL_LOGL_MSG, "fra"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(fra_logreg_domains, ulogd_fra);
+
+/**
+ * Global "registry" of all virtual resources in one application.
+ */
+struct fres_vreses fres_vreses;
+
+GAVL_CUST_NODE_INT_IMP(fres_vreses_nolock /* cust_prefix */,
+ struct fres_vreses /* cust_root_t */,
+ struct fres_vres /* cust_item_t */,
+ fres_contract_id_t /* cust_key_t */,
+ vreses /* cust_root_node */,
+ node /* cust_item_node */,
+ id /* cust_item_key */,
+ fres_contract_id_cmp /* cust_cmp_fnc */);
+
+
+/**
+ * * Global "registry" of all bound threads in one application.
+ * */
+struct fres_threads_vres fres_threads_vres;
+
+GAVL_CUST_NODE_INT_IMP(fres_threads_vres_nolock /* cust_prefix */,
+ struct fres_threads_vres /* cust_root_t */,
+ struct fres_thread_vres /* cust_item_t */,
+ fres_thread_vres_key_t /* cust_key_t */,
+ threads /* cust_root_node */,
+ node /* cust_item_node */,
+ thread_vres /* cust_item_key */,
+ fres_thread_vres_cmp /* cust_cmp_fnc */);
+
+/**
+ * Inserts vres to the global vres "registry".
+ *
+ * @param vres
+ *
+ * @return Positive value on success, -1 on error.
+ */
+static int
+fres_vreses_insert(struct fres_vres *vres)
+{
+ int ret;
+ fosa_mutex_lock(&fres_vreses.mutex);
+ ret = fres_vreses_nolock_insert(&fres_vreses, vres);
+ fosa_mutex_unlock(&fres_vreses.mutex);
+ return ret;
+}
+
+static int
+fres_vreses_delete(struct fres_vres *vres)
+{
+ int ret;
+ fosa_mutex_lock(&fres_vreses.mutex);
+ ret = fres_vreses_nolock_delete(&fres_vreses, vres);
+ fosa_mutex_unlock(&fres_vreses.mutex);
+ return ret;
+}
+
+static struct fres_vres *
+fres_vreses_find(fres_contract_id_t *id)
+{
+ struct fres_vres *ret;
+ fosa_mutex_lock(&fres_vreses.mutex);
+ ret = fres_vreses_nolock_find(&fres_vreses, id);
+ fosa_mutex_unlock(&fres_vreses.mutex);
+ return ret;
+}
+
+struct fres_vres *
+fres_vreses_find_label(fres_block_label *label, fres_block_resource *res)
+{
+ struct fres_vres *item;
+
+ gavl_cust_for_each(fres_vreses_nolock, &fres_vreses, item) {
+ struct fres_contract *c = item->perceived;
+ fres_block_label *l = fres_contract_get_label(c);
+ fres_block_resource *r = fres_contract_get_resource(c);
+
+ if (!strncmp(l->label, label->label, strlen(label->label)) &&
+ res->resource_type == r->resource_type &&
+ res->resource_id == r->resource_id)
+ return item;
+ }
+
+ return NULL;
+}
+
+
+#define save_errno(cmd) do { int _e = errno; cmd; errno = _e; } while(0)
+
+CORBA_long change_vreses(fres_resource_allocator obj,
+ const fres_contract_ptr_seq* contracts,
+ CORBA_Environment *ev)
+{
+ int ret;
+ unsigned len = contracts->_length;
+ unsigned i;
+ struct fres_allocator *alloc = forb_instance_data(obj);
+ struct fres_vres **vreses;
+
+ /* Prepare the vres structures */
+ vreses = malloc(len*sizeof(vreses[0]));
+ if (!vreses) {
+ ret = errno;
+ goto err;
+ }
+
+ for (i=0; i<len; i++) {
+ struct fres_contract *contract;
+ struct fres_vres *vres;
+ contract = fres_contract_duplicate(contracts->_buffer[i]);
+ if (!contract) {
+ ret = -1;
+ goto err_free_vreses;
+ }
+ vres = fres_vreses_find(&contract->id);
+ if (!vres) {
+ vres = fres_vres_new(&contract->id);
+ if (!vres) {
+ ret = errno;
+ goto err_free_vreses;
+ }
+ ret = fres_vreses_insert(vres);
+ assert(ret > 0); /* Nobody else inserted the same vres. */
+ }
+ vres->new = contract;
+ vres->allocator = alloc;
+ vreses[i] = vres;
+ }
+
+ /* Apply the changes */
+ if (alloc->apply_vres_changes) {
+ /* Full interface */
+ /* FIXME: Do not call this hook for DUMMY contracts */
+ ret = alloc->apply_vres_changes(vreses, len, alloc->priv);
+ if (ret) {
+ ul_logerr("apply_vres_changes failed %d\n", ret);
+ goto err_free_vreses;
+ }
+ } else {
+ /* Simple interface */
+ for (i=0; i<len; i++) {
+ struct fres_vres *vres = vreses[i];
+ if (fres_contract_get_type(&vres->new) == FRSH_CT_DUMMY)
+ continue;
+ if (fres_contract_get_num_blocks(vres->new) == 0) {
+ /* VRES cancleation */
+ ret = alloc->cancel_vres(vres, alloc->priv);
+
+ fres_vreses_delete(vres);
+ fres_vres_destroy(vres);
+ vreses[i] = NULL;
+ } else if (vres->allocated) {
+ /* VRES change */
+ struct fres_contract *last_perceived = vres->perceived;
+ ret = alloc->change_vres(vreses[i], alloc->priv);
+ if (last_perceived == vres->perceived) {
+ ul_logerr("change_vres callback did not change the perceived vres!\n");
+ vres->perceived = vres->new;
+ }
+ } else {
+ /* VRES creation */
+ ret = alloc->create_vres(vreses[i], alloc->priv);
+ vres->perceived = vres->new;
+ }
+ if (ret) {
+ ul_logerr("VRES apply error %d\n", ret);
+ goto err_free_vreses;
+ }
+ }
+ }
+
+ /* Update the vres structures (move new to allocated) */
+ for (i=0; i<len; i++) {
+ struct fres_vres *vres = vreses[i];
+ struct fres_contract *tmp;
+
+ if (vres) {
+ tmp = vres->allocated;
+ vres->allocated = vres->new;
+ if (tmp) fres_contract_destroy(tmp);
+ }
+ }
+
+ ret = 0;
+
+err_free_vreses:
+ free(vreses);
+err:
+ return ret;
+}
+
+static const struct forb_fres_resource_allocator_impl fra_impl = {
+ .change_vreses = change_vreses,
+};
+
+
+/**
+ * Creates allocator object and registeres it with the given executor.
+ *
+ * @param orb
+ * @param executor
+ * @param allocator
+ *
+ * @return Object reference on success or NULL on error.
+ */
+fres_resource_allocator fra_new(forb_orb orb,
+ forb_executor_t *executor,
+ struct fres_allocator *allocator)
+{
+ int ret;
+ fres_resource_allocator fra;
+
+ fra = forb_fres_resource_allocator_new(orb, &fra_impl, allocator);
+ if (!fra) {
+ save_errno(ul_logerr("forb_fres_resource_manager_new error"));
+ goto err;
+ }
+
+ /* Prepare executor before we register the resource allocator
+ * with contract broker */
+ ret = forb_executor_register_object(executor, fra);
+ if (ret) goto err_release;
+
+ return fra;
+err_release:
+ save_errno(forb_object_release(fra));
+err:
+ return NULL;
+}
+
+/**
+ * Returns pointer to VRes, which corresponds to the contract with the
+ * given id.
+ *
+ * @param id
+ *
+ * @return Pointer to VRes, or NULL in the VRes doesn't exist.
+ */
+fres_vres_t *fra_get_vres(fres_contract_id_t *id)
+{
+ return fres_vreses_find(id);
+}
+
+static inline
+int fres_threads_vres_insert(struct fres_thread_vres *tv)
+{
+ int ret;
+
+ fosa_mutex_lock(&fres_threads_vres.mutex);
+ ret = fres_threads_vres_nolock_insert(&fres_threads_vres, tv);
+ fosa_mutex_unlock(&fres_threads_vres.mutex);
+
+ return ret;
+}
+
+static inline
+int fres_threads_vres_delete(struct fres_thread_vres *tv)
+{
+ int ret;
+
+ fosa_mutex_lock(&fres_threads_vres.mutex);
+ ret = fres_threads_vres_nolock_delete(&fres_threads_vres, tv);
+ fosa_mutex_unlock(&fres_threads_vres.mutex);
+
+ return ret;
+}
+
+static inline
+struct fres_thread_vres *fres_threads_vres_find(const fres_thread_vres_key_t *key)
+{
+ struct fres_thread_vres *ret;
+
+ fosa_mutex_lock(&fres_threads_vres.mutex);
+ ret = fres_threads_vres_nolock_find(&fres_threads_vres, key);
+ fosa_mutex_unlock(&fres_threads_vres.mutex);
+
+ return ret;
+}
+
+/**
+ * Creates binding from a thread to VRES of specified type;
+ * if binding already exists, it fails... The old one should be
+ * deleted first.
+ *
+ * @param id Thread ID bounded to @a vres of type @vres_type.
+ * @param vres VRES
+ *
+ * @return Positive number when a new binding was inserted, zero when
+ * binding was changed and -1 on error.
+ */
+int fra_insert_thread_vres(const fosa_thread_id_t *id,
+ int vres_type,
+ fres_vres_t *vres)
+{
+ fres_thread_vres_key_t key;
+ struct fres_thread_vres *tv;
+
+ key.thread_id = *id;
+ key.vres_type = vres_type;
+
+ tv = fres_threads_vres_find(&key);
+ if (tv) return -1;
+
+ tv = fres_thread_vres_new(id, vres_type, vres);
+ if (!tv) return -1;
+
+ return !fres_threads_vres_insert(tv);
+}
+
+/**
+ * Deletes thread to VRES binding.
+ *
+ * @param id Thread ID to unbind.
+ *
+ * @return Zero on success, -1 on when the thread was not bound.
+ */
+int fra_delete_thread_vres(const fosa_thread_id_t *id, int vres_type)
+{
+ struct fres_thread_vres *tv;
+ fres_thread_vres_key_t key;
+ int ret;
+
+ key.thread_id = *id;
+ key.vres_type = vres_type;
+
+ fosa_mutex_lock(&fres_threads_vres.mutex);
+ tv = fres_threads_vres_nolock_find(&fres_threads_vres, &key);
+ if (!tv) {
+ ret = -1;
+ goto retr;
+ }
+
+ ret = fres_threads_vres_nolock_delete(&fres_threads_vres, tv);
+ fosa_mutex_unlock(&fres_threads_vres.mutex);
+ if (ret) goto retr;
+
+ ret = !fres_threads_vres_delete(tv);
+
+retr:
+ return ret;
+}
+
+/**
+ * Returns VRES bounded to a thread.
+ *
+ * @param id Thread ID
+ *
+ * @return VRES on NULL in the thread is not bound.
+ *
+ * @todo Is this function needed if we have
+ * fra_get_vres_thread_vres()?
+ */
+fres_thread_vres_t *fra_get_thread_vres
+ (const fosa_thread_id_t *id,
+ int vres_type)
+{
+ fres_thread_vres_key_t key;
+
+ key.thread_id = *id;
+ key.vres_type = vres_type;
+
+ return fres_threads_vres_find(&key);
+}
+
+/**
+ * Returns VRES bounded to a thread.
+ *
+ * @param id Thread ID
+ *
+ * @return VRES on NULL in the thread is not bound.
+ */
+fres_vres_t *fra_get_vres_thread_vres
+ (const fosa_thread_id_t *id,
+ int vres_type)
+{
+ fres_thread_vres_key_t key;
+ fres_thread_vres_t *tv;
+
+ key.thread_id = *id;
+ key.vres_type = vres_type;
+
+ tv = fres_threads_vres_find(&key);
+ if (!tv) return NULL;
+
+ return tv->vres;
+}
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file fra_generic.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Mon Nov 3 15:32:54 2008
+ *
+ * @brief FORB interface of FRES Resource Allocator
+ *
+ *
+ */
+#ifndef FRA_GENERIC_H
+#define FRA_GENERIC_H
+#include <fcb.h>
+#include <fra.h>
+#include <fres_contract.h>
+#include <ul_gavlcust.h>
+#include <fosa.h>
+#include <forb/executor.h>
+#include <fres_contract_idl.h>
+#include <fres_vres.h>
+
+/** Registry of all virtual resources in an application. */
+struct fres_vreses {
+ fosa_mutex_t mutex; /**< Mutex for manipulation with vreses tree. If all allocators are executed from one executor, locking can be avoided. */
+ gavl_cust_root_field_t vreses; /**< Container of all virtual resources */
+};
+
+GAVL_CUST_NODE_INT_DEC(fres_vreses_nolock /* cust_prefix */,
+ struct fres_vreses /* cust_root_t */,
+ struct fres_vres /* cust_item_t */,
+ fres_contract_id_t /* cust_key_t */,
+ vreses /* cust_root_node */,
+ node /* cust_item_node */,
+ id /* cust_item_key */,
+ fres_contract_id_cmp /* cust_cmp_fnc */)
+
+extern struct fres_vreses fres_vreses;
+
+struct fres_vres *
+fres_vreses_find_label(fres_block_label *label, fres_block_resource *res);
+
+/** Registry of all threads in an application that are bound to a VRES. */
+struct fres_threads_vres {
+ fosa_mutex_t mutex; /**< Mutex for manipulation with vreses tree. If all allocators are executed from one executor, locking can be avoided. */
+ gavl_cust_root_field_t threads; /**< Container of all virtual resources */
+};
+
+GAVL_CUST_NODE_INT_DEC(fres_threads_vres_nolock /* cust_prefix */,
+ struct fres_threads_vres /* cust_root_t */,
+ struct fres_thread_vres /* cust_item_t */,
+ fres_thread_vres_key_t /* cust_key_t */,
+ threads /* cust_root_node */,
+ node /* cust_item_node */,
+ thread_vres /* cust_item_key */,
+ fres_thread_vres_cmp /* cust_cmp_fnc */)
+
+extern struct fres_threads_vres fres_threads_vres;
+
+
+/**
+ * Structure describing FRES allocator. It is used as a parameter to
+ * fra_register(), which registeres this allocator with contract
+ * broker and provides FORB interface to the real allocator.
+ *
+ */
+struct fres_allocator {
+ frsh_resource_type_t res_type; /**< Resource type */
+ frsh_resource_id_t res_id; /**< Resource ID */
+ /** @name Simple interface
+ * The allocator cannot influence the order of applying changes. */
+ /*@{*/
+ /**
+ * Should create the VRES according to the parameters in
+ * fres_vres::new.
+ *
+ * @param vres VRES to create.
+ * @param priv User supplied pointer registered by fra_register()
+ *
+ * @return Zero in case of success, nonzero error code on error.
+ */
+ int (*create_vres)(fres_vres_t *vres, void *priv);
+ /**
+ * Should change the already crated VRES according to the
+ * parameters in fres_vres::new. The currenlty allocated
+ * parameters are in fres_vres::allocated. This function
+ * should change the fres_vres::perceived to @a fres_vres::new
+ * at some point in time (depending on the kind of the change).
+ * The fres_vres::allocated parameters will be freed after
+ * the return of this function and then fres_vres::allocated
+ * will be set to fres_vres::new.
+ *
+ * @param vres VRES to change.
+ * @param priv User supplied pointer registered by fra_register()
+ *
+ * @return Zero in case of success, nonzero error code on error.
+ */
+ int (*change_vres)(fres_vres_t *vres, void *priv);
+ /**
+ * Cancel the CRES
+ *
+ * @param cancel_vres VRES to cancel
+ *
+ * @return Zero on succaess, non-zero error code on error.
+ */
+ int (*cancel_vres)(fres_vres_t *vres, void *priv);
+ /*@}*/
+
+ /** @name Full interface
+ *
+ * Full interface provides a way for the allocator to
+ * influence the order of applying changes.
+ */
+ /*@{*/
+ /**
+ * A more general (and more compilcated) allocator
+ * interface. If this field is non-NULL, the simple interface
+ * is not used.
+ *
+ * The advantage of this method is that it can apply the
+ * changes in whatever order and even in parallel. The new
+ * version of VRES parameters is stored in fres_vres::new,
+ * whereas the previous version (if any) is stored in
+ * fres_vres::allocated. This function should change the
+ * fres_vres::perceived to @a fres_vres::new at some point in
+ * time (depending on the kind of the change) as the
+ * fres_vres::allocated parameters will be freed after the
+ * return of this function. When the fres_vres::new contains
+ * no blocks, the VRES should be canceled.
+ *
+ * @param vreses Array of pointers to VRESes.
+ * @param length The number of elements in @a vreses.
+ * @param priv Value of @a priv field in this structure.
+ *
+ * @return Zero in case of success, non-zero error code otherwise.
+ */
+ int (*apply_vres_changes)(fres_vres_t *vreses[], unsigned length, void *priv);
+ /*@}*/
+
+ /** @name Feedback module support */
+ /*@{*/
+ int (*set_spare_bandwidth)(fres_vres_t *vres);
+ int (*get_desired_budget)(fres_vres_t *vres, frsh_rel_time_t *p_budget_out);
+ int (*set_desired_budget)(fres_vres_t *vres_id, frsh_rel_time_t *p_budget_in);
+ int (*get_actual_budget)(fres_vres_t *vres_id, frsh_rel_time_t *budget);
+ /*@}*/
+
+ int (*bind_thread)(fres_vres_t *vres, fosa_thread_id_t thread);
+ int (*unbind_thread)(fosa_thread_id_t thread);
+
+ int (*vres_get_job_usage)(const fres_vres_t *vres, frsh_rel_time_t *spent);
+ int (*vres_get_remaining_budget)(const fres_vres_t *vres, frsh_rel_time_t *budget);
+ int (*vres_get_usage)(const fres_vres_t *vres, frsh_rel_time_t *spent);
+
+ void *priv; /**< Pointer to allocator's private data */
+
+ /**
+ * A callback called whenever the resource allocator is to be
+ * activated by fra_activate().
+ */
+ int (*activate_callback)(forb_orb orb);
+};
+
+fres_resource_allocator fra_new(forb_orb orb,
+ forb_executor_t *executor,
+ struct fres_allocator *allocator);
+
+int fra_registry_init(forb_orb orb,
+ fres_contract_broker fcb,
+ forb_executor_t *executor);
+int fra_register(struct fres_allocator *allocator);
+int fra_activate(frsh_resource_type_t res_type,
+ frsh_resource_id_t res_id);
+struct fres_allocator *fra_get(frsh_resource_type_t res_type,
+ frsh_resource_id_t res_id);
+
+fres_vres_t *fra_get_vres(fres_contract_id_t *id);
+
+int fra_insert_thread_vres(const fosa_thread_id_t *id,
+ int vres_type,
+ fres_vres_t *vres);
+int fra_delete_thread_vres(const fosa_thread_id_t *id,
+ int vres_type);
+fres_thread_vres_t *fra_get_thread_vres(const fosa_thread_id_t *id,
+ int vres_type);
+fres_vres_t *fra_get_vres_thread_vres(const fosa_thread_id_t *id,
+ int vres_type);
+
+#endif
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file fra_registry.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Thu Oct 23 15:26:19 2008
+ *
+ * @brief Registry of FRES Resource Allocator.
+ *
+ * This registry is used by fra_register() and its main purpose is to
+ * allow "late" registration of allocators to FCB. Late registration
+ * means, that the allocator is registered with FCB only when the
+ * application accesses the resource.
+ *
+ * This functionality is useful at least during testing and debugging,
+ * when it is not necessary to run all the resource managers. Only the
+ * managers for resources used by the application are required.
+ */
+#include <forb.h>
+#include <fra.h>
+#include <fcb.h>
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <ul_gavlcust.h>
+#include "fra_generic.h"
+#include <stdbool.h>
+
+UL_LOG_CUST(ulogd_fra_registry);
+ul_log_domain_t ulogd_fra_registry = {UL_LOGL_MSG, "fra_registry"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(fra_registry_logreg_domains, ulogd_fra_registry);
+
+#define save_errno(cmd) do { int _e = errno; cmd; errno = _e; } while(0)
+
+struct registered_allocator {
+ gavl_node_t node;
+ struct fres_allocator *allocator;
+ bool registered_with_fcb;
+};
+
+#define FRA_MAX_ALLOCATORS 32
+static struct registered_allocator allocators[FRA_MAX_ALLOCATORS];
+static unsigned free_allocator_idx = 0;
+
+static struct registry {
+ forb_orb orb;
+ fres_contract_broker fcb;
+ forb_executor_t *executor;
+
+ pthread_mutex_t mutex;
+ gavl_cust_root_field_t allocators;
+} registry;
+
+
+static inline int fres_allocator_cmp(struct fres_allocator * const *a,
+ struct fres_allocator * const *b)
+{
+ if ((*a)->res_type < (*b)->res_type) {
+ return -1;
+ } else if ((*a)->res_type > (*b)->res_type) {
+ return +1;
+ } else if ((*a)->res_id < (*b)->res_id) {
+ return -1;
+ } else if ((*a)->res_id > (*b)->res_id) {
+ return +1;
+ } else {
+ return 0;
+ }
+}
+
+GAVL_CUST_NODE_INT_DEC(fra_registry /* cust_prefix */,
+ struct registry /* cust_root_t */,
+ struct registered_allocator /* cust_item_t */,
+ struct fres_allocator* /* cust_key_t */,
+ allocators /* cust_root_node */,
+ node /* cust_item_node */,
+ allocator /* cust_item_key */,
+ fres_allocator_cmp /* cust_cmp_fnc */);
+
+GAVL_CUST_NODE_INT_IMP(fra_registry /* cust_prefix */,
+ struct registry /* cust_root_t */,
+ struct registered_allocator /* cust_item_t */,
+ struct fres_allocator* /* cust_key_t */,
+ allocators /* cust_root_node */,
+ node /* cust_item_node */,
+ allocator /* cust_item_key */,
+ fres_allocator_cmp /* cust_cmp_fnc */);
+
+
+/**
+ * Initializes registry of resource allocators.
+ *
+ * @param orb
+ * @param fcb Contract broker object reference
+ * @param executor Executor for all allocator objects
+ *
+ * @return Zero on success, error number on error.
+ */
+int fra_registry_init(forb_orb orb,
+ fres_contract_broker fcb,
+ forb_executor_t *executor)
+{
+ int rv;
+ registry.orb = orb;
+ registry.fcb = fcb;
+ registry.executor = executor;
+
+ pthread_mutexattr_t ma;
+ rv = pthread_mutexattr_init(&ma);
+ rv = pthread_mutexattr_setprotocol(&ma, PTHREAD_PRIO_INHERIT);
+ if (rv) return rv;
+ pthread_mutex_init(®istry.mutex, &ma);
+ fra_registry_init_root_field(®istry);
+ return 0;
+}
+
+/**
+ * Registeres the allocator in registry.
+ *
+ * @param allocator
+ *
+ * @return Zero on success, -1 on error.
+ */
+int fra_register(struct fres_allocator *allocator)
+{
+ struct registered_allocator *ra;
+ int ret;
+ pthread_mutex_lock(®istry.mutex);
+ ra = fra_registry_find(®istry, &allocator);
+ if (!ra && free_allocator_idx < FRA_MAX_ALLOCATORS) {
+ ra = &allocators[free_allocator_idx];
+ free_allocator_idx++;
+ ra->allocator = allocator;
+ ra->registered_with_fcb = false;
+ fra_registry_insert(®istry, ra);
+ ret = 0;
+ } else {
+ ret = -1;
+ }
+ pthread_mutex_unlock(®istry.mutex);
+ return ret;
+}
+
+/**
+ * Creates FORB object reference for the allocator and registeres it
+ * with contract broker.
+ *
+ * @param allocator
+ *
+ * @return Zero on success, non-zero error code on error.
+ */
+static int register_fra_to_fcb(struct fres_allocator *allocator)
+{
+ int ret;
+ struct forb_env env;
+ fres_resource_allocator fra;
+
+ fra = fra_new(registry.orb, registry.executor, allocator);
+
+ if (allocator->activate_callback) {
+ ret = allocator->activate_callback(registry.orb);
+ if (ret) goto err_release;
+ }
+ /* Register resource allocator */
+ ret = fres_contract_broker_register_allocator(registry.fcb,
+ allocator->res_type,
+ allocator->res_id,
+ fra, &env);
+ if (forb_exception_occurred(&env)) {
+ ret = fres_forbex2err(&env);
+ goto err_release;
+ }
+ if (ret)
+ goto err_release;
+ return 0;
+err_release:
+ save_errno(forb_object_release(fra));
+ return ret;
+}
+
+/**
+ * Creates the allocator object and registeres it with contract
+ * broker. The allocator must be previously registered by
+ * fra_register(). If the allocator is already registered, this
+ * function does nothing.
+ *
+ * @param res_type
+ * @param res_id
+ *
+ * @return Zero on success, non-zero error code on error.
+ */
+
+int fra_activate(frsh_resource_type_t res_type,
+ frsh_resource_id_t res_id)
+{
+ struct fres_allocator key, *pkey=&key;
+ struct registered_allocator *ra;
+ int ret;
+
+ key.res_type = res_type;
+ key.res_id = res_id;
+ pthread_mutex_lock(®istry.mutex);
+ ra = fra_registry_find(®istry, &pkey);
+ if (ra) {
+ if (ra->registered_with_fcb) {
+ ret = 0;
+ } else {
+ ret = register_fra_to_fcb(ra->allocator);
+ if (ret == 0) {
+ ra->registered_with_fcb = true;
+ }
+ }
+ } else {
+ ret = FRES_ERR_NO_RESOURCE_ALLOCATOR;
+ }
+ pthread_mutex_unlock(®istry.mutex);
+
+ return ret;
+}
+
+/**
+ * Returns allocator for a given resource, previously registered by
+ * fra_register().
+ *
+ * @param res_type
+ * @param res_id
+ *
+ * @return Pointer to the resource allocator or NULL if no allocator
+ * is registered for the resource.
+ */
+struct fres_allocator *fra_get(frsh_resource_type_t res_type,
+ frsh_resource_id_t res_id)
+{
+ struct registered_allocator *ra;
+ struct fres_allocator key, *pkey=&key;
+
+ pkey->res_type = res_type;
+ pkey->res_id = res_id;
+
+ pthread_mutex_lock(®istry.mutex);
+ ra = fra_registry_find(®istry, &pkey);
+ pthread_mutex_unlock(®istry.mutex);
+ if (ra) {
+ return ra->allocator;
+ } else {
+ return NULL;
+ }
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file fres_vres.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Wed Feb 18 16:00:53 2009
+ *
+ * @brief VRES implementation
+ *
+ *
+ */
+
+
+#include "fres_vres.h"
+#include <string.h>
+#include <fres_contract.h>
+
+/**
+ * Allocates new vres structure.
+ *
+ * @return Pointer to the new vres or NULL in case of error.
+ */
+fres_vres_t *fres_vres_new(fres_contract_id_t *id)
+{
+ fres_vres_t *vres;
+
+ vres = malloc(sizeof(*vres));
+ if (!vres) goto err;
+
+ memset(vres, 0, sizeof(*vres));
+ vres->id = *id;
+err:
+ return vres;
+}
+
+/**
+ * Deallocates vres structure and contract(s) associated with it.
+ *
+ * @param vres Vres to deallocate
+ */
+void fres_vres_destroy(fres_vres_t *vres)
+{
+ if (!vres) return;
+
+ if (vres->allocated ) {
+ fres_contract_destroy(vres->allocated);
+ }
+ if (vres->perceived && vres->perceived != vres->allocated) {
+ fres_contract_destroy(vres->perceived);
+ }
+ if (vres->new && vres->new != vres->allocated
+ && vres->new != vres->perceived) {
+ fres_contract_destroy(vres->new);
+ }
+ free(vres);
+}
+
+fres_thread_vres_t *fres_thread_vres_new
+ (const fosa_thread_id_t *id,
+ int vres_type,
+ fres_vres_t *vres)
+{
+ fres_thread_vres_t *tv;
+
+ tv = malloc(sizeof(*tv));
+ if (!tv) goto out;
+
+ memset(tv, 0, sizeof(*tv));
+ tv->thread_vres.thread_id = *id;
+ tv->thread_vres.vres_type = vres_type;
+ tv->vres = vres;
+
+out:
+ return tv;
+}
+
+void fres_thread_vres_destroy(fres_thread_vres_t *tv)
+{
+ if (!tv) return;
+
+ free(tv);
+}
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file fres_vres.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * Dario Faggioli <faggioli@gandalf.sssup.it>
+ * @date Wed Feb 18 16:00:15 2009
+ *
+ * @brief VRES definition
+ *
+ *
+ */
+
+#ifndef FRES_VRES_H
+#define FRES_VRES_H
+
+#include <fosa.h>
+
+#include <fres_contract_idl.h>
+#include <ul_gavlcust.h>
+
+struct fres_allocator;
+
+/** Description of VRES (virtual resource) */
+typedef struct fres_vres {
+ /** Contracts IDs of this VRES. */
+ fres_contract_id_t id;
+
+ /**
+ * Stores actual allocation of the resource. During a mode
+ * change, the callbacks can compare this old allocation with
+ * the changed one (stored in @a new) and depending on the
+ * kind of difference, they can apply the change
+ * differently. Callbacks must not change this field.
+ */
+ struct fres_contract *allocated;
+
+ /**
+ * Perceived allocation as seen by application (used during
+ * during mode change). Callback functions must set this value
+ * because FRSH functions such as
+ * frsh_vres_get_budget_and_period() use it to inform the
+ * application about current allocation.
+ *
+ * @todo We need reference counting here.
+ */
+ struct fres_contract *perceived;
+
+ /**
+ * The schedulable contract received by the allocator. The
+ * allocator callbacks should use this contract to
+ * create/change VRES and must not change the value of this
+ * field.
+ */
+ struct fres_contract *new;
+
+ struct fres_allocator *allocator;
+ void *priv; /**< Resource allocator private data */
+ gavl_node_t node;
+} fres_vres_t;
+
+fres_vres_t *fres_vres_new(fres_contract_id_t *id);
+void fres_vres_destroy(fres_vres_t *vres);
+
+/**
+ * Representation of thread to VRES binding.
+ */
+typedef struct fres_thread_vres_key {
+ fosa_thread_id_t thread_id;
+ int vres_type;
+} fres_thread_vres_key_t;
+
+typedef struct fres_thread_vres {
+ struct fres_thread_vres_key thread_vres;
+ fres_vres_t *vres;
+
+ fosa_abs_time_t job_start_time;
+ fosa_abs_time_t job_cpu_time;
+
+ gavl_node_t node;
+} fres_thread_vres_t;
+
+static inline
+int fres_thread_vres_cmp
+ (const fres_thread_vres_key_t *a,
+ const fres_thread_vres_key_t *b)
+{
+ /*
+ * TODO:
+ * Make this a little bit less specific!
+ */
+ if (a->thread_id.linux_tid < a->thread_id.linux_tid)
+ return -1;
+ else if (a->thread_id.linux_tid > a->thread_id.linux_tid)
+ return +1;
+ else if (a->vres_type < b->vres_type)
+ return -1;
+ else if (a->vres_type > b->vres_type)
+ return +1;
+
+ return 0;
+}
+
+fres_thread_vres_t *fres_thread_vres_new(const fosa_thread_id_t *id,
+ int vres_type,
+ fres_vres_t *vres);
+
+void fres_thread_vres_destroy(fres_thread_vres_t *tv);
+
+#endif
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+shared_LIBRARIES = frm
+frm_SOURCES = fres_sa_scenario.c frm_generic.c
+frm_SERVER_IDL = frm.idl
+
+include_HEADERS += frm_generic.h fres_sa_scenario.h
+include_GEN_HEADERS += frm.h
+
+lib_LIBRARIES += frm_client
+frm_client_CLIENT_IDL = frm.idl
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file fres_sa_scenario.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Tue Nov 11 08:37:55 2008
+ *
+ * @brief Schedulability analysis data structures
+ *
+ *
+ */
+#include "fres_sa_scenario.h"
+
+/**
+ * Allocates memory for a new ::fres_sa_contract.
+ *
+ *
+ * @return Pointer to the allocated ::fres_sa_contract or NULL in case
+ * of error.
+ */
+struct fres_sa_contract *
+fres_sa_contract_new(void)
+{
+ struct fres_sa_contract *c;
+
+ c = malloc(sizeof(*c));
+ if (!c) goto err;
+
+ memset(c, 0, sizeof(*c));
+ return c;
+err:
+ return NULL;
+}
+
+/**
+ * Dellocates the memory of ::fres_sa_contract and all contracts
+ * (::fres_contract) associated with it.
+ *
+ * @param c SA contract to deallocate.
+ */
+void
+fres_sa_contract_destroy(struct fres_sa_contract *c)
+{
+ if (c) {
+ if (c->committed) {
+ fres_contract_destroy(c->committed);
+ }
+ if (c->reserved && c->reserved != c->committed) {
+ fres_contract_destroy(c->reserved);
+ }
+ if (c->new && c->new != c->committed
+ && c->new != c->reserved) {
+ fres_contract_destroy(c->new);
+ }
+ free(c->priv);
+ free(c);
+ }
+}
+
+/**
+ * Duplicates SA contract. It doesn't duplicate @a priv field.
+ *
+ * @param src
+ *
+ * @return Duplicate or NULL in case of error.
+ */
+struct fres_sa_contract *
+fres_sa_contract_duplicate(const struct fres_sa_contract *src)
+{
+ struct fres_sa_contract *dst;
+
+ dst = fres_sa_contract_new();
+ if (!dst) goto err;
+
+ dst->committed = fres_contract_duplicate(src->committed);
+ dst->reserved = fres_contract_duplicate(src->reserved);
+ dst->new = fres_contract_duplicate(src->new);
+
+ /* TODO: How about duplication of src->priv? */
+
+ return dst;
+err:
+ return NULL;
+}
+
+
+GAVL_CUST_NODE_INT_IMP(fres_sa_scenario_contract /* cust_prefix */,
+ struct fres_sa_scenario /* cust_root_t */,
+ struct fres_sa_contract /* cust_item_t */,
+ fres_contract_id_t /* cust_key_t */,
+ contracts /* cust_root_node */,
+ node /* cust_item_node */,
+ id /* cust_item_key */,
+ fres_contract_id_cmp /* cust_cmp_fnc */);
+
+struct fres_sa_scenario *
+fres_sa_scenario_new(void)
+{
+ struct fres_sa_scenario *s;
+
+ s = malloc(sizeof(*s));
+ if (!s) return NULL;
+
+ memset(s, 0, sizeof(*s));
+ s->utilization = -1;
+
+ return s;
+}
+
+void fres_sa_scenario_destroy(struct fres_sa_scenario *scenario)
+{
+ struct fres_sa_contract *c;
+ if (!scenario) return;
+ fres_sa_scenario_for_each_contract(scenario, c) {
+ fres_sa_contract_destroy(c);
+ }
+ free(scenario);
+}
+
+/**
+ * Duplicates the scenario and all contracts it contains. Priv
+ * pointers are not duplicated.
+ *
+ * @param src
+ *
+ * @return
+ */
+struct fres_sa_scenario *
+fres_sa_scenario_duplicate(const struct fres_sa_scenario *src)
+{
+ struct fres_sa_scenario *dst;
+ struct fres_sa_contract *c1, *c2;
+
+ if (!src) goto err;
+ dst = fres_sa_scenario_new();
+ if (!dst) goto err;
+
+ dst->num_contracts = src->num_contracts;
+ dst->utilization = src->utilization;
+ gavl_cust_for_each(fres_sa_scenario_contract,
+ src, c1) {
+ c2 = fres_sa_contract_duplicate(c1);
+ if (!c2) goto free_err;
+ fres_sa_scenario_contract_insert(dst, c2);
+ }
+
+ return dst;
+free_err:
+ fres_sa_scenario_destroy(dst);
+err:
+ return NULL;
+}
+
+/**
+ * Adds the contract to the scenario.
+ *
+ * @param scenario
+ * @param contract
+ *
+ * @return Zero.
+ */
+int fres_sa_scenario_add_contract(struct fres_sa_scenario *scenario,
+ struct fres_sa_contract *contract)
+{
+ fres_sa_scenario_contract_insert(scenario, contract);
+ scenario->num_contracts ++;
+
+ return 0;
+
+}
+
+/**
+ * Deletes the contract from the scenario.
+ *
+ * @param scenario
+ * @param c
+ *
+ * @return One, if the contract was deleted, zero if not.
+ */
+int fres_sa_scenario_del_contract(struct fres_sa_scenario *scenario,
+ struct fres_sa_contract *c)
+{
+ if (scenario && c) {
+ scenario->num_contracts--;
+ fres_sa_scenario_contract_delete(scenario, c);
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * Finds the contract with the given ID in the scenario.
+ *
+ * @param scenario
+ * @param id
+ *
+ * @return The found contract of NULL if the contract was not found.
+ */
+struct fres_sa_contract *
+fres_sa_scenario_find_contract(const struct fres_sa_scenario *scenario,
+ fres_contract_id_t *id)
+{
+ return fres_sa_scenario_contract_find(scenario, id);
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file fres_sa_scenario.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Tue Nov 11 08:37:29 2008
+ *
+ * @brief Schedulability analysis data structures declarations.
+ *
+ *
+ */
+#ifndef FRES_SA_SCENARIO_H
+#define FRES_SA_SCENARIO_H
+
+#include <fres_contract.h>
+#include <ul_gavlcust.h>
+
+/**
+ * Represenation of a contract in a scenario.
+ *
+ */
+struct fres_sa_contract {
+ fres_contract_id_t id; /**< ID of all contract versions stored here. */
+
+ /** If the contract was already committed, the committed version
+ * is stored here. The contract is moved here from @a reserved
+ * field in fres_resource_manager::commit_contracts(). */
+ struct fres_contract *committed;
+
+ /** The reserved (and not yet committed) version of the
+ * contract. If a new contract is to be negotiated or an old
+ * one is to be changed, the new version is stored here after
+ * successful admission test. */
+ struct fres_contract *reserved;
+
+ /** If a new contract is to be negotiated it is stored
+ * here. After sucessfull admission test, the contract is
+ * moved to @a reserved field. If the contract is to be
+ * changed, the admission test can compare the committed and
+ * new version and analyze not only the target state but also
+ * the mode change. */
+ struct fres_contract *new;
+
+ /** Convenience pointer, which has the same value as one of @a
+ * new, @a reserved and @a committed. It is meant for simpler
+ * admission tests, which do not evaluate mode changes and
+ * therefore have no need for comparison of committed and new
+ * version of contact. */
+ struct fres_contract *contract;
+
+
+ void *priv; /**< Private data for use by admission test */
+ gavl_node_t node;
+};
+
+/**
+ * Scenario for schedulability analysis.
+ *
+ * Basically it represents a set of contracts.
+ *
+ * @warning Do not manipulate the tree direcly through this macros,
+ * instead use fres_sa_scenario_add_contract(),
+ * fres_sa_scenario_del_contract() and
+ * fres_sa_scenario_find_contract().
+ */
+
+struct fres_sa_scenario {
+ gavl_cust_root_field_t contracts; /**< GAVL tree of contracts. */
+ unsigned num_contracts; /**< The number if contracts in scenario */
+ int utilization; /**< Utilization (0-100) used by GUI */
+ void *priv;
+};
+
+GAVL_CUST_NODE_INT_DEC(fres_sa_scenario_contract /* cust_prefix */,
+ struct fres_sa_scenario /* cust_root_t */,
+ struct fres_sa_contract /* cust_item_t */,
+ fres_contract_id_t /* cust_key_t */,
+ contracts /* cust_root_node */,
+ node /* cust_item_node */,
+ id /* cust_item_key */,
+ fres_contract_id_cmp /* cust_cmp_fnc */);
+
+
+static inline struct fres_sa_contract *
+fres_sa_scenario_contract_next_non_cancelation(struct fres_sa_scenario *scenario,
+ struct fres_sa_contract *contract)
+{
+ do {
+ if (!contract)
+ contract = fres_sa_scenario_contract_first(scenario);
+ else
+ contract = fres_sa_scenario_contract_next(scenario, contract);
+ } while (contract && (fres_contract_get_num_blocks(contract->contract) == 0));
+ return contract;
+}
+
+/**
+ * Expands to for-cycle for traversing all contracts in a scenario,
+ * which are not going to be canceled. The actual contract is stored
+ * in @a contract variable.
+ *
+ */
+#define fres_sa_scenario_for_each_no_cancel_contract(scenario, contract) \
+ for((contract) = fres_sa_scenario_contract_next_non_cancelation((scenario), NULL); \
+ contract; \
+ (contract) = fres_sa_scenario_contract_next_non_cancelation((scenario), (contract)))
+
+/**
+ * Expands to for-cycle for traversing all contracts in a
+ * scenario. The actual contract is stored in @a contract variable.
+ *
+ */
+#define fres_sa_scenario_for_each_contract(scenario, contract) \
+ gavl_cust_for_each(fres_sa_scenario_contract, scenario, contract)
+
+struct fres_sa_contract *
+fres_sa_contract_new(void);
+
+void
+fres_sa_contract_destroy(struct fres_sa_contract *sa_contract);
+
+struct fres_sa_contract *
+fres_sa_contract_duplicate(const struct fres_sa_contract *sa_contract);
+
+struct fres_sa_scenario *
+fres_sa_scenario_new(void);
+
+void fres_sa_scenario_destroy(struct fres_sa_scenario *scenario);
+
+struct fres_sa_scenario *
+fres_sa_scenario_duplicate(const struct fres_sa_scenario *scenario);
+
+int fres_sa_scenario_add_contract(struct fres_sa_scenario *scenario,
+ struct fres_sa_contract *contract);
+
+int fres_sa_scenario_del_contract(struct fres_sa_scenario *scenario,
+ struct fres_sa_contract *contract);
+
+struct fres_sa_contract *
+fres_sa_scenario_find_contract(const struct fres_sa_scenario *scenario,
+ fres_contract_id_t *id);
+
+#endif
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------------------- //
+// Copyright (C) 2006 - 2008 FRESCOR consortium partners: //
+// //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// Scuola Superiore Sant'Anna, ITALY //
+// Kaiserslautern University, GERMANY //
+// Univ. Politécnica Valencia, SPAIN //
+// Czech Technical University in Prague, CZECH REPUBLIC //
+// ENEA SWEDEN //
+// Thales Communication S.A. FRANCE //
+// Visual Tools S.A. SPAIN //
+// Rapita Systems Ltd UK //
+// Evidence ITALY //
+// //
+// See http://www.frescor.org for a link to partners' websites //
+// //
+// FRESCOR project (FP6/2005/IST/5-034026) is funded //
+// in part by the European Union Sixth Framework Programme //
+// The European Union is not liable of any use that may be //
+// made of this code. //
+// //
+// //
+// based on previous work (FSF) done in the FIRST project //
+// //
+// Copyright (C) 2005 Mälardalen University, SWEDEN //
+// Scuola Superiore S.Anna, ITALY //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// //
+// FSF API web pages: http:marte.unican.es/fsf/docs //
+// http:shark.sssup.it/contrib/first/docs/ //
+// //
+// This file is part of FORB (Frescor Object Request Broker) //
+// //
+// FORB is free software; you can redistribute it and/or modify it //
+// under terms of the GNU General Public License as published by the //
+// Free Software Foundation; either version 2, or (at your option) any //
+// later version. FORB is distributed in the hope that it will be //
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty //
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
+// General Public License for more details. You should have received a //
+// copy of the GNU General Public License along with FORB; see file //
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, //
+// Cambridge, MA 02139, USA. //
+// //
+// As a special exception, including FORB header files in a file, //
+// instantiating FORB generics or templates, or linking other files //
+// with FORB objects to produce an executable application, does not //
+// by itself cause the resulting executable application to be covered //
+// by the GNU General Public License. This exception does not //
+// however invalidate any other reasons why the executable file might be //
+// covered by the GNU Public License. //
+////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @file frm.idl
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Sat Oct 25 21:57:56 2008
+ *
+ * @brief FORB interface of resource manager
+ *
+ *
+ */
+#ifndef _FRM_IDL
+#define _FRM_IDL
+
+#include "../contract/fres_contract_idl.idl"
+
+/// FRES framework
+module fres {
+ /** Resource manager */
+ interface resource_manager {
+ /**
+ * Executes admission test and if the contracts are
+ * accepted, they are put to "reserved" state.
+ *
+ * @todo If a contract is in the "reserved" state, and
+ * reserve_contracts() is called again with the same
+ * contract, the previously reserved contract should
+ * be replaced with the new one.
+ *
+ * @param[in] contracts Contract(s) to negotiate,
+ * renegotiate or cancel. The operation on the
+ * contract is determined as follows:
+ * - cancel: contracts with an ID and without any block
+ *
+ * - neg: contracts with ID not present in current
+ * schedulability scenario.
+ *
+ * - reneg: contracts with ID present in current
+ * schedulability scenario.
+ *
+ * @return
+ * - Zero if reservation (admisson test) was successfull,
+ * - one if admission test was not successfull and
+ * - negative error code if an error occured.
+ */
+ long reserve_contracts(in contract::ptr_seq contracts);
+
+ /**
+ * Puts contracts with given IDs to the "commited"
+ * state and sends back the changes to VRESes to reach
+ * the new state.
+ *
+ * @param[in] ids IDs of contracts to be commited.
+ *
+ * @param[out] schedulable_contracts Schedulable
+ * contracts, for new or changed VRESes. These
+ * contract may be extened by one or more data blocks
+ * for use by the allocator. The allocator receives
+ * the contracts in the same order as they are
+ * returned.
+ */
+ void commit_contracts(in contract::id_seq ids,
+ out contract::ptr_seq schedulable_contracts);
+
+ /**
+ * Cancels not-commited reservations.
+ *
+ * @param ids ID's of reserved contracts to be rolled-back
+ * to the state before reservation.
+ */
+ void cancel_reservations(in contract::id_seq ids);
+ /**
+ * Returns the list of commited contracts
+ *
+ * @param contracts Commited contracts
+ *
+ * @param utilization Utilization in the range 0-100
+ * (for visualization) or -1 if utilization cannot be
+ * calculated.
+ */
+ void get_contracts(out contract::ptr_seq contracts, out long utilization);
+ };
+};
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file frm_generic.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Tue Nov 11 08:34:34 2008
+ *
+ * @brief Generic resource manager implementation.
+ *
+ *
+ */
+#include <frm_generic.h>
+#include <forb.h>
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <fres_sa_scenario.h>
+#include <fcb.h>
+
+UL_LOG_CUST(ulogd_frm_generic);
+ul_log_domain_t ulogd_frm_generic = {UL_LOGL_DEB, "frm"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(frm_generic_logreg_domains, ulogd_frm_generic);
+
+#define object_to_frm(o) (struct frm_data*)forb_instance_data(o)
+#define save_errno(cmd) do { int _e = errno; cmd; errno = _e; } while(0)
+
+void fres_sa_scenario_reserve_new(struct fres_sa_scenario *scenario)
+{
+ struct fres_sa_contract *c;
+ fres_sa_scenario_for_each_contract(scenario, c) {
+ if (c->new) {
+ if (c->reserved) {
+ fres_contract_destroy(c->reserved);
+ }
+ c->reserved = c->new;
+ c->new = NULL;
+ }
+ }
+}
+
+void fres_sa_scenario_rollback(struct fres_sa_scenario *scenario)
+{
+ struct fres_sa_contract *c, *c_next;
+
+ /* Deleteion safe scenario traverse */
+ for(c=fres_sa_scenario_contract_first(scenario),
+ c_next=c?fres_sa_scenario_contract_next(scenario,c):NULL;
+ c;
+ c=c_next,c_next=c?fres_sa_scenario_contract_next(scenario,c):NULL) {
+ if (c->new) {
+ if (c->committed || c->reserved) {
+ fres_contract_destroy(c->new);
+ c->new = NULL;
+ c->contract = c->reserved ? c->reserved : c->committed;
+ } else {
+ fres_sa_scenario_del_contract(scenario, c);
+ fres_sa_contract_destroy(c);
+ }
+ }
+ }
+}
+
+
+static CORBA_long reserve_contracts(fres_resource_manager obj,
+ const fres_contract_ptr_seq* contracts,
+ CORBA_Environment *ev)
+{
+ struct frm_data *frm = object_to_frm(obj);
+ struct fres_sa_scenario *scenario = frm->scenario;
+ bool schedulable =false;
+ int i, ret;
+ struct fres_sa_contract *c;
+
+ ul_logmsg("reserve_contracts\n");
+
+ for (i=0; i<contracts->_length; i++) {
+ struct fres_contract *cin = contracts->_buffer[i];
+
+ c = fres_sa_scenario_find_contract(scenario, &cin->id);
+ if (!c) {
+ c = fres_sa_contract_new();
+ if (c) {
+ c->id = cin->id;
+ fres_sa_scenario_add_contract(scenario, c);
+ }
+ }
+ if (!c) goto err;
+
+ {
+ char id[40];
+ char *operation;
+ fres_contract_id_to_string(id, &c->id, sizeof(id));
+ if (fres_contract_get_num_blocks(cin) == 0) operation = "cancelation";
+ else if (c->committed) operation = "renegotiation";
+ else if (c->reserved) operation = "negotiation (already reserved)";
+ else operation = "negotiation";
+ ul_logdeb(" reserve contract %s %s\n", id, operation);
+ }
+ assert(c->new == NULL);
+ c->new = fres_contract_duplicate(cin);
+ c->contract = c->new;
+ if (!c->new) goto err;
+ }
+
+ ret = frm->desc->admission_test(scenario, frm->desc->priv, &schedulable);
+ if (ret) {
+ ul_logmsg("admission_test failed: %d\n", ret);
+ goto err;
+ }
+
+ if (schedulable) {
+ fres_sa_scenario_reserve_new(scenario);
+ } else {
+ fres_sa_scenario_rollback(scenario);
+ }
+ return schedulable ? 0 : 1;
+err:
+ fres_sa_scenario_rollback(scenario);
+ return -1;
+}
+
+static int utilization(struct fres_contract *c)
+{
+ fres_block_basic *b;
+ b = fres_contract_get_basic(c);
+ if (b) {
+ uint64_t budget, period;
+ budget = fosa_rel_time_to_nsec(b->budget);
+ period = fosa_rel_time_to_nsec(b->period);
+ return budget*100000/period;
+ } else
+ return 0;
+}
+
+static void clear_id(fres_contract_id_t *id)
+{
+ memset(id, 0, sizeof(*id));
+}
+
+static void commit_contracts(fres_resource_manager obj,
+ const fres_contract_id_seq* ids,
+ fres_contract_ptr_seq** contracts_with_scheduling_data,
+ CORBA_Environment *ev)
+{
+ struct frm_data *frm = object_to_frm(obj);
+ int i, num;
+ struct fres_sa_contract *c;
+ fres_contract_ptr_seq *contracts;
+ enum { CANCELATION, DECREASE, INCREASE } pass;
+
+ ul_logmsg("commit_contracts\n");
+
+ contracts = forb_malloc(sizeof(*contracts));
+ if (!contracts) {
+ ev->major = FORB_EX_NO_MEMORY;
+ goto err;
+ }
+ num = ids->_length;
+ contracts->_buffer = CORBA_sequence_fres_contract_ptr_allocbuf(num);
+ CORBA_sequence_set_release(contracts, CORBA_TRUE);
+ contracts->_maximum = num;
+ contracts->_length = 0;
+
+ /* TODO: Add also the changed contracts (e.g. because of
+ * priorities). Question: How to recognize which contracts are
+ * changed because of this commit? */
+ for (pass = CANCELATION; pass <= INCREASE; pass++) {
+ for (i=0; i < num; i++) {
+ char id[40];
+ const char *operation = NULL;
+ if (fres_contract_id_is_empty(&ids->_buffer[i])) {
+ /* This ID was handled in a previous pass */
+ continue;
+ }
+ fres_contract_id_to_string(id, &ids->_buffer[i], sizeof(id));
+
+ c = fres_sa_scenario_find_contract(frm->scenario, &ids->_buffer[i]);
+ if (c && c->reserved) {
+ if (fres_contract_get_num_blocks(c->reserved) == 0 &&
+ pass == CANCELATION) {
+ /* Cancelation request */
+ operation = "cancelation";
+ contracts->_buffer[contracts->_length++] = c->reserved;
+ c->reserved = NULL;
+ fres_sa_scenario_del_contract(frm->scenario, c);
+ fres_sa_contract_destroy(c);
+ clear_id(&ids->_buffer[i]);
+ } else {
+ /* Normal reservation */
+ if (c->committed) {
+ if ((utilization(c->reserved) < utilization(c->committed) && pass == DECREASE) ||
+ (utilization(c->reserved) >= utilization(c->committed) && pass == INCREASE)) {
+ operation = "renegotiation";
+ fres_contract_destroy(c->committed);
+ c->committed = c->reserved;
+ c->reserved = NULL;
+ contracts->_buffer[contracts->_length++] = fres_contract_duplicate(c->committed);
+ clear_id(&ids->_buffer[i]);
+ }
+ } else if (pass == INCREASE) {
+ operation = "negotiation";
+ c->committed = c->reserved;
+ c->reserved = NULL;
+ contracts->_buffer[contracts->_length++] = fres_contract_duplicate(c->committed);
+ clear_id(&ids->_buffer[i]);
+ }
+ }
+ } else {
+ operation = "error";
+ contracts->_buffer[contracts->_length++] = NULL;
+ if (!c) ul_logerr("Commit to unknown contract ID\n");
+ else if (!c->reserved) ul_logerr("Commit to not reserved contract\n");
+ }
+ if (operation) {
+ ul_logdeb(" commit contract %s %s\n", id, operation);
+ }
+ }
+ }
+
+ *contracts_with_scheduling_data = contracts;
+err:;
+}
+
+static void cancel_reservations(fres_resource_manager obj,
+ const fres_contract_id_seq* ids,
+ CORBA_Environment *ev)
+{
+ int i;
+ struct frm_data *frm = object_to_frm(obj);
+
+ ul_logmsg("cancel_reservations\n");
+
+ for (i=0; i<ids->_length; i++) {
+ struct fres_sa_contract *c;
+ c = fres_sa_scenario_find_contract(frm->scenario, &ids->_buffer[i]);
+
+ if (!c) {
+ char id[40];
+ fres_contract_id_to_string(id, &ids->_buffer[i], sizeof(id));
+ ul_logerr("Cannot cancel reservation of unknown contract %s\n",
+ id);
+ continue;
+ }
+ if (c->reserved) {
+ if (c->committed) {
+ /* Roll-back renegotiation */
+ fres_contract_destroy(c->reserved);
+ c->reserved = NULL;
+ c->contract = c->committed;
+ } else {
+ /* Roll-back negotiation */
+ fres_sa_scenario_del_contract(frm->scenario, c);
+ fres_sa_contract_destroy(c);
+ }
+ }
+ }
+}
+
+
+static void get_contracts(fres_resource_manager obj,
+ fres_contract_ptr_seq** contracts_out,
+ CORBA_long* utilization, CORBA_Environment *ev)
+{
+ struct frm_data *frm = object_to_frm(obj);
+ struct fres_sa_contract *c;
+ fres_contract_ptr_seq *contracts;
+
+ contracts = forb_malloc(sizeof(*contracts));
+ if (!contracts) {
+ ev->major = FORB_EX_NO_MEMORY;
+ goto err;
+ }
+ contracts->_buffer = CORBA_sequence_fres_contract_ptr_allocbuf(frm->scenario->num_contracts);
+ CORBA_sequence_set_release(contracts, CORBA_TRUE);
+ contracts->_maximum = frm->scenario->num_contracts;
+ contracts->_length = 0;
+
+ fres_sa_scenario_for_each_contract(frm->scenario, c) {
+ if (c->committed) {
+ int i = contracts->_length;
+ contracts->_buffer[i] = fres_contract_duplicate(c->committed);
+ contracts->_length++;
+ }
+
+ }
+ *contracts_out = contracts;
+ *utilization = frm->scenario->utilization;
+err:;
+}
+
+
+static const struct forb_fres_resource_manager_impl frm_impl = {
+ .reserve_contracts = reserve_contracts,
+ .commit_contracts = commit_contracts,
+ .cancel_reservations = cancel_reservations,
+ .get_contracts = get_contracts,
+};
+
+/**
+ * Initializes generic resource manager. The only thing a
+ * caller has to supply is admission test function, which is passed in
+ * @a frm_data->admission_test.
+ *
+ * @param orb FORB object used to communicate with other components.
+ * @param[out] frm_data Pointer to frm_data structure
+ * @param executor Executor used for this resource manager.
+ * @param desc Description on the resource manager
+ *
+ * @return Resource manager object reference of NULL in case of error.
+ */
+fres_resource_manager frm_register(forb_orb orb, struct frm_data *frm_data,
+ forb_executor_t *executor,
+ const struct fres_res_manager *desc)
+{
+ fres_contract_broker fcb;
+ fres_resource_desc res_desc;
+ fres_resource_manager frm;
+ struct forb_env env;
+ int ret;
+
+ memset(frm_data, 0, sizeof(*frm_data));
+ frm_data->desc = desc;
+ frm_data->scenario = fres_sa_scenario_new();
+ if (!frm_data->scenario) {
+ save_errno(ul_logerr("fres_sa_scenario_new failed\n"));
+ goto err;
+ }
+
+ fcb = forb_resolve_reference(orb, fres_contract_broker_reg_name);
+ if (!fcb) {
+ save_errno(ul_logerr("Could not find contract broker\n"));
+ goto err;
+ }
+
+ frm = forb_fres_resource_manager_new(orb, &frm_impl, frm_data);
+ if (!frm) {
+ save_errno(ul_logerr("forb_fres_resource_manager_new error\n"));
+ goto err_release_fcb;
+ }
+
+ ret = forb_executor_register_object(executor, frm);
+ if (ret) {
+ save_errno(ul_logerr("forb_executor_register_object failed\n"));
+ goto err_executor;
+ }
+
+ /* Register resource manager */
+ res_desc.manager = frm;
+ res_desc.name = desc->name;
+ ret = fres_contract_broker_register_resource(fcb,
+ desc->res_type,
+ desc->res_id,
+ &res_desc, &env);
+ if (forb_exception_occurred(&env)) {
+ save_errno(ul_logerr("fres_contract_broker_register_resource: %s\n", forb_strerror(&env)));
+ goto err_register;
+ } else if (ret != 0) {
+ save_errno(ul_logerr("fres_contract_broker_register_resource error: %d\n", ret));
+ goto err_register;
+ }
+
+ forb_object_release(fcb);
+ return frm;
+err_register:
+ forb_executor_unregister_object(executor, frm);
+err_executor:
+ forb_object_release(frm);
+err_release_fcb:
+ forb_object_release(fcb);
+err:
+ return NULL;
+}
+
+/**
+ * Initializes and runs a generic resource manager. The only thing a
+ * caller has to supply is admission test function, which is passed in
+ * @a frm_data->admission_test.
+ *
+ * @param orb FORB object used to communicate with other components.
+ * @param desc Description on the resource manager
+ *
+ * @return
+ */
+int frm_register_and_run(forb_orb orb, const struct fres_res_manager *desc)
+{
+ fres_resource_manager frm;
+ struct frm_data frm_data;
+ forb_executor_t executor;
+ int ret = -1;
+
+ /* Prepare executor before we register the resource manager
+ * with contract broker */
+ ret = forb_executor_init(&executor);
+ if (ret) {
+ save_errno(ul_logerr("forb_executor_init failed\n"));
+ goto err;
+ }
+
+ frm = frm_register(orb, &frm_data, &executor, desc);
+ if (!frm) {
+ ret = -1;
+ save_errno(ul_logerr("frm_register failed\n"));
+ goto err_destroy_executor;
+ }
+
+ /* Start request processing */
+ ul_logmsg("Waiting for requests\n");
+ forb_daemon_ready();
+ ret = forb_executor_run(&executor);
+ if (ret) goto err_release_frm;
+
+err_release_frm:
+ forb_object_release(frm);
+err_destroy_executor:
+ forb_executor_destroy(&executor);
+err:
+ return ret;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file frm_generic.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Tue Nov 11 08:34:09 2008
+ *
+ * @brief Generic resource manager declarations
+ *
+ *
+ */
+#ifndef FRM_GENERIC_H
+#define FRM_GENERIC_H
+
+#include <frm.h>
+#include <fres_sa_scenario.h>
+#include <fra_generic.h>
+#include <ul_log.h>
+
+extern ul_log_domain_t ulogd_frm_generic;
+
+/**
+ * Admission test for a given resource.
+ *
+ * The admission test is called from
+ * fres::resource_manager::reserve_contracts() to evaluate
+ * schedulability of the scenario given as a parameter. It can use
+ * fres_sa_scenario_for_each_no_cancel_contract() or
+ * fres_sa_scenario_for_each_no_cancel_contract() macros to traverse
+ * all the relevant contracts in the scenario. No constract should be
+ * added or deleted, but any data (blocks) can be added to the
+ * contracts. If the scenario is schedulable, the contracts (with
+ * possibly added data) are sent to resource scheduler, which can use
+ * this additional data as parameters for VRes creation.
+ *
+ * During the admission test, the contracts in scenariou can be
+ * processed in any way as the test desires. The contract to be tested
+ * is stored in fres_sa_contract::contract. If the test want to know
+ * about the state of the contract it can compare the value of
+ * fres_sa_contract::contract with fres_sa_contract::new,
+ * fres_sa_contract::reserved and fres_sa_contract::commited.
+ *
+ * @param[in] scenario Scenario to check its schedulability.
+ * @param[in] priv Pointer to private data, registered by frm_generic_run().
+ * @param[out] schedulable Set to true if the scenario is schedulable, to false otherwise.
+ *
+ * @return Zero on success, non-zero error code on return.
+ */
+typedef int (*frm_adm_test_fnc_t)(struct fres_sa_scenario *scenario, void *priv, bool *schedulable);
+
+/** Description of a resource manager */
+struct fres_res_manager {
+ frsh_resource_type_t res_type;
+ frsh_resource_id_t res_id;
+ frm_adm_test_fnc_t admission_test; /**< Pointer to the admission test routine */
+ char *name; /**< Human understandable name of the resource (displayed by frm_gui) */
+ void *priv; /**< Any data to be passed to admission test */
+};
+
+struct frm_data {
+ struct fres_sa_scenario *scenario;
+ const struct fres_res_manager *desc;
+};
+
+fres_resource_manager frm_register(forb_orb orb, struct frm_data *frm_data,
+ forb_executor_t *executor,
+ const struct fres_res_manager *desc);
+int frm_register_and_run(forb_orb orb,
+ const struct fres_res_manager *desc);
+
+#endif
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+shared_LIBRARIES = sharedobj
+
+sharedobj_SOURCES = fres_sharedobj.c
+sharedobj_CLIENT_IDL = fres_sharedobj_idl.idl
+
+#fres_sharedobj_idl_IDLFLAGS = --include=fres_contract_ser.h
+#fres_blocks_IDLFLAGS = --include=idl_native.h
+
+include_HEADERS = fres_sharedobj.h
+
+include_GEN_HEADERS = fres_sharedobj_idl.h
+
+SUBDIRS=tests
--- /dev/null
+/**
+ * @file fres_sharedobj.c
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ *
+ * @brief Implementation of shared objects functions.
+ *
+ *
+ */
+#include <frsh_forb.h>
+#include <fres_sharedobj.h>
+#include <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+/**
+ * Allocates new fres_sharedobj structure. Use fres_sharedobj_destroy to
+ * deallocate the shared object.
+ *
+ * @return The new object on succes, NULL on error.
+ */
+struct fres_sharedobj* fres_sharedobj_new(const char *label, int kind)
+{
+ struct fres_sharedobj *s;
+ char shm_path[108];
+ int ret, shm_fd;
+
+ snprintf(shm_path, sizeof(shm_path), "/shared.%s", label);
+
+ shm_fd = shm_open(shm_path, O_CREAT|O_EXCL|O_RDWR, S_IRWXU|S_IRWXG);
+ if (shm_fd < 0) goto err;
+ ret = ftruncate(shm_fd, sizeof(*s));
+ if (ret) goto unlink_err;
+
+ s = mmap(NULL, sizeof(*s),
+ PROT_READ|PROT_WRITE, MAP_SHARED,
+ shm_fd, 0);
+ if (s == MAP_FAILED) goto unlink_err;
+
+ memcpy(s->label, label, sizeof(s->label));
+ memcpy(s->path, shm_path, sizeof(shm_path));
+ fosa_mutex_init(&s->mutex, 0);
+ s->kind = kind;
+
+ return s;
+
+unlink_err:
+ shm_unlink(shm_path);
+err:
+ return NULL;
+}
+
+struct fres_sharedobj* fres_sharedobj_get_path(const char *sharedobj_path)
+{
+ struct fres_sharedobj *s = NULL;
+ int shm_fd;
+
+ shm_fd = shm_open(sharedobj_path, O_RDWR, S_IRWXU|S_IRWXG);
+ if (shm_fd < 0) goto out;
+
+ s = mmap(NULL, sizeof(*s),
+ PROT_READ|PROT_WRITE, MAP_SHARED,
+ shm_fd, 0);
+ if (s == MAP_FAILED) goto out;
+
+out:
+ return s;
+}
+
+struct fres_sharedobj* fres_sharedobj_get_label(const char *label)
+{
+ char shm_path[108];
+
+ snprintf(shm_path, sizeof(shm_path), "/shared.%s", label);
+
+ return fres_sharedobj_get_path(shm_path);
+}
+
+int fres_sharedobj_put(struct fres_sharedobj *s)
+{
+ return munmap((void*) s, sizeof(*s));
+}
+
+int fres_sharedobj_destroy(struct fres_sharedobj *s)
+{
+ int ret = 0;
+
+ if (!s) return EINVAL;
+
+ /* Since now no new task can mmap the object. */
+ ret = shm_unlink(s->path);
+ if (ret) goto out;
+
+ ret = fres_sharedobj_put(s);
+ if (ret) goto out;
+
+out:
+ return ret;
+}
+
+int
+fres_sharedobj_to_string(char *dest,
+ size_t size,
+ const struct fres_sharedobj *s)
+{
+ int ret;
+
+ if (!s) return 0;
+
+ ret = snprintf(dest, size, "label: %s\n"
+ "path: %s\n"
+ "kind: %d\n",
+ s->label, s->path, s->kind);
+
+ return ret;
+}
+
+void
+fres_sharedobj_print(char *prefix, const struct fres_sharedobj *s)
+{
+ char sharedobj[1000];
+
+ fres_sharedobj_to_string(sharedobj, sizeof(sharedobj)-1, s);
+ sharedobj[sizeof(sharedobj)-1] = 0;
+ printf("%s %s", prefix, sharedobj);
+}
+
--- /dev/null
+/**
+ * @file fres_sharedobj.h
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ *
+ * @brief Declaration of synchronization object type and functions.
+ *
+ *
+ */
+#ifndef FRES_SHAREDOBJ_H
+#define FRES_SHAREDOBJ_H
+
+#include <ul_gavl.h>
+#include <forb/server_id.h>
+#include <fres_sharedobj_idl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Synchronization object data type.
+ *
+ */
+struct fres_sharedobj {
+ char path[108]; /**< Filesystem path of the POSIX semaphore. */
+
+ fosa_mutex_t mutex; /**< POSIX mutex implementing the object. */
+ fosa_timer_id_t wcet_timer; /** WCET enforcing timer. */
+ fosa_long_jump_context_t context; /** Jump context (for overruns). */
+
+ char label[65]; /**< Shared object label. */
+ int kind; /**< Shared object kind. */
+};
+
+static inline int fres_sharedobj_id_cmp(const fres_sharedobj_id_t *a,
+ const fres_sharedobj_id_t *b)
+{
+ return forb_server_id_cmp((forb_server_id*)a,
+ (forb_server_id*)b);
+}
+
+static inline char *fres_sharedobj_id_to_string(char *dest,
+ const fres_sharedobj_id_t *id,
+ size_t n)
+{
+ return forb_server_id_to_string(dest, (forb_server_id*)id, n);
+}
+
+struct fres_sharedobj *fres_sharedobj_new(const char *label, int kind);
+struct fres_sharedobj *fres_sharedobj_get_path(const char sharedobj_path[]);
+struct fres_sharedobj *fres_sharedobj_get_label(const char sharedobj_label[]);
+int fres_sharedobj_put(struct fres_sharedobj *s);
+int fres_sharedobj_destroy(struct fres_sharedobj *sharedobj);
+
+void
+fres_sharedobj_print(char *prefix, const struct fres_sharedobj *c);
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif
+
--- /dev/null
+/**
+ * @file fres_synchobj_idl.idl
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ *
+ * @brief Definitions of data types and constants for
+ FRESCOR synchronization objects.
+ *
+ */
+
+#ifndef _SHAREDOBJ_IDL
+#define _SHAREDOBJ_IDL
+module fres {
+ module sharedobj {
+ /// Pointer to the contract type
+ native ptr;
+
+ /// Globaly unique contract ID
+ struct id_t {
+ char byte[8];
+ };
+
+ };
+};
+
+#endif
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+test_PROGRAMS:=$(basename $(notdir $(wildcard $(SOURCES_DIR)/*.c)))
+
+$(foreach t,$(test_PROGRAMS),\
+$(eval $(t)_SOURCES = $(t).c)\
+$(eval $(t)_LIBS = fosa m contract sharedobj rt forb ulut)\
+)
--- /dev/null
+#include <fosa.h>
+#include <fres_sharedobj.h>
+#include <error.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <forb/cdr.h>
+
+void cmp(struct fres_sharedobj *s1, struct fres_sharedobj *s2, const char *msg)
+{
+ int ret;
+
+ ret = strncmp(s1->path, s2->path, sizeof(s1->path));
+ if (ret) error(1, 0, "%s: path cmp failed %d", msg, ret);
+
+ ret = memcmp(&s1->mutex, &s2->mutex, sizeof(fosa_mutex_t));
+ if (ret) error(1, 0, "%s: mutex var. cmp failed %d", msg, ret);
+
+ ret = memcmp(&s1->wcet_timer,
+ &s2->wcet_timer,
+ sizeof(fosa_timer_id_t));
+ if (ret) error(1, 0, "%s: timer cmp failed %d", msg, ret);
+
+ ret = memcmp(&s1->context,
+ &s2->context,
+ sizeof(fosa_long_jump_context_t));
+ if (ret) error(1, 0, "%s: context cmp failed %d", msg, ret);
+
+ ret = strncmp(s1->label, s2->label, sizeof(s1->label));
+ if (ret) error(1, 0, "%s: label cmp failed %d", msg, ret);
+
+ ret = s1->kind == s2->kind;
+ if (!ret) error(1, 0, "%s: kind cmp failed %d", msg, ret);
+}
+
+int main()
+{
+ int ret;
+ struct fres_sharedobj *s, *s2;
+
+ s = fres_sharedobj_new("SHAREDOBJ_0", 0);
+ if (!s) error(1, errno, "fres_sharedobj_new");
+
+ fres_sharedobj_print("print new sharedobj:\n", s);
+
+ s2 = fres_sharedobj_get_label("SHAREDOBJ_0");
+ if (!s2) error(1, errno, "fres_sharedobj_get_label");
+ cmp(s, s2, "cmp after fres_sharedobj_get_label");
+ ret = fres_sharedobj_put(s2);
+ if (ret) error(1, errno, "fres_sharedobj_put after get_label");
+
+ s2 = fres_sharedobj_get_path(s->path);
+ if (!s2) error(1, errno, "fres_sharedobj_get_path");
+ cmp(s, s2, "cmp after fres_sharedobj_get_path");
+ ret = fres_sharedobj_put(s2);
+ if (ret) error(1, errno, "fres_sharedobj_put after get_path");
+
+ ret = fres_sharedobj_destroy(s);
+ if (ret) error(1, errno, "frsh_sharedobj_destroy");
+
+ printf("OK\n");
+
+ return 0;
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+shared_LIBRARIES = synchobj
+
+synchobj_SOURCES = fres_synchobj.c
+synchobj_CLIENT_IDL = fres_synchobj_idl.idl
+
+#fres_synchobj_idl_IDLFLAGS = --include=fres_contract_ser.h
+#fres_blocks_IDLFLAGS = --include=idl_native.h
+
+include_HEADERS = fres_synchobj.h
+
+include_GEN_HEADERS = fres_synchobj_idl.h
+
+SUBDIRS=tests
--- /dev/null
+/**
+ * @file fres_synchobj.c
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ *
+ * @brief Implementation of synchronization objects functions.
+ *
+ *
+ */
+#include <frsh_forb.h>
+#include <fres_synchobj.h>
+#include <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+/**
+ * Allocates new fres_synchobj structure. Use fres_synchobj_destroy to
+ * deallocate the synchronization object.
+ *
+ * @return The new object on succes, NULL on error.
+ */
+struct fres_synchobj* fres_synchobj_new()
+{
+ struct fres_synchobj *s;
+ fres_synchobj_id_t id;
+ char shm_path[108], str_id[65];
+ int ret, shm_fd;
+
+ forb_uuid_generate((forb_uuid_t*) &id);
+ sprintf(shm_path, "/sync.%s",
+ fres_synchobj_id_to_string(str_id, &id, sizeof(str_id)));
+
+ shm_fd = shm_open(shm_path, O_CREAT|O_EXCL|O_RDWR, S_IRWXU|S_IRWXG);
+ if (shm_fd < 0) goto err;
+ ret = ftruncate(shm_fd, sizeof(*s));
+ if (ret) goto unlink_err;
+
+ s = mmap(NULL, sizeof(*s),
+ PROT_READ|PROT_WRITE, MAP_SHARED,
+ shm_fd, 0);
+ if (s == MAP_FAILED) goto unlink_err;
+
+ s->id = id;
+ memcpy(s->path, shm_path, sizeof(shm_path));
+
+ fosa_cond_init(&s->cond);
+ fosa_mutex_init(&s->mutex, 0);
+
+ s->nr_waiting = 0;
+ s->queued_signal = 0;
+
+ return s;
+
+unlink_err:
+ shm_unlink(shm_path);
+err:
+ return NULL;
+}
+
+struct fres_synchobj* fres_synchobj_get_path(const char synchobj_path[])
+{
+ struct fres_synchobj *s = NULL;
+ int shm_fd;
+
+ shm_fd = shm_open(synchobj_path, O_RDWR, S_IRWXU|S_IRWXG);
+ if (shm_fd < 0) goto out;
+
+ s = mmap(NULL, sizeof(*s),
+ PROT_READ|PROT_WRITE, MAP_SHARED,
+ shm_fd, 0);
+ if (s == MAP_FAILED) goto out;
+
+out:
+ return s;
+}
+
+struct fres_synchobj* fres_synchobj_get(const fres_synchobj_id_t *id)
+{
+ char shm_path[108], str_id[65];
+
+ sprintf(shm_path, "/sync.%s",
+ fres_synchobj_id_to_string(str_id, id, sizeof(str_id)));
+
+ return fres_synchobj_get_path(shm_path);
+}
+
+int fres_synchobj_put(struct fres_synchobj *s)
+{
+ return munmap((void*) s, sizeof(*s));
+}
+
+int fres_synchobj_destroy(struct fres_synchobj *s)
+{
+ int ret = 0;
+
+ if (!s) return EINVAL;
+
+ /* Since now no new task can mmap the object. */
+ ret = shm_unlink(s->path);
+ if (ret) goto out;
+
+ fosa_mutex_lock(&s->mutex);
+
+ /* If there are waiting tasks try to wake up them. */
+ if (s->nr_waiting)
+ fosa_cond_broadcast(&s->cond);
+
+ /* Mark the synchronization object as invalid. */
+ s->nr_waiting = -1;
+ fosa_mutex_unlock(&s->mutex);
+
+ ret = fres_synchobj_put(s);
+ if (ret) goto out;
+
+out:
+ return ret;
+}
+
+int fres_synchobj_wait_with_timeout
+ (struct fres_synchobj *s,
+ const fosa_abs_time_t *timeout)
+{
+ int ret = 0;
+
+ if (!s) return EINVAL;
+
+ fosa_mutex_lock(&s->mutex);
+ if (s->nr_waiting == -1) goto unmap_err;
+
+ if (!s->queued_signal) {
+ s->nr_waiting++;
+ if (!timeout)
+ ret = fosa_cond_wait(&s->cond, &s->mutex);
+ else
+ ret = fosa_cond_timedwait(&s->cond,
+ &s->mutex,
+ timeout);
+ if (ret) goto wakeup_err;
+
+ if (s->nr_waiting == -1) goto unmap_err;
+ } else
+ s->queued_signal--;
+
+wakeup_err:
+ s->nr_waiting--;
+ fosa_mutex_unlock(&s->mutex);
+
+ return ret;
+
+unmap_err:
+ fosa_mutex_unlock(&s->mutex);
+ ret = munmap((void*) s, sizeof(*s));
+
+ return ret;
+}
+
+int fres_synchobj_signal(struct fres_synchobj *s)
+{
+ int ret = 0;
+
+ fosa_mutex_lock(&s->mutex);
+ if (s->nr_waiting == -1) goto unmap_err;
+
+ if (!s->nr_waiting)
+ s->queued_signal++;
+ else
+ ret = fosa_cond_signal(&s->cond);
+
+ fosa_mutex_unlock(&s->mutex);
+
+ return ret;
+
+unmap_err:
+ fosa_mutex_unlock(&s->mutex);
+ ret = munmap((void*) s, sizeof(*s));
+
+ return ret;
+}
+
+int
+fres_synchobj_to_string(char *dest, size_t size, const struct fres_synchobj *s)
+{
+ int ret;
+ char id[30];
+
+ if (!s) return 0;
+
+ fres_synchobj_id_to_string(id, &s->id, sizeof(id));
+ ret = snprintf(dest, size, "id: %s\n"
+ "path: %s\n"
+ "nr. waiting: %d\n"
+ "queued signals: %d\n",
+ id, s->path, s->nr_waiting,s->queued_signal);
+
+ return ret;
+}
+
+void
+fres_synchobj_print(char *prefix, const struct fres_synchobj *s)
+{
+ char synchobj[1000];
+
+ fres_synchobj_to_string(synchobj, sizeof(synchobj)-1, s);
+ synchobj[sizeof(synchobj)-1] = 0;
+ printf("%s %s", prefix, synchobj);
+}
+
--- /dev/null
+/**
+ * @file fres_synchobj.h
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ *
+ * @brief Declaration of synchronization object type and functions.
+ *
+ *
+ */
+#ifndef FRES_SYNCHOBJ_H
+#define FRES_SYNCHOBJ_H
+
+#include <ul_gavl.h>
+#include <forb/server_id.h>
+#include <fres_synchobj_idl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Synchronization object data type.
+ *
+ */
+struct fres_synchobj {
+ fres_synchobj_id_t id; /**< Global ID */
+ char path[108]; /**< Filesystem path of the POSIX semaphore. */
+
+ fosa_cond_t cond; /**< POSIX condition variable. */
+ fosa_mutex_t mutex; /**< POSIX mutex (for exclusive access). */
+
+ int nr_waiting; /**< Number of waiting vreses. */
+ int queued_signal; /**< Number of not yet delivered signals. */
+};
+
+static inline int fres_synchobj_id_cmp(const fres_synchobj_id_t *a,
+ const fres_synchobj_id_t *b)
+{
+ return forb_server_id_cmp((forb_server_id*)a,
+ (forb_server_id*)b);
+}
+
+static inline char *fres_synchobj_id_to_string(char *dest,
+ const fres_synchobj_id_t *id,
+ size_t n)
+{
+ return forb_server_id_to_string(dest, (forb_server_id*)id, n);
+}
+
+struct fres_synchobj *fres_synchobj_new(void);
+struct fres_synchobj *fres_synchobj_get_path(const char synchobj_path[]);
+struct fres_synchobj *fres_synchobj_get(const fres_synchobj_id_t *id);
+int fres_synchobj_put(struct fres_synchobj *s);
+int fres_synchobj_destroy(struct fres_synchobj *synchobj);
+
+int fres_synchobj_signal(struct fres_synchobj *s);
+int fres_synchobj_wait_with_timeout(struct fres_synchobj *s,
+ const fosa_abs_time_t *timeout);
+
+void
+fres_synchobj_print(char *prefix, const struct fres_synchobj *c);
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif
+
--- /dev/null
+/**
+ * @file fres_synchobj_idl.idl
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ *
+ * @brief Definitions of data types and constants for
+ FRESCOR synchronization objects.
+ *
+ */
+
+#ifndef _SYNCHOBJ_IDL
+#define _SYNCHOBJ_IDL
+module fres {
+ module synchobj {
+ /// Pointer to the contract type
+ native ptr;
+
+ /// Globaly unique contract ID
+ struct id_t {
+ char byte[8];
+ };
+
+ };
+};
+
+#endif
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+test_PROGRAMS:=$(basename $(notdir $(wildcard $(SOURCES_DIR)/*.c)))
+
+$(foreach t,$(test_PROGRAMS),\
+$(eval $(t)_SOURCES = $(t).c)\
+$(eval $(t)_LIBS = fosa m synchobj rt forb ulut)\
+)
--- /dev/null
+#include <fosa.h>
+#include <fres_synchobj.h>
+#include <error.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <forb/cdr.h>
+
+void cmp(struct fres_synchobj *s1, struct fres_synchobj *s2, const char *msg)
+{
+ int ret;
+
+ ret = fres_synchobj_id_cmp(&s1->id, &s2->id);
+ if (ret) error(1, 0, "%s: id cmp failed %d", msg, ret);
+
+ ret = strncmp(s1->path, s2->path, sizeof(s1->path));
+ if (ret) error(1, 0, "%s: path cmp failed %d", msg, ret);
+
+ ret = memcmp(&s1->cond, &s2->cond, sizeof(fosa_cond_t));
+ if (ret) error(1, 0, "%s: condition var. cmp failed %d", msg, ret);
+
+ ret = memcmp(&s1->mutex, &s2->mutex, sizeof(fosa_mutex_t));
+ if (ret) error(1, 0, "%s: mutex cmp failed %d", msg, ret);
+
+ ret = s1->nr_waiting == s2->nr_waiting;
+ if (!ret) error(1, 0, "%s: nr_waiting cmp failed %d", msg, ret);
+
+ ret = s1->queued_signal == s2->queued_signal;
+ if (!ret) error(1, 0, "%s: queued_signal cmp failed %d", msg, ret);
+}
+
+int main()
+{
+ int ret;
+ struct fres_synchobj *s, *s2;
+ fosa_abs_time_t timeout;
+
+ s = fres_synchobj_new();
+ if (!s) error(1, errno, "fres_synchobj_new");
+
+ fres_synchobj_print("print new synchobj:\n", s);
+
+ s2 = fres_synchobj_get_path(s->path);
+ if (!s2) error(1, errno, "fres_synchobj_get_path");
+ cmp(s, s2, "cmp after fres_synchobj_get_path");
+ ret = fres_synchobj_put(s2);
+ if (ret) error(1, errno, "fres_synchobj_put after get_path");
+
+ s2 = fres_synchobj_get(&s->id);
+ if (!s2) error(1, errno, "fres_synchobj_get");
+ cmp(s, s2, "cmp after fres_synchobj_get");
+ ret = fres_synchobj_put(s2);
+ if (ret) error(1, errno, "fres_synchobj_put after get");
+
+ timeout = fosa_msec_to_abs_time(1000);
+ ret = fres_synchobj_wait_with_timeout(s, &timeout);
+ if (ret != ETIMEDOUT) error(1, errno, "fres_synchobj_wait_with_timeout");
+
+ ret = fres_synchobj_signal(s);
+ if (ret) error(1, errno, "fres_synchobj_signal");
+
+ ret = fres_synchobj_wait_with_timeout(s, NULL);
+ if (ret) error(1, errno, "wait with NULL timeout and queued signal");
+
+ /*{
+ FORB_CDR_Codec codec;
+ CORBA_boolean cb;
+ FORB_CDR_codec_init_static(&codec, NULL);
+ cb = FORB_CDR_buffer_init(&codec, 4000, 0);
+ if (!cb) error(1, errno, "CDR_buffer_init");
+
+ cb = fres_synchobj_id_t_serialize(&codec, &s);
+ if (!cb) error(1, 0, "fres_synchobj_serialize failed");
+ cb = fres_synchobj_id_t_deserialize(&codec, &s2);
+ if (!cb) error(1, 0, "fres_synchobj_deserialize failed");
+
+ cmp(s, s2, "cmp after serialize/desearialize");
+
+ }*/
+
+ ret = fres_synchobj_destroy(s);
+ if (ret) error(1, errno, "frsh_synchobj_destroy");
+
+ printf("OK\n");
+
+ return 0;
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+SUBDIRS = tests
+
+shared_LIBRARIES = frsh
+frsh_SOURCES = frsh_contract.c frsh_vres.c frsh_synchobj.c frsh_core.c \
+ frsh_spare_capacity.c frsh_error.c frsh_thread.c \
+ frsh_sharedobj.c frsh_power.c frsh_feedback.c \
+ frsh_transaction.c
+include_HEADERS = frsh_opaque_types.h frsh_forb.h
+frsh_LIBS = fcb_client forb contract synchobj sharedobj fra ulut fosa $(allocator-libs-y) $(platform-libs-y)
+
+ifneq ($(filter y true 1,$(FRSH_DISTRIBUTED_MODULE_SUPPORTED)),)
+frsh_SOURCES += frsh_distributed.c
+frsh_LIBS += fna
+endif
+
+config_include_HEADERS = frsh_resources.h
+frsh_resources_DEFINES = CONFIG_RESOURCE_DUMMY \
+ CONFIG_AQUOSA\
+ CONFIG_CPUCG\
+ CONFIG_DISKBFQ\
+ CONFIG_FWP \
+ CONFIG_RESOURCE_ITEM \
+ CONFIG_ACPI_LCD \
+ CONFIG_ACPI_CPU \
+ CONFIG_ACPI_BATTERY
+
+allocator-libs-$(CONFIG_RESOURCE_DUMMY) += fra_dummy
+allocator-libs-$(CONFIG_RESOURCE_ITEM) += fra_item
+allocator-libs-$(CONFIG_FWP) += frsh_fwp fwp
+allocator-libs-$(CONFIG_AQUOSA) += frshaqcpu
+allocator-libs-$(CONFIG_CPUCG) += frshcpucg
+allocator-libs-$(CONFIG_DISKBFQ) += frshdiskbfq
+
+platform-libs-$(CONFIG_ACPI_CPU) += acpi_cpu
+platform-libs-$(CONFIG_ACPI_LCD) += acpi_lcd
+platform-libs-$(CONFIG_ACPI_BATTERY) += acpi_battery
+
+ifneq ($(AQUOSA_ROOT),)
+LOADLIBES += -L $(AQUOSA_ROOT)/lib
+LDFLAGS += -L $(AQUOSA_ROOT)/lib
+endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file frsh_contract.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * Dario Faggioli <faggioli@gandalf.sssup.it>
+ *
+ * @brief Implementation of FRSH contract API on top of FRES contracts.
+ *
+ *
+ */
+#include <fres_contract.h>
+#include <fres_contract_idl.h>
+#include <frsh_core.h>
+#include <frsh_error.h>
+#include <fres_blocks.h>
+#include <string.h>
+#include <fcb.h>
+#include "frsh_forb.h"
+#include <fra_generic.h>
+#include <frsh_energy_management.h>
+
+/**********************************/
+/* -----===== FRSH API =====----- */
+/**********************************/
+
+int
+frsh_contract_init(frsh_contract_t *contract)
+{
+ frsh_rel_time_t zero_msec = fosa_msec_to_rel_time(0);
+ if (!contract) return FRSH_ERR_BAD_ARGUMENT;
+
+ *contract = fres_contract_new();
+ if (!(*contract)) goto err;
+
+ /* Set default parameters */
+ frsh_contract_set_resource_and_label(contract,
+ FRSH_RT_PROCESSOR,
+ 0,
+ NULL);
+ frsh_contract_set_basic_params(contract,
+ &zero_msec,
+ &zero_msec,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_REGULAR);
+ return 0;
+err:
+ return errno;
+}
+
+void
+frsh_contract_destroy(frsh_contract_t *contract)
+{
+ if (contract)
+ fres_contract_destroy(*contract);
+}
+
+int frsh_contract_set_basic_params
+ (frsh_contract_t *contract,
+ const frsh_rel_time_t *budget_min,
+ const frsh_rel_time_t *period_max,
+ const frsh_workload_t workload,
+ const frsh_contract_type_t contract_type)
+{
+ fres_block_basic *b;
+ int ret;
+ if (!contract ||
+ !*contract ||
+ !budget_min ||
+ !period_max) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ if ((fosa_rel_time_is_null(*period_max) &&
+ !fosa_rel_time_is_null(*budget_min)) ||
+ (!fosa_rel_time_is_null(*period_max) &&
+ fosa_rel_time_is_null(*budget_min)) ||
+ fosa_rel_time_smaller(*period_max, *budget_min))
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ if (workload != FRSH_WT_BOUNDED &&
+ workload != FRSH_WT_INDETERMINATE)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ if (contract_type != FRSH_CT_REGULAR &&
+ contract_type != FRSH_CT_BACKGROUND &&
+ contract_type != FRSH_CT_DUMMY)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ b = malloc(sizeof(*b));
+ if (!b) return ENOMEM;
+
+ b->budget = *budget_min;
+ b->period = *period_max;
+ b->workload = workload;
+ b->contract_type = contract_type;
+
+ fres_contract_del_basic(*contract);
+ ret = fres_contract_add_basic(*contract, b);
+
+ if (ret) {
+ free(b);
+ return errno;
+ }
+
+ return 0;
+}
+
+int frsh_contract_get_basic_params
+ (const frsh_contract_t *contract,
+ frsh_rel_time_t *budget_min,
+ frsh_rel_time_t *period_max,
+ frsh_workload_t *workload,
+ frsh_contract_type_t *contract_type)
+{
+ fres_block_basic *b;
+
+ if (!contract || !*contract)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ b = fres_contract_get_basic(*contract);
+
+ if (workload)
+ *workload = b->workload;
+ if (budget_min)
+ *budget_min = b->budget;
+ if (period_max)
+ *period_max = b->period;
+ if (contract_type)
+ *contract_type = b->contract_type;
+
+ return 0;
+}
+
+int frsh_contract_set_resource_and_label
+ (frsh_contract_t *contract,
+ const frsh_resource_type_t resource_type,
+ const frsh_resource_id_t resource_id,
+ const frsh_contract_label_t contract_label)
+{
+ fres_block_label *label;
+ fres_block_resource *r;
+ int ret;
+
+ if (!contract || !*contract) return FRSH_ERR_BAD_ARGUMENT;
+
+ r = malloc(sizeof(*r));
+ if (!r) return ENOMEM;
+
+ r->resource_type = resource_type;
+ r->resource_id = resource_id;
+ fres_contract_del_resource(*contract);
+ ret = fres_contract_add_resource(*contract, r);
+
+ if (ret != 0) {
+ free(r);
+ return errno;
+ }
+
+
+ if (contract_label) {
+ label = malloc(sizeof(*label));
+ if (!label) return ENOMEM;
+ strncpy(label->label, contract_label, sizeof(label->label));
+ label->label[sizeof(label->label)-1] = '\0';
+ fres_contract_del_label(*contract);
+ ret = fres_contract_add_label(*contract, label);
+ if (ret) {
+ free(label);
+ return errno;
+ }
+ }
+ return 0;
+}
+
+int frsh_contract_get_resource_and_label
+ (const frsh_contract_t *contract,
+ frsh_resource_type_t *resource_type,
+ frsh_resource_id_t *resource_id,
+ frsh_contract_label_t contract_label)
+{
+ fres_block_resource *r;
+ fres_block_label *label;
+
+ if (!contract || !*contract)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ if (resource_type || resource_id) {
+ r = fres_contract_get_resource(*contract);
+ if (resource_type)
+ *resource_type = r->resource_type;
+ if (resource_id)
+ *resource_id = r->resource_id;
+ }
+
+ if (contract_label) {
+ label = fres_contract_get_label(*contract);
+ strncpy(contract_label, label->label, sizeof(label->label));
+ contract_label[sizeof(label->label)-1] = '\0';
+ }
+
+ return 0;
+}
+
+int frsh_contract_set_timing_reqs
+ (frsh_contract_t *contract,
+ const bool d_equals_t,
+ const frsh_rel_time_t *deadline)
+{
+ int ret;
+ fres_block_timing_reqs *t;
+
+ if (!contract || !*contract)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ if ((d_equals_t && deadline != FRSH_NULL_DEADLINE) ||
+ (!d_equals_t && (deadline == FRSH_NULL_DEADLINE)))
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ t = malloc(sizeof(*t));
+ if (!t) return ENOMEM;
+
+ t->d_equals_t = d_equals_t;
+ if (!d_equals_t) {
+ if (deadline) {
+ t->deadline = *deadline;
+ } else {
+ free(t);
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+ }
+
+ fres_contract_del_timing_reqs(*contract);
+ ret = fres_contract_add_timing_reqs(*contract, t);
+ if (ret) {
+ free(t);
+ return errno;
+ }
+ return 0;
+}
+
+int frsh_contract_get_timing_reqs
+ (const frsh_contract_t *contract,
+ bool *d_equals_t,
+ frsh_rel_time_t *deadline)
+{
+ fres_block_timing_reqs *t;
+
+ if (!contract || !*contract)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ t = fres_contract_get_timing_reqs(*contract);
+
+ if (d_equals_t)
+ *d_equals_t = t->d_equals_t;
+
+ if (deadline)
+ *deadline = t->deadline;
+
+ return 0;
+}
+
+static
+int __contract_check_min_expiration(const frsh_contract_t *contract)
+{
+ fres_block_power_management *p;
+ int ret = 0;
+
+ p = fres_contract_get_power_management(*contract);
+ if (p && !fosa_rel_time_is_null(p->min_expiration)) {
+ frsh_abs_time_t req_time, exp_time;
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, &req_time);
+ req_time = fosa_abs_time_incr(req_time, p->min_expiration);
+
+ ret = frsh_battery_get_expiration(&exp_time);
+ if (ret) goto err;
+
+ if (fosa_abs_time_smaller(exp_time, req_time))
+ ret = FRSH_ERR_CONTRACT_REJECTED;
+ }
+
+err:
+ return ret;
+}
+
+
+int frsh_contract_negotiate
+ (const frsh_contract_t *contract,
+ frsh_vres_id_t *vres)
+{
+ struct forb_env env;
+ int ret;
+ fres_contract_ptr_seq contracts;
+ fres_contract_ptr contracts_buf[1];
+ fres_contract_id_seq *ids;
+ fres_block_resource *r;
+
+ if (!contract || !*contract || !vres) {
+ ret = FRSH_ERR_BAD_ARGUMENT;
+ goto err;
+ }
+
+ /* TODO: Battery time check should be moved to
+ * FCB. Implementation of FRSH API is meant only as a thin
+ * wrapper of FRES framework and the FRES framework could
+ * theoretically be used without FRSH API. Moreover, if there
+ * is some logging mechanism in FCB, this contract rejection
+ * will not be logged. */
+ ret = __contract_check_min_expiration(contract);
+ if (ret) goto err;
+
+ /* Activate allocator */
+ r = fres_contract_get_resource(*contract);
+ if (r) {
+ ret = fra_activate(r->resource_type,
+ r->resource_id);
+ if (ret) goto err;
+ }
+
+ /* Negotiate contract */
+ contracts_buf[0] = *contract;
+ contracts._buffer = contracts_buf;
+ contracts._length = contracts._maximum = 1;
+ ret = fres_contract_broker_negotiate_contracts(frsh_forb_global.fcb,
+ &contracts,
+ &ids, &env);
+ if (forb_exception_occurred(&env)) {
+ ret = fres_forbex2err(&env);
+ goto err;
+ }
+
+ if (ret == 0) {
+ assert(ids->_length == 1);
+ *vres = fra_get_vres(&ids->_buffer[0]);
+ assert(*vres != NULL);
+ }
+ if (CORBA_sequence_get_release(ids))
+ CORBA_free(ids->_buffer);
+ CORBA_free(ids);
+
+err:
+ return ret;
+}
+
+int frsh_contract_cancel (const frsh_vres_id_t vres)
+{
+ int ret;
+ struct forb_env env;
+ struct fres_contract *empty_contract;
+ fres_contract_ptr_seq contracts;
+ fres_contract_id_seq *ids;
+
+ if (!vres) {
+ ret = FRSH_ERR_BAD_ARGUMENT;
+ goto err;
+ }
+
+ empty_contract = fres_contract_new();
+ empty_contract->id = vres->id;
+
+ contracts._buffer = &empty_contract;
+ contracts._length = contracts._maximum = 1;
+ ret = fres_contract_broker_negotiate_contracts(frsh_forb_global.fcb,
+ &contracts,
+ &ids, &env);
+ if (forb_exception_occurred(&env)) {
+ ret = fres_forbex2err(&env);
+ goto err;
+ }
+
+ /* The returned ID is the same as of vres */
+ if (CORBA_sequence_get_release(ids))
+ CORBA_free(ids->_buffer);
+ CORBA_free(ids);
+err:
+ return ret;
+}
+
+int frsh_contract_renegotiate_sync
+ (const frsh_contract_t *new_contract,
+ frsh_vres_id_t vres_id)
+{
+ struct forb_env env;
+ struct fres_contract *contract;
+ int ret = 0;
+ fres_contract_ptr contracts_buf[1];
+ fres_contract_ptr_seq contracts;
+ fres_contract_id_seq *ids;
+
+ if (!new_contract || !*new_contract || !vres_id) {
+ ret = FRSH_ERR_BAD_ARGUMENT;
+ goto out;
+ }
+
+ ret = __contract_check_min_expiration(new_contract);
+ if (ret) goto out;
+
+ contract = fres_contract_duplicate(*new_contract);
+ if (!contract) {
+ ret = errno;
+ goto out;
+ }
+
+ /* Assign the ID, so that FCB recognises that this is
+ * renegotiation */
+ contract->id = vres_id->id;
+
+ /* Renegotiate with FCB contract */
+ contracts_buf[0] = contract;
+ contracts._buffer = contracts_buf;
+ contracts._length = contracts._maximum = 1;
+ ret = fres_contract_broker_negotiate_contracts(frsh_forb_global.fcb,
+ &contracts,
+ &ids, &env);
+ if (forb_exception_occurred(&env)) {
+ ret = fres_forbex2err(&env);
+ goto err;
+ }
+
+ if (CORBA_sequence_get_release(ids))
+ CORBA_free(ids->_buffer);
+ CORBA_free(ids);
+err:
+ fres_contract_destroy(contract);
+out:
+ return ret;;
+}
+
+int frsh_contract_renegotiate_async
+ (const frsh_contract_t *new_contract,
+ frsh_vres_id_t vres,
+ frsh_signal_t signal_to_notify,
+ frsh_signal_info_t signal_info)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_group_change_mode_sync
+ (const frsh_contracts_group_t *contracts_to_neg,
+ const frsh_contracts_group_t *contracts_to_reneg,
+ const frsh_vres_group_t *vres_to_reneg,
+ const frsh_vres_group_t *vres_to_cancel,
+ frsh_vres_group_t *new_vres)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_group_change_mode_async
+ (const frsh_contracts_group_t *contracts_to_neg,
+ const frsh_contracts_group_t *contracts_to_reneg,
+ const frsh_vres_group_t *vres_to_reneg,
+ const frsh_vres_group_t *vres_to_cancel,
+ const frsh_signal_t signal,
+ const frsh_signal_info_t signal_info,
+ frsh_group_id_t *group)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file frsh_core.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * Dario Faggioli <faggioli@gandalf.sssup.it>
+ * @date Wed Feb 18 16:04:22 2009
+ *
+ * @brief Core of FRSH_FORB framework
+ *
+ */
+
+
+#include <frsh_core.h>
+#include <fcb.h>
+#include <forb.h>
+#include <fra_generic.h>
+#include "frsh_forb.h"
+#include <frsh_resources.h>
+
+#if FRSH_DISTRIBUTED_MODULE_SUPPORTED
+#include <frsh_distributed.h>
+#endif
+
+#ifdef CONFIG_AQUOSA
+#include <aqcpu_res.h>
+#endif
+
+#ifdef CONFIG_CPUCG
+#include <cpucg_res.h>
+#endif
+
+#ifdef CONFIG_DISKBFQ
+#include <diskbfq_res.h>
+#endif
+
+#ifdef CONFIG_RESOURCE_DUMMY
+#include <res_dummy.h>
+#endif
+
+#ifdef CONFIG_RESOURCE_ITEM
+#include <item.h>
+#endif
+
+struct frsh_forb frsh_forb_global;
+
+static void *alloc_executor_thread(void *arg)
+{
+ return (void*)(uintptr_t)forb_executor_run(&frsh_forb_global.alloc_executor);
+}
+
+
+int frsh_init()
+{
+ int ret;
+ struct forb_init_attr attr = {
+ .orb_id = "org.frescor.frsh_app"
+ };
+
+ frsh_forb_global.orb = forb_init(NULL, NULL, &attr);
+ if (!frsh_forb_global.orb) {
+ ret = errno;
+ goto err;
+ }
+
+ frsh_forb_global.fcb = forb_resolve_reference(frsh_forb_global.orb,
+ fres_contract_broker_reg_name);
+ if (!frsh_forb_global.fcb) {
+ ret = FRES_ERR_FCB_NOT_RUNNING;
+ goto err;
+ }
+
+ /* Initialize resource allocators */
+ ret = forb_executor_init(&frsh_forb_global.alloc_executor);
+ if (ret) goto err;
+
+ ret = fra_registry_init(frsh_forb_global.orb, frsh_forb_global.fcb,
+ &frsh_forb_global.alloc_executor);
+ if (ret) goto err;
+
+#ifdef CONFIG_AQUOSA
+ ret = aqcpu_fra_init();
+ if (ret) goto err;
+#endif
+#ifdef CONFIG_CPUCG
+ ret = cpucg_fra_init();
+ if (ret) goto err;
+#endif
+#ifdef CONFIG_RESOURCE_DUMMY
+ ret = fra_dummy_init();
+ if (ret) goto err;
+#endif
+
+#ifdef CONFIG_DISKBFQ
+ ret = diskbfq_fra_init();
+ if (ret) goto err;
+#endif
+
+#if FRSH_DISTRIBUTED_MODULE_SUPPORTED
+ ret = frsh_distributed_init();
+ if (ret) goto err;
+#endif
+
+#ifdef CONFIG_RESOURCE_ITEM
+ ret = fra_item_init();
+ if (ret) goto err;
+#endif
+ /* Run resource allocators */
+ fosa_thread_create(&frsh_forb_global.alloc_executor_thread, NULL,
+ alloc_executor_thread, NULL);
+
+ return 0;
+err:
+ if (ret == -1) ret = errno;
+ return ret;
+}
+
+void frsh_destroy()
+{
+ pthread_cancel(frsh_forb_global.alloc_executor_thread.pthread_id);
+ pthread_join(frsh_forb_global.alloc_executor_thread.pthread_id, NULL);
+
+ forb_destroy(frsh_forb_global.orb);
+ /* TODO: Destroy all FRAs etc. */
+}
+
+
+
+bool frsh_config_is_admission_test_enabled()
+{
+ return true;
+}
+
+frsh_resource_id_t frsh_get_local_cpu_id(void)
+{
+ long int ret = FRSH_CPU_ID_DEFAULT;
+ if (getenv("FRSH_CPU_ID")) {
+ errno = 0; /* See strtol(1) */
+ ret = strtol(getenv("FRSH_CPU_ID"), NULL, 10);
+ if (errno != 0)
+ ret = FRSH_CPU_ID_DEFAULT;
+ }
+ return ret;
+}
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2008 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+//
+//
+
+#include <frsh.h>
+/* #include <frsh_internal.h> */
+
+#if FRSH_DISTRIBUTED_MODULE_SUPPORTED
+
+#include "fosa.h"
+#include "fna_configuration.h" // for fna_operations, FNA_MAX_NETWORKS
+//#include "frsh_debug_and_trace.h" // for FRSH_TRACE
+#include <string.h>
+
+#define FRSH_ENDPOINT_SIZE sizeof(fna_endpoint_data_t)
+
+static inline void* endpoint_alloc()
+{
+ return calloc(1, FRSH_ENDPOINT_SIZE);
+}
+
+static inline void endpoint_free(void* endpoint)
+{
+ return free(endpoint);
+}
+
+//-------------------------//
+// check_valid_resource_id //
+//-------------------------//
+// Internal function to check that a given resource_id is valid
+
+static inline int check_valid_resource_id (const frsh_resource_id_t resource_id)
+{
+ if (resource_id >= FNA_MAX_NETWORKS || resource_id < 0) {
+ return FRSH_ERR_RESOURCE_ID_INVALID;
+ }
+
+ if (fna_operations[resource_id] == NULL) {
+ return FRSH_ERR_RESOURCE_ID_INVALID;
+ }
+
+ return 0;
+}
+
+//---------------------------//
+// check_valid_send_endpoint //
+//---------------------------//
+// Internal function to check that a given send_endpoint is valid. if it is
+// valid it returns the position, if not it returns -1
+
+static inline int check_valid_send_endpoint(frsh_send_endpoint_t endpoint)
+{
+ if ((!endpoint) || (endpoint->endpoint_type != FRSH_SEND_ENDPOINT_TYPE)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+//------------------------------//
+// check_valid_receive_endpoint //
+//------------------------------//
+// Internal function to check that a given receive_endpoint is valid. if it is
+// valid it returns the position, if not it returns -1
+
+static inline int check_valid_receive_endpoint(frsh_receive_endpoint_t endpoint)
+{
+ if ((!endpoint) || (endpoint->endpoint_type != FRSH_RECEIVE_ENDPOINT_TYPE)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+//-----------------------//
+// frsh_distributed_init //
+//-----------------------//
+// TODO: use a flag to say if it is initialized or not
+
+int frsh_distributed_init(void)
+{
+ frsh_resource_id_t id = 0;
+ int err = 0;
+
+ // execute the fna_init operation of each installed network
+ for (id=0; id<FNA_MAX_NETWORKS; id++) {
+ if (fna_operations[id] != NULL) {
+ //FRSH_TRACE(FRSH_TRACE_DISTRIBUTED, "init network id=%d\n", id);
+ if (!fna_operations[id]->fna_init) continue;
+ err = fna_operations[id]->fna_init(id);
+ if (err != 0) return -1;
+ }
+ }
+
+ // initialize the freelist to handle the set of endpoints
+ //FRSH_TRACE(FRSH_TRACE_DISTRIBUTED, "init endpoints freelist\n");
+
+ return 0;
+}
+
+//-----------------------------------//
+// frsh_network_get_max_message_size //
+//-----------------------------------//
+
+int frsh_network_get_max_message_size
+ (const frsh_resource_id_t resource_id,
+ const frsh_network_address_t destination,
+ size_t *max_size)
+{
+ if (check_valid_resource_id(resource_id)) {
+ return FRSH_ERR_RESOURCE_ID_INVALID;
+ }
+
+ if (fna_operations[resource_id]->fna_network_get_max_message_size == NULL) {
+ return FRSH_ERR_INTERNAL_ERROR;
+ }
+
+ return fna_operations[resource_id]->fna_network_get_max_message_size
+ (resource_id, destination, max_size);
+}
+
+//------------------------------//
+// frsh_network_bytes_to_budget //
+//------------------------------//
+
+int frsh_network_bytes_to_budget
+ (const frsh_resource_id_t resource_id,
+ const size_t nbytes,
+ frsh_rel_time_t *budget)
+{
+ if (check_valid_resource_id(resource_id)) {
+ return FRSH_ERR_RESOURCE_ID_INVALID;
+ }
+
+ if (fna_operations[resource_id]->fna_network_bytes_to_budget == NULL) {
+ return FRSH_ERR_INTERNAL_ERROR;
+ }
+
+ return fna_operations[resource_id]->fna_network_bytes_to_budget
+ (resource_id, nbytes, budget);
+}
+
+//------------------------------//
+// frsh_network_budget_to_bytes //
+//------------------------------//
+
+int frsh_network_budget_to_bytes
+ (const frsh_resource_id_t resource_id,
+ const frsh_rel_time_t *budget,
+ size_t *nbytes)
+{
+ if (check_valid_resource_id(resource_id)) {
+ return FRSH_ERR_RESOURCE_ID_INVALID;
+ }
+
+ if (fna_operations[resource_id]->fna_network_budget_to_bytes == NULL) {
+ return FRSH_ERR_INTERNAL_ERROR;
+ }
+
+ return fna_operations[resource_id]->fna_network_budget_to_bytes
+ (resource_id, budget, nbytes);
+}
+
+//---------------------------------------//
+// frsh_network_get_min_effective_budget //
+//---------------------------------------//
+
+int frsh_network_get_min_effective_budget
+ (const frsh_resource_id_t resource_id,
+ frsh_rel_time_t *budget)
+{
+ if (check_valid_resource_id(resource_id)) {
+ return FRSH_ERR_RESOURCE_ID_INVALID;
+ }
+
+ if (fna_operations[resource_id]->fna_network_get_min_eff_budget == NULL) {
+ return FRSH_ERR_INTERNAL_ERROR;
+ }
+
+ return fna_operations[resource_id]->fna_network_get_min_eff_budget
+ (resource_id, budget);
+}
+
+//---------------------------//
+// frsh_send_endpoint_create //
+//---------------------------//
+
+int frsh_send_endpoint_create
+ (frsh_resource_id_t resource_id,
+ frsh_network_address_t destination,
+ frsh_stream_id_t stream_id,
+ frsh_send_endpoint_protocol_info_t protocol_info,
+ frsh_send_endpoint_t *endpoint)
+{
+ frsh_send_endpoint_t epoint;
+
+ if (check_valid_resource_id(resource_id)) {
+ return FRSH_ERR_RESOURCE_ID_INVALID;
+ }
+
+ if (endpoint == NULL) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ // allocate a free endpoint position in the table
+ epoint = endpoint_alloc();
+
+ if (epoint == NULL) {
+ return FRSH_ERR_NO_SPACE;
+ }
+
+ // initialize the send endpoint
+ epoint->endpoint_type = FRSH_SEND_ENDPOINT_TYPE;
+ epoint->resource_id = resource_id;
+ epoint->destination = destination;
+ epoint->stream_id = stream_id;
+ epoint->endpoint_protocol_info.send = protocol_info;
+ epoint->is_bound = false;
+ /*FRSH_TRACE(FRSH_TRACE_DISTRIBUTED,"%s:stream_id=%d\n", __func__, stream_id);*/
+
+ *endpoint = epoint;
+ if (fna_operations[resource_id]->fna_send_endpoint_created) {
+ return fna_operations[resource_id]->fna_send_endpoint_created(epoint);
+ }
+ else
+ return 0;
+}
+
+// int frsh_contract_set_queueing_info(frsh_endpoint_queueing_info_t queueing_info,
+// frsh_contract_t *contract);
+//
+// int frsh_contract_get_queueing_info(const frsh_contract_t *contract,
+// frsh_endpoint_queueing_info_t *queueing_info);
+//
+// int frsh_contract_set_protocol_info(frsh_protocol_info_t protocol_info,
+// frsh_contract_t *contract);
+//
+// int frsh_contract_get_protocol_info(frsh_contract_t *contract,
+// frsh_protocol_info_t *protocol_info);
+//
+
+
+//-------------------------------//
+// frsh_send_endpoint_get_params //
+//-------------------------------//
+
+int frsh_send_endpoint_get_params
+ (const frsh_send_endpoint_t endpoint,
+ frsh_resource_id_t *resource_id,
+ frsh_network_address_t *destination,
+ frsh_stream_id_t *stream,
+ frsh_send_endpoint_protocol_info_t *protocol_info)
+{
+ if (check_valid_send_endpoint(endpoint) < 0) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ if (resource_id)
+ *resource_id = endpoint->resource_id;
+ if (destination)
+ *destination = endpoint->destination;
+ if (stream)
+ *stream = endpoint->stream_id;
+ if (protocol_info)
+ *protocol_info = endpoint->endpoint_protocol_info.send;
+
+ return 0;
+}
+//----------------------------//
+// frsh_send_endpoint_destroy //
+//----------------------------//
+
+int frsh_send_endpoint_destroy
+ (frsh_send_endpoint_t endpoint)
+{
+ fna_endpoint_data_t *epoint = endpoint;
+ int rv;
+
+ if (check_valid_send_endpoint(endpoint) < 0) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ if (fna_operations[epoint->resource_id]->fna_endpoint_destroy) {
+ rv = fna_operations[epoint->resource_id]->\
+ fna_endpoint_destroy(endpoint);
+ if (rv)
+ return rv;
+ }
+
+ endpoint_free(endpoint);
+ return 0;
+}
+
+//-------------------------//
+// frsh_send_endpoint_bind //
+//-------------------------//
+
+int frsh_send_endpoint_bind
+ (frsh_vres_id_t vres,
+ frsh_send_endpoint_t endpoint)
+{
+ if (check_valid_send_endpoint(endpoint) < 0) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ // TODO: check that resource_id and resource_type matches
+ endpoint->vres = vres;
+ endpoint->is_bound = true;
+ /*FRSH_TRACE(FRSH_TRACE_DISTRIBUTED,"%s:vres=%d\n", __func__,
+ endpoint_data[pos].vres);*/
+
+ if (fna_operations[endpoint->resource_id]->fna_send_endpoint_bind) {
+ return fna_operations[endpoint->resource_id]->\
+ fna_send_endpoint_bind(endpoint,vres);
+ }
+ else
+ return 0;
+}
+
+//---------------------------//
+// frsh_send_endpoint_unbind //
+//---------------------------//
+
+int frsh_send_endpoint_unbind
+ (frsh_send_endpoint_t endpoint)
+{
+ if (check_valid_send_endpoint(endpoint) < 0) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ endpoint->is_bound = false;
+
+ if (fna_operations[endpoint->resource_id]->fna_send_endpoint_unbind) {
+ return fna_operations[endpoint->resource_id]->\
+ fna_send_endpoint_unbind(endpoint);
+ }
+ else
+ return 0;
+}
+
+//--------------------------------//
+// frsh_send_endpoint_get_vres_id //
+//--------------------------------//
+
+int frsh_send_endpoint_get_vres_id
+ (const frsh_send_endpoint_t endpoint,
+ frsh_vres_id_t *vres)
+{
+ if (check_valid_send_endpoint(endpoint) < 0) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ if (vres)
+ *vres = endpoint->vres;
+ return 0;
+}
+
+//-----------------//
+// frsh_send_async //
+//-----------------//
+
+int frsh_send_async
+ (const frsh_send_endpoint_t endpoint,
+ const void *msg,
+ const size_t size)
+{
+ frsh_resource_id_t resource_id;
+
+ if (check_valid_send_endpoint(endpoint) < 0) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ if (endpoint->is_bound == false) {
+ return FRSH_ERR_NOT_BOUND;
+ }
+
+ resource_id = endpoint->resource_id;
+
+ if (fna_operations[resource_id]->fna_send_async == NULL) {
+ return FRSH_ERR_INTERNAL_ERROR;
+ }
+
+ return fna_operations[resource_id]->fna_send_async
+ (endpoint, msg, size);
+}
+
+//-----------------//
+// frsh_send_sync //
+//-----------------//
+
+int frsh_send_sync
+ (const frsh_send_endpoint_t endpoint,
+ const void *msg,
+ const size_t size)
+{
+ frsh_resource_id_t resource_id;
+
+ if (check_valid_send_endpoint(endpoint) < 0) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ if (endpoint->is_bound == false) {
+ return FRSH_ERR_NOT_BOUND;
+ }
+
+ resource_id = endpoint->resource_id;
+
+ if (fna_operations[resource_id]->fna_send_sync == NULL) {
+ return FRSH_ERR_INTERNAL_ERROR;
+ }
+
+ return fna_operations[resource_id]->fna_send_sync
+ (endpoint, msg, size);
+}
+
+// int frsh_send_endpoint_get_status(const frsh_send_endpoint_t endpoint,
+// int *number_pending_msg,
+// frsh_endpoint_network_status_t *network_status,
+// frsh_protocol_status_t *protocol_status);
+//
+
+//------------------------------//
+// frsh_receive_endpoint_create //
+//------------------------------//
+
+int frsh_receive_endpoint_create
+ (frsh_resource_id_t resource_id,
+ frsh_stream_id_t stream_id,
+ frsh_endpoint_queueing_info_t queueing_info,
+ frsh_receive_endpoint_protocol_info_t protocol_info,
+ frsh_receive_endpoint_t *endpoint)
+{
+ frsh_receive_endpoint_t epoint;
+
+ if (check_valid_resource_id(resource_id)) {
+ return FRSH_ERR_RESOURCE_ID_INVALID;
+ }
+
+ if (endpoint == NULL) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ if ((epoint = endpoint_alloc()) == NULL) {
+ return FRSH_ERR_NO_SPACE;
+ }
+
+ // initialize the receive_endpoint
+ epoint->endpoint_type = FRSH_RECEIVE_ENDPOINT_TYPE;
+ epoint->resource_id = resource_id;
+ epoint->stream_id = stream_id;
+ epoint->queue_info = queueing_info;
+ epoint->endpoint_protocol_info.receive = protocol_info;
+
+ //FRSH_TRACE(FRSH_TRACE_DISTRIBUTED,"%s:stream_id=%d\n", __func__, stream_id);
+ // the receive_endpoint identifier for the user is the position in the table
+ *endpoint = epoint;
+
+ if (fna_operations[resource_id]->fna_receive_endpoint_created) {
+ return fna_operations[resource_id]->\
+ fna_receive_endpoint_created(epoint);
+ }
+ else
+ return 0;
+}
+
+//----------------------------------//
+// frsh_receive_endpoint_get_params //
+//----------------------------------//
+
+int frsh_receive_endpoint_get_params
+ (const frsh_receive_endpoint_t endpoint,
+ frsh_resource_id_t *resource_id,
+ frsh_stream_id_t *stream,
+ frsh_endpoint_queueing_info_t *queueing_info,
+ frsh_receive_endpoint_protocol_info_t *protocol_info)
+{
+ if (check_valid_receive_endpoint(endpoint) < 0) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ if (resource_id)
+ *resource_id = endpoint->resource_id;
+ if (stream)
+ *stream = endpoint->stream_id;
+ if (queueing_info)
+ *queueing_info = endpoint->queue_info;
+ if (protocol_info)
+ *protocol_info = endpoint->endpoint_protocol_info.receive;
+
+ return 0;
+}
+
+//-------------------------------//
+// frsh_receive_endpoint_destroy //
+//-------------------------------//
+
+int frsh_receive_endpoint_destroy
+ (frsh_receive_endpoint_t endpoint)
+{
+ fna_endpoint_data_t *epoint = endpoint;
+ int rv;
+
+ if (check_valid_receive_endpoint(endpoint) < 0) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ if (fna_operations[epoint->resource_id]->fna_endpoint_destroy) {
+ rv = fna_operations[epoint->resource_id]->\
+ fna_endpoint_destroy(endpoint);
+ if (rv)
+ return rv;
+ }
+
+ endpoint_free(endpoint);
+ return 0;
+}
+
+//-------------------//
+// frsh_receive_sync //
+//-------------------//
+
+int frsh_receive_sync
+ (const frsh_receive_endpoint_t endpoint,
+ void *buffer,
+ size_t buffer_size,
+ size_t *message_size,
+ frsh_network_address_t *from)
+{
+ frsh_resource_id_t resource_id;
+
+ if (check_valid_receive_endpoint(endpoint) < 0) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ resource_id = endpoint->resource_id;
+
+ if (fna_operations[resource_id]->fna_receive_sync == NULL) {
+ return FRSH_ERR_INTERNAL_ERROR;
+ }
+
+ return fna_operations[resource_id]->fna_receive_sync
+ (endpoint, buffer, buffer_size, message_size, from);
+}
+
+//
+// int frsh_receive_async
+// (const frsh_receive_endpoint_t endpoint,
+// void *buffer,
+// size_t buffer_size,
+// size_t *message_size,
+// frsh_network_address_t *from);
+//
+// int frsh_receive_endpoint_get_status(const frsh_receive_endpoint_t endpoint,
+// int *number_pending_messages,
+// frsh_endpoint_network_status_t *network_status,
+// frsh_protocol_status_t *protocol_status);
+
+#endif /* FRSH_DISTRIBUTED_MODULE_SUPPORTED */
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2008 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH (FRescor ScHeduler)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+#include <stdio.h>
+#include <string.h>
+
+#include <frsh.h>
+#include <fres_error.h>
+
+
+////////////////////////////////////////////////////////////////////////
+// ERROR REPORTING
+////////////////////////////////////////////////////////////////////////
+
+/* Use to debug an error condition */
+/***********************************/
+int global_error_condition = 0;
+
+
+
+/* These variables get initialised in frsh_init() */
+/**************************************************/
+fosa_abs_time_t frsh_trace_init_timespec;
+long frsh_trace_init_timemsec = -1;
+
+
+//error codes to message section
+static const int frsh_strerror_table_size = FRSH_ERR_LAST_VALUE-FRSH_ERR_BASE_VALUE;
+static char * frsh_strerror_table[] =
+{
+ "TOO_MANY_TASKS ",
+ "BAD_ARGUMENT ",
+ "INVALID_SYNCH_OBJ_HANDLE ",
+ "NO_RENEGOTIATION_REQUESTED ",
+ "CONTRACT_REJECTED ",
+ "NOT_SCHEDULED_CALLING_THREAD ",
+ "NOT_BOUND_THREAD ",
+ "UNKNOWN_SCHEDULED_THREAD ",
+ "NOT_CONTRACTED_SERVER ",
+ "NOT_SCHEDULED_THREAD ",
+ "TOO_MANY_SERVICE_JOBS ",
+ "TOO_MANY_SYNCH_OBJS ",
+ "TOO_MANY_SERVERS_IN_SYNCH_OBJ ",
+ "TOO_MANY_EVENTS_IN_SYNCH_OBJ ",
+ "INTERNAL_ERROR ",
+ "TOO_MANY_SERVERS ",
+ "INVALID_SCHEDULER_REPLY ",
+ "TOO_MANY_PENDING_REPLENISHMENTS",
+ "SYSTEM_ALREADY_INITIALIZED ",
+ "SHARED_OBJ_ALREADY_INITIALIZED ",
+ "SHARED_OBJ_NOT_INITIALIZED ",
+ "SCHED_POLICY_NOT_COMPATIBLE ",
+ "SERVER_WORKLOAD_NOT_COMPATIBLE ",
+ "ALREADY_BOUND ",
+ "RESOURCE_ID_INVALID ",
+ "TOO_LARGE ",
+ "BUFFER_FULL ",
+ "NO_SPACE ",
+ "NO_MESSAGES ",
+ "MODULE_NOT_SUPPORTED ",
+ "SYSTEM_NOT_INITIALIZED ",
+ "TOO_MANY_SHARED_OBJS ",
+ "CONTRACT_LABEL_ALREADY_EXISTS ",
+ "BUDGET_EXPIRED ",
+ "SHARED_OBJECT_NOT_PROTECTED ",
+ "NOT_IMPLEMENTED ",
+ "CONTRACT_TYPE_NOT_COMPATIBLE ",
+ "CAPACITY_NOT_DECREASING ",
+ "CONTRACT_LABEL_UNKNOWN "
+};
+
+
+
+/**
+ * frsh_strerror()
+ *
+ * This function converts an error code to an error message that is
+ * stored in the buffer starting at the location pointed to by
+ * message. The size of this buffer is specified by the size
+ * argument. If the error message is longer than size-1, it is
+ * truncated to that length. Regardless of whether the message is
+ * truncated or not, a final zero character that marks the end of the
+ * string is stored in the buffer. The function fails if the error
+ * code passed does not correspond to any of the frsh error codes.
+ * [@return:
+ * FRSH_ERR_BAD_ARGUMENT : error is not a valid value
+ * ]
+ **/
+int frsh_strerror (int error, char *message, size_t size)
+{
+ char *s;
+ int ret;
+
+ ret = fres_strerror(error, message, size);
+ if (ret == 0) return 0;
+
+ if ((error > FRSH_ERR_LAST_VALUE) ||
+ (error <= FRSH_ERR_BASE_VALUE))
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ s = frsh_strerror_table[error - FRSH_ERR_BASE_VALUE -1];
+
+ if ( message != NULL && size > 0) {
+ strncpy(message, s, size);
+ message[size-1] = '\0';
+ }
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------------------ */
+void my_frsh_strerror(int error, char *sss)
+{
+ char s[32];
+ frsh_strerror(error, s, 32);
+ printf("(%x ", error);
+ printf(s);
+ printf(") ");
+ printf(sss);
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file frsh_feedback.c
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ * @date Wed Feb 20 14:53:22 2009
+ *
+ * @brief Feedback module of FRSH_FORB framework
+ *
+ */
+
+#include <frsh_core.h>
+#include <fra_generic.h>
+#include "frsh_forb.h"
+#include <frsh_resources.h>
+
+#ifdef CONFIG_AQUOSA
+#include <aqcpu_res.h>
+#endif
+#ifdef CONFIG_CPUCG
+#include <cpucg_res.h>
+#endif
+#ifdef CONFIG_DISKBFQ
+#include <diskbfq_res.h>
+#endif
+
+static frsh_vres_id_t spare_vres;
+
+int frsh_feedback_get_spare(frsh_contract_t *spare_contract)
+{
+ return frsh_vres_get_contract(spare_vres, spare_contract);
+}
+
+int frsh_feedback_set_spare
+ (const frsh_contract_t *spare_contract)
+{
+ int ret = 0;
+ frsh_vres_id_t spare_vres;
+
+ if (!spare_contract || !*spare_contract)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ ret = frsh_contract_negotiate(spare_contract, &spare_vres);
+ if (ret) return ret;
+
+
+ if (spare_vres->allocator->set_spare_bandwidth) {
+ ret = spare_vres->allocator->set_spare_bandwidth(spare_vres);
+ } else {
+ ret = FRSH_ERR_NOT_IMPLEMENTED;
+ }
+
+ return ret;
+}
+
+int frsh_feedback_get_desired_budget
+ (frsh_vres_id_t vres_id,
+ frsh_rel_time_t *p_budget_out)
+{
+ if (vres_id->allocator->get_desired_budget) {
+ return vres_id->allocator->get_desired_budget(vres_id, p_budget_out);
+ } else {
+ return FRSH_ERR_NOT_IMPLEMENTED;
+ }
+}
+
+int frsh_feedback_set_desired_budget
+ (frsh_vres_id_t vres_id,
+ frsh_rel_time_t *p_budget_in)
+{
+ if (vres_id->allocator->set_desired_budget) {
+ return vres_id->allocator->set_desired_budget(vres_id, p_budget_in);
+ } else {
+ return FRSH_ERR_NOT_IMPLEMENTED;
+ }
+}
+
+int frsh_feedback_get_actual_budget
+ (frsh_vres_id_t vres_id,
+ frsh_rel_time_t *budget)
+{
+ if (vres_id->allocator->get_actual_budget) {
+ return vres_id->allocator->get_actual_budget(vres_id, budget);
+ } else {
+ return FRSH_ERR_NOT_IMPLEMENTED;
+ }
+}
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file frsh_forb.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Wed Feb 18 16:05:12 2009
+ *
+ * @brief Internal declaration for FRSH_FORB framework
+ *
+ *
+ */
+
+
+#ifndef FRSH_FORB_H
+#define FRSH_FORB_H
+
+#include <forb.h>
+#include <fcb.h>
+#include <fosa.h>
+
+/** Global FRSH_FORB variables */
+struct frsh_forb {
+ forb_orb orb; /**< ORB used to communicate with contract broker */
+ fres_contract_broker fcb; /**< Contract broker object referemce */
+ forb_executor_t alloc_executor; /**< Executor to execute allocators */
+ fosa_thread_id_t alloc_executor_thread; /**< Thread to run @a alloc_executor */
+};
+
+extern struct frsh_forb frsh_forb_global;
+
+#endif
--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2008 FRESCOR consortium partners:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politécnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org for a link to partners' websites
+//
+// FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// FSF API web pages: http://marte.unican.es/fsf/docs
+// http://shark.sssup.it/contrib/first/docs/
+//
+// This file is part of FRSH_FORB (FRescor ScHeduler based on FORB)
+//
+// FRSH is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FRSH is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FRSH; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FRSH header files in a file,
+// instantiating FRSH generics or templates, or linking other files
+// with FRSH objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//frsh_opaque_types.h
+//==============================================
+// ******** ******* ******** ** **
+// **///// /**////** **////// /** /**
+// ** /** /** /** /** /**
+// ******* /******* /********* /**********
+// **//// /**///** ////////** /**//////**
+// ** /** //** /** /** /**
+// ** /** //** ******** /** /**
+// // // // //////// // //
+//
+// FRSH(FRescor ScHeduler), pronounced "fresh"
+//==============================================
+
+// Implementation dependent definitions
+#ifndef _FRSH_OPAQUE_TYPES_H_
+#define _FRSH_OPAQUE_TYPES_H_
+
+#include <fres_contract_type.h>
+#include <fres_synchobj.h>
+#include <frsh_cpp_macros.h>
+#include <fres_error.h>
+
+FRSH_CPP_BEGIN_DECLS
+
+/// Mark that we are using different FRSH implementation
+#define FRSH_FORB 1
+
+/**
+ * @file frsh_opaque_types.h
+ **/
+
+/**
+ * @defgroup opaque Opaque types
+ *
+ * This module specifies some #defines for privates types in the
+ * interface. In this way we warn the FRSH user never to access the internal
+ * members of the types directly allowing us to change their internal
+ * definitions to suit our needs.
+ *
+ * Note that in Ada the FRSH user would never be allowed to access the
+ * members directly, however in C the compiler does not prevent this.
+ * But this is the best we can do in this language.
+ *
+ * @{
+ **/
+
+struct fres_vres;
+#define FRSH_VRES_ID_T_OPAQUE struct fres_vres *
+
+/** frsh_contract_parameters_t **/
+#define FRSH_CONTRACT_T_OPAQUE fres_contract_ptr
+
+
+#define FRSH_SYNCHOBJ_HANDLE_T_OPAQUE struct fres_synchobj *
+
+#define FRSH_SHAREDOBJ_HANDLE_T_OPAQUE struct fres_sharedobj *
+
+typedef unsigned int FRSH_GROUP_ID_T_OPAQUE;
+
+
+/**
+ * Critical section runtime data
+ * - comon parameters
+ * op_kind; // kind of operation (READ or WRITE)
+ * obj_label; // label of the shared object
+ * wcet; // Execution time
+ * blocking; // Blocking time (execution time + protection overheads)
+ *
+ **/
+#define FRSH_CSECT_RUNTIME_T_OPAQUE struct { \
+ frsh_csect_op_kind_t op_kind; \
+ frsh_sharedobj_label_t obj_label; \
+ frsh_rel_time_t wcet; \
+ frsh_rel_time_t blocking; \
+}
+
+/**
+ * Critical section data
+ * - runtime parameters
+ * runtime; //
+ * - attributes used only for protected shared objects
+ * op; // pointer to the operation
+ * - attributes used only for protected write operations
+ * areas; // memory areas to be protected
+ *
+ **/
+#define FRSH_CSECT_T_OPAQUE struct { \
+ frsh_csect_op_kind_t op_kind; \
+ frsh_sharedobj_label_t obj_label; \
+ frsh_rel_time_t wcet; \
+ frsh_rel_time_t blocking; \
+ frsh_csect_op_t op; \
+ frsh_memory_areas_t areas; \
+}
+
+struct fna_endpoint_data;
+
+//opaque types for frsh endpoints
+typedef struct fna_endpoint_data* FRSH_SEND_ENDPOINT_T_OPAQUE;
+typedef struct fna_endpoint_data* FRSH_RECEIVE_ENDPOINT_T_OPAQUE;
+
+/*@}*/
+
+FRSH_CPP_END_DECLS
+
+#endif // _FRSH_OPAQUE_TYPES_H_
--- /dev/null
+/**
+ * @file frsh_power.c
+ * @author Michael Trimarchi <trimarchimichael@yahoo.it>
+ * Dario Faggioli <faggioli@gandalf.sssup.it>
+ *
+ * @brief FRSH core thread related functions not implamented in managers..
+ *
+ *
+ */
+
+#include <string.h>
+
+#include <fres_contract.h>
+#include <fres_contract_idl.h>
+#include <fres_blocks.h>
+#include <fcb.h>
+#include <fra_generic.h>
+#include <frsh_forb.h>
+#include "frsh_resources.h"
+#ifdef CONFIG_ACPI_CPU
+# include <fra_acpi_cpu.h>
+#endif
+#ifdef CONFIG_ACPI_BATTERY
+# include "fra_acpi_battery.h"
+#endif
+#ifdef CONFIG_ACPI_LCD
+# include <fra_acpi_lcd.h>
+#endif
+#include <frsh.h>
+
+static inline int __is_a_valid_power(int level)
+{
+ if (level >= 0 && level < 3 )
+ return 1;
+
+ return 0;
+}
+
+static inline
+fres_block_power_management *__dup_power_management(frsh_contract_t *contract)
+{
+ fres_block_power_management *p, *old_p;
+
+ old_p = fres_contract_get_power_management(*contract);
+ p = malloc(sizeof(*p));
+ if (!p) return 0;
+ /**
+ * Needed since frsh_contract_del_xxx frees the
+ * old block.
+ **/
+ if (old_p)
+ memcpy(p, old_p, sizeof(*old_p));
+ else
+ bzero(p, sizeof(*p));
+
+ return p;
+}
+
+int frsh_contract_set_min_expiration(frsh_contract_t *contract,
+ frsh_rel_time_t min_expiration)
+{
+ fres_block_power_management *p;
+ int ret;
+
+ if (!contract || !*contract)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ p = __dup_power_management(contract);
+ if (!p)
+ return ENOMEM;
+
+ p->min_expiration = min_expiration;
+
+ fres_contract_del_power_management(*contract);
+ ret = fres_contract_add_power_management(*contract, p);
+ if (ret) {
+ free(p);
+ return errno;
+ }
+
+ return FRSH_NO_ERROR;
+}
+
+int frsh_contract_get_min_expiration(const frsh_contract_t *contract,
+ frsh_rel_time_t *min_expiration)
+{
+ fres_block_power_management *p;
+
+ if (!contract || !*contract)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ p = fres_contract_get_power_management(*contract);
+ if (!p)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ *min_expiration = p->min_expiration;
+
+ return FRSH_NO_ERROR;
+}
+
+int frsh_contract_set_min_budget_pow
+ (frsh_contract_t *contract,
+ frsh_power_level_t power_level,
+ const frsh_rel_time_t *pow_min_budget)
+{
+ fres_block_power_management *b;
+ int ret;
+
+ if (!contract || !*contract ||
+ !pow_min_budget)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ b = __dup_power_management(contract);
+ if (!b)
+ return ENOMEM;
+
+ b->min_budget[power_level] = *pow_min_budget;
+
+ fres_contract_del_power_management(*contract);
+ ret = fres_contract_add_power_management(*contract, b);
+ if (ret) {
+ free(b);
+ return errno;
+ }
+
+ return FRSH_NO_ERROR;
+}
+
+int frsh_contract_get_min_budget_pow
+ (const frsh_contract_t *contract,
+ frsh_power_level_t power_level,
+ frsh_rel_time_t *pow_min_budget)
+{
+ fres_block_power_management *b;
+
+ if (!contract || !*contract ||
+ !__is_a_valid_power(power_level))
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ b = fres_contract_get_power_management(*contract);
+ if (!b)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ *pow_min_budget = b->min_budget[power_level];
+
+ return FRSH_NO_ERROR;
+}
+
+int frsh_contract_set_max_budget_pow
+ (frsh_contract_t *contract,
+ frsh_power_level_t power_level,
+ const frsh_rel_time_t *pow_max_budget)
+{
+ fres_block_power_management *b;
+ int ret;
+
+ if (!contract || !*contract ||
+ !pow_max_budget || !__is_a_valid_power(power_level))
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ b = __dup_power_management(contract);
+ if (!b)
+ return ENOMEM;
+
+ b->max_budget[power_level] = *pow_max_budget;
+
+ fres_contract_del_power_management(*contract);
+ ret = fres_contract_add_power_management(*contract, b);
+ if (ret) {
+ free(b);
+ return errno;
+ }
+
+ return FRSH_NO_ERROR;
+}
+
+int frsh_contract_get_max_budget_pow(const frsh_contract_t *contract,
+ frsh_power_level_t power_level,
+ frsh_rel_time_t *pow_max_budget)
+{
+ fres_block_power_management *b;
+
+ if (!contract || !*contract ||
+ !__is_a_valid_power(power_level)) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ b = fres_contract_get_power_management(*contract);
+ if (!b)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ *pow_max_budget = b->max_budget[power_level];
+
+ return FRSH_NO_ERROR;
+}
+
+int frsh_contract_set_utilization_pow
+ (frsh_contract_t *contract,
+ frsh_power_level_t power_level,
+ const frsh_rel_time_t *budget,
+ const frsh_rel_time_t *period,
+ const frsh_rel_time_t *deadline)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_contract_get_utilization_pow
+ (const frsh_contract_t *contract,
+ frsh_power_level_t power_level,
+ frsh_rel_time_t *budget,
+ frsh_rel_time_t *period,
+ frsh_rel_time_t *deadline)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;;
+}
+
+/* FIXME: What happens when one application set one power-level and
+ * second application different level. I think this function should
+ * not be part of API. It should be used internally (e.g. by contract
+ * broker) to achieve the requirements specified by
+ * frsh_contract_set_min_expiration() and similar functions.
+ *
+ * This implementation also skips FCB when doing changes to resources,
+ * which is certainly not good, because resource manager does not know
+ * about the change.
+ */
+int frsh_resource_set_power_level
+ (frsh_resource_type_t resource_type,
+ frsh_resource_id_t resource_id,
+ frsh_power_level_t power_level)
+{
+
+ if (!__is_a_valid_power(power_level))
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ switch(resource_type)
+ {
+#ifdef CONFIG_ACPI_CPU
+ case FRSH_RT_PROCESSOR:
+ {
+ int ret;
+
+ ret = fra_CPU_power_init(resource_id);
+ if (ret) return FRSH_ERR_INTERNAL_ERROR;
+ ret = fra_CPU_set_power(resource_id, power_level);
+ if (ret) return FRSH_ERR_INTERNAL_ERROR;
+
+ /**
+ * @TODO:
+ * if (i budget sono effettivamente diversi)
+ * rinegozia i contratti coi nuovi valori
+ **/
+ break;
+ }
+#endif
+#ifdef CONFIG_ACPI_LCD
+ case FRSH_RT_LCD:
+ {
+ int ret;
+
+ ret = fra_LCD_power_init(resource_id);
+ if (ret) return FRSH_ERR_INTERNAL_ERROR;
+ ret = fra_LCD_set_power(resource_id, power_level);
+ if (ret) return FRSH_ERR_INTERNAL_ERROR;
+ break;
+ }
+#endif
+ default:
+ return FRSH_ERR_NOT_IMPLEMENTED;
+ }
+
+ return FRSH_NO_ERROR;
+}
+
+int frsh_resource_get_power_level
+ (frsh_resource_type_t resource_type,
+ frsh_resource_id_t resource_id,
+ frsh_power_level_t *power_level)
+{
+ switch(resource_type)
+ {
+#ifdef CONFIG_ACPI_CPU
+ case FRSH_RT_PROCESSOR:
+ {
+ int ret;
+
+ ret = fra_CPU_power_init(resource_id);
+ if (ret) return FRSH_ERR_INTERNAL_ERROR;
+ ret = fra_CPU_get_power(resource_id,
+ (int*) power_level);
+ if (ret) return FRSH_ERR_INTERNAL_ERROR;
+
+ break;
+ }
+#endif
+#ifdef CONFIG_ACPI_LCD
+ case FRSH_RT_LCD:
+ {
+ int ret;
+
+ ret = fra_LCD_power_init(resource_id);
+ if (ret) return FRSH_ERR_INTERNAL_ERROR;
+ ret = fra_LCD_get_power(resource_id,
+ (int*) power_level);
+ if (ret) return FRSH_ERR_INTERNAL_ERROR;
+
+ break;
+ }
+#endif
+ default:
+ return FRSH_ERR_NOT_IMPLEMENTED;
+ }
+
+ return FRSH_NO_ERROR;
+}
+
+int frsh_resource_get_speed
+ (frsh_resource_type_t resource_type,
+ frsh_resource_id_t resource_id,
+ frsh_power_level_t power_level,
+ double *speed_ratio)
+{
+ switch(resource_type)
+ {
+#ifdef CONFIG_ACPI_CPU
+ case FRSH_RT_PROCESSOR:
+ {
+ int ret;
+
+ ret = fra_CPU_power_init(resource_id);
+ if (ret) return FRSH_ERR_INTERNAL_ERROR;
+ ret = fra_CPU_get_speed(resource_id,
+ (int) power_level,
+ speed_ratio);
+ if (ret) return FRSH_ERR_INTERNAL_ERROR;
+
+ break;
+ }
+#endif
+#ifdef CONFIG_ACPI_LCD
+ case FRSH_RT_LCD:
+ {
+ int ret;
+
+ ret = fra_LCD_power_init(resource_id);
+ if (ret) return FRSH_ERR_INTERNAL_ERROR;
+ ret = fra_LCD_get_speed(resource_id,
+ (int) power_level,
+ speed_ratio);
+ if (ret) return FRSH_ERR_INTERNAL_ERROR;
+
+ break;
+ }
+#endif
+ default:
+ return FRSH_ERR_NOT_IMPLEMENTED;
+ }
+
+ return FRSH_NO_ERROR;
+}
+
+int frsh_resource_get_num_power_levels
+ (frsh_resource_type_t resource_type,
+ frsh_resource_id_t resource_id,
+ int *num_power_levels)
+{
+ int ret;
+
+ *num_power_levels = 1;
+
+ switch(resource_type)
+ {
+#ifdef CONFIG_ACPI_CPU
+ case FRSH_RT_PROCESSOR:
+ {
+ ret = fra_CPU_power_init(resource_id);
+ if (ret) goto out;
+ break;
+ }
+#endif
+#ifdef CONFIG_ACPI_LCD
+ case FRSH_RT_LCD:
+ {
+ ret = fra_LCD_power_init(resource_id);
+ if (ret) goto out;
+
+ break;
+ }
+#endif
+ default:
+ return FRSH_ERR_NOT_IMPLEMENTED;
+ }
+
+ /**
+ * @FIXME:
+ * This looks tremendous... But the number '3' is hardcoded
+ * whereever in the headers as the number of power level, so...
+ */
+ *num_power_levels = 3;
+
+out:
+ return FRSH_NO_ERROR;
+}
+
+int frsh_battery_get_expiration(frsh_abs_time_t *expiration)
+{
+#ifdef CONFIG_ACPI_BATTERY
+ frsh_rel_time_t interval;
+ int ret;
+
+ ret = fra_battery_init();
+ if (ret) return FRSH_ERR_INTERNAL_ERROR;
+
+ ret = fra_battery_expiration(&interval);
+ if (ret == EAGAIN) return ret;
+ if (ret) return FRSH_ERR_INTERNAL_ERROR;
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, expiration);
+ *expiration = fosa_abs_time_incr(*expiration, interval);
+
+ return FRSH_NO_ERROR;
+#else
+ return FRSH_ERR_NOT_IMPLEMENTED;
+#endif
+}
+
--- /dev/null
+/**
+ * @file frsh_sharedobj.c
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ *
+ * @brief FRSH shared objects related functions.
+ *
+ *
+ */
+#include <fres_contract.h>
+#include <fres_contract_idl.h>
+#include <frsh_error.h>
+#include <fres_blocks.h>
+#include <frsh_core.h>
+#include <fres_sharedobj.h>
+
+int frsh_sharedobj_init
+ (const char *obj_label,
+ frsh_sharedobj_kind_t obj_kind,
+ frsh_sharedobj_handle_t *obj_handle,
+ frsh_mutex_t *mutex)
+{
+ if (!obj_handle)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ /* In this implementation external mutex is not supported, *
+ * use frsh_sharedobj_get_mutex instead. */
+ if (mutex)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ *obj_handle = fres_sharedobj_new(obj_label, obj_kind);
+ if (!(*obj_handle)) goto err;
+
+ return 0;
+err:
+ return errno;
+}
+
+int frsh_sharedobj_get_handle
+ (char *obj_label,
+ frsh_sharedobj_handle_t *obj_handle)
+{
+ if (!obj_label || !obj_handle)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ *obj_handle = fres_sharedobj_get_label(obj_label);
+ if (!(*obj_handle)) goto err;
+
+ return 0;
+err:
+ return errno;
+}
+
+int frsh_sharedobj_get_mutex
+ (frsh_sharedobj_handle_t obj_handle,
+ frsh_mutex_t **mutex)
+{
+ if (!obj_handle || !mutex)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ *mutex = &obj_handle->mutex;
+
+ return 0;
+}
+
+int frsh_sharedobj_get_obj_kind
+ (frsh_sharedobj_handle_t obj_handle,
+ frsh_sharedobj_kind_t *obj_kind)
+{
+ if (!obj_handle || !obj_kind)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ *obj_kind = obj_handle->kind;
+
+ return 0;
+}
+
+int frsh_sharedobj_remove(frsh_sharedobj_handle_t obj_handle)
+{
+ if (!obj_handle)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ return fres_sharedobj_destroy(obj_handle);
+}
+
+/* Critical Sections. */
+
+int frsh_csect_init
+ (frsh_sharedobj_handle_t obj_handle,
+ frsh_rel_time_t wcet,
+ frsh_csect_t *csect)
+{
+ if (!obj_handle || !csect)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ csect->op_kind = FRSH_CSOK_UNCHECKED;
+ strncpy(csect->obj_label,
+ obj_handle->label,
+ sizeof(obj_handle->label));
+ csect->wcet = wcet;
+ csect->blocking = wcet;
+ csect->op = NULL;
+ csect->areas.size = 0;
+
+ return 0;
+}
+
+int frsh_csect_get_sharedobj_handle
+ (const frsh_csect_t *csect,
+ frsh_sharedobj_handle_t *obj_handle)
+{
+ if (!obj_handle || !csect)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ *obj_handle = fres_sharedobj_get_label(csect->obj_label);
+
+ return 0;
+}
+
+int frsh_csect_get_wcet
+ (const frsh_csect_t *csect,
+ frsh_rel_time_t *wcet)
+{
+ if (!csect || !wcet)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ *wcet = csect->wcet;
+
+ return 0;
+}
+
+int frsh_csect_get_blocking_time
+ (const frsh_csect_t *csect,
+ fosa_rel_time_t *blocking)
+{
+ if (!csect || !blocking)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ *blocking = csect->blocking;
+
+ return 0;
+}
+
+int frsh_csect_get_op_kind
+ (const frsh_csect_t *csect,
+ frsh_csect_op_kind_t *op_kind)
+{
+ if (!csect || !op_kind)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ *op_kind = csect->op_kind;
+
+ return 0;
+}
+
+int frsh_csect_get_read_op
+ (const frsh_csect_t *csect,
+ frsh_csect_op_t *op)
+{
+ if (!csect ||
+ !op ||
+ csect->op_kind != FRSH_CSOK_READ)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ *op = csect->op;
+
+ return 0;
+}
+
+int frsh_csect_get_write_op
+ (const frsh_csect_t *csect,
+ frsh_csect_op_t *op,
+ frsh_memory_areas_t *areas)
+{
+ int i;
+
+ if (!csect ||
+ !op ||
+ !areas ||
+ csect->op_kind != FRSH_CSOK_WRITE)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ *op = csect->op;
+ areas->size = csect->areas.size;
+
+ for (i = 0; i < areas->size; i++)
+ areas->memory_areas[i] = csect->areas.memory_areas[i];
+
+ return 0;
+}
+
+int frsh_csect_register_read_op
+ (frsh_csect_t *csect,
+ frsh_csect_op_t op)
+{
+ if (!csect || !op)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ csect->op_kind = FRSH_CSOK_READ;
+ csect->op = op;
+
+ /* Account for protection overheads: NOT IMPLEMENTED! */
+ /* csect->blocking = fosa_rel_time_add(csect->wcet, ); */
+ csect->blocking = csect->wcet;
+
+ return 0;
+}
+
+int frsh_csect_register_write_op
+ (frsh_csect_t *csect,
+ frsh_csect_op_t op,
+ const frsh_memory_areas_t *areas)
+{
+ int i;
+
+ if (!csect || !op)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ if (areas->size <= 0 || areas->size > FRSH_MAX_N_MEMORY_AREAS)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ /* TODO:
+ * Check for the shared object associated with this
+ * critical section not to be UNPROTECTED;
+ */
+
+ csect->areas.size = areas->size;
+ csect->op_kind = FRSH_CSOK_WRITE;
+ csect->op = op;
+
+ for (i = 0; i< areas->size; i++)
+ csect->areas.memory_areas[i] = areas->memory_areas[i];
+
+ /* Account for protection and rollback overheads: NOT IMPLEMENTED! */
+ /* csect->blocking = fosa_rel_time_add(csect->wcet, ); */
+ csect->blocking = csect->wcet;
+
+ return 0;
+}
+
+int frsh_csect_invoke
+ (const frsh_csect_t *csect,
+ const void *input_arg,
+ void *output_arg)
+{
+ int i, jumped, ret = 0;
+ frsh_memory_areas_t storage = { .size = 0 };
+ frsh_sharedobj_handle_t obj_handle;
+ fosa_mutex_t *obj_mutex;
+ fosa_clock_id_t clockid;
+ fosa_signal_t signal;
+ fosa_signal_info_t siginfo;
+
+ if (!csect) {
+ ret = FRSH_ERR_BAD_ARGUMENT;
+ goto out;
+ }
+
+ obj_handle = fres_sharedobj_get_label(csect->obj_label);
+ if (!obj_handle) {
+ ret = errno;
+ goto out;
+ }
+ ret = frsh_sharedobj_get_mutex(obj_handle, &obj_mutex);
+ if (ret) goto out;
+ ret = fosa_mutex_lock(obj_mutex);
+ if (ret) goto out;
+
+ siginfo.sival_ptr = (void*) (&(obj_handle->context));
+ ret = fosa_long_jump_install_handler(&signal, NULL);
+ if (ret) goto out_unlock;
+
+ /* Prepare the WCET timer. */
+ ret = fosa_thread_get_cputime_clock(fosa_thread_self() ,&clockid);
+ if (ret) goto out_unlock;
+ ret = fosa_timer_create_with_receiver(clockid,
+ signal,
+ siginfo,
+ &obj_handle->wcet_timer,
+ fosa_thread_self());
+ if (ret) goto out_unlock;
+ ret = fosa_rel_timer_arm(obj_handle->wcet_timer, &csect->wcet);
+ if (ret) goto out_disarm;
+
+ /* Backup memory areas. */
+ if (csect->op_kind == FRSH_CSOK_WRITE) {
+ for (i = 0; i < csect->areas.size; i++) {
+ storage.memory_areas[i].size =
+ csect->areas.memory_areas[i].size;
+ storage.memory_areas[i].area =
+ malloc(csect->areas.memory_areas[i].size);
+ if (!storage.memory_areas[i].area) {
+ ret = errno;
+ goto out_disarm;
+ }
+ if (!memcpy(storage.memory_areas[i].area,
+ csect->areas.memory_areas[i].area,
+ csect->areas.memory_areas[i].size)) {
+ ret = errno;
+ goto out_disarm;
+ }
+ storage.size++;
+ }
+ }
+
+ ret = fosa_long_jump_save_context(&obj_handle->context);
+ if (ret) goto out_disarm;
+ ret = fosa_long_jump_was_performed(&obj_handle->context, &jumped);
+ if (ret) goto out_disarm;
+
+ if (!jumped) {
+ /* Invoke the operation. */
+ csect->op(input_arg,output_arg);
+
+ /* Leave the critical section normally. */
+ goto out_disarm;
+ }
+
+ ret = FRSH_ERR_BUDGET_EXPIRED;
+
+ /* Restore backed-up memory areas. */
+ if (csect->op_kind == FRSH_CSOK_WRITE) {
+ for (i = 0; i < csect->areas.size; i++)
+ if (!memcpy(csect->areas.memory_areas[i].area,
+ storage.memory_areas[i].area,
+ csect->areas.memory_areas[i].size)) {
+ ret = errno;
+ goto out_unlock;
+ }
+ }
+
+out_disarm:
+ fosa_timer_disarm(obj_handle->wcet_timer, NULL);
+ fosa_timer_delete(obj_handle->wcet_timer);
+
+ for (i = 0; i < storage.size; i++)
+ if (storage.memory_areas[i].area) /* Uneeded ? */
+ free(storage.memory_areas[i].area);
+
+out_unlock:
+ fosa_mutex_unlock(obj_mutex);
+out:
+ return ret;
+}
+
+/* Contract Parameters. */
+
+int frsh_contract_set_csects
+ (frsh_contract_t *contract,
+ const frsh_csects_group_t *critical_sections)
+{
+ fres_block_csects *c;
+ int i, len, ret;
+
+ if (!contract || !*contract || !critical_sections)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ if (critical_sections->size < 0 ||
+ critical_sections->size > FRSH_MAX_N_CRITICAL_SECTIONS)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ c = malloc(sizeof(*c));
+ if (!c) return FOSA_ENOMEM;
+
+ len = critical_sections->size;
+ c->sections._length = len;
+ c->sections._maximum = len;
+ c->sections._buffer = CORBA_sequence_frsh_csect_runtime_allocbuf(len);
+ for (i = 0; i < len; i++)
+ memcpy(&c->sections._buffer[i],
+ &critical_sections->csects[i],
+ sizeof(c->sections._buffer[i]));
+
+ fres_contract_del_csects(*contract);
+ ret = fres_contract_add_csects(*contract, c);
+
+ if (ret) {
+ free(c);
+ return errno;
+ }
+
+ return 0;
+}
+
+int frsh_contract_get_csects
+ (const frsh_contract_t *contract,
+ frsh_csects_group_t *critical_sections)
+{
+ fres_block_csects *c;
+ int i;
+
+ if (!contract || !*contract || !critical_sections)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ c = fres_contract_get_csects(*contract);
+
+ critical_sections->size = c->sections._length;
+ for (i = 0; i < critical_sections->size; i++)
+ memcpy(&critical_sections->csects[i],
+ &c->sections._buffer[i],
+ sizeof(critical_sections->csects[i]));
+
+ return 0;
+}
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file frsh_spare_capacity.c
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ *
+ * @brief Implementation of FRSH contract API on top of FRES contracts.
+ *
+ *
+ */
+#include <fres_contract.h>
+#include <fres_contract_idl.h>
+#include <frsh_core.h>
+#include <frsh_error.h>
+#include <fres_blocks.h>
+#include <string.h>
+#include <fcb.h>
+#include "frsh_forb.h"
+#include <fra_generic.h>
+
+int frsh_contract_set_reclamation_params
+ (frsh_contract_t *contract,
+ const struct timespec *stability_time,
+ const struct timespec *budget_max,
+ const struct timespec *period_min,
+ frsh_granularity_t granularity,
+ const frsh_utilization_set_t *utilization_set,
+ int importance,
+ int weight)
+{
+ fres_block_spare_capacity *s;
+ int ret;
+
+ if (!contract || !*contract ||
+ !stability_time || !budget_max || !period_min)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ if (fosa_rel_time_is_null(*budget_max) ||
+ fosa_rel_time_is_null(*period_min) ||
+ fosa_rel_time_smaller(*period_min, *budget_max))
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ if ((granularity == FRSH_GR_CONTINUOUS && utilization_set != NULL) ||
+ (granularity == FRSH_GR_DISCRETE && utilization_set == NULL))
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ if (granularity != FRSH_GR_CONTINUOUS &&
+ granularity != FRSH_GR_DISCRETE)
+ return FRSH_ERR_NOT_IMPLEMENTED;
+
+ s = malloc(sizeof(*s));
+ if (!s) return ENOMEM;
+ memset(s, 0, sizeof(*s));
+
+ s->budget = *budget_max;
+ s->period = *period_min;
+ s->granularity = granularity;
+
+ if (utilization_set) {
+ int i;
+ if (!forb_sequence_alloc_buf(&s->variants, utilization_set->size)) {
+ goto err;
+ }
+ for (i=0; i<utilization_set->size; i++) {
+ struct fres_container *c = NULL;
+ fres_block_basic *b = NULL;
+ fres_block_timing_reqs *t = NULL;
+ c = fres_container_new();
+ if (!c)
+ goto err;
+ b = malloc(sizeof(*b));
+ if (!b)
+ goto err_ut;
+ t = malloc(sizeof(*t));
+ if (!t)
+ goto err_ut;
+
+ b->budget = utilization_set->utilizations[i].budget;
+ b->period = utilization_set->utilizations[i].period;
+ /* FIXME: workload and contract type should be
+ * the same as in basic_params. The easyest
+ * solution would be to split basic block to
+ * two blocks - (budget, period) and
+ * (workload, contract_type).
+ * Note: frsh_contract_set_reclamation_params()
+ * should be defined differently. */
+ b->workload = FRSH_WT_BOUNDED;
+ b->contract_type = FRSH_CT_REGULAR;
+ ret = fres_container_add_basic(c, b);
+
+ t->d_equals_t = true; /* FIXME: the same as above */
+ t->deadline = utilization_set->utilizations[i].deadline;
+
+ ret = fres_container_add_timing_reqs(c, t);
+
+ forb_sequence_elem(&s->variants, i) = c;
+ continue;
+ err_ut:
+ fres_container_destroy(c);
+ free(b); /* FIXME: Possible double free */
+ free(t);
+ goto err;
+ }
+ s->variants._length = utilization_set->size;
+ }
+ /* TODO: In case of CONTINUOUS granularity copy min and max
+ * requirements to the variants. */
+ s->importance = importance;
+ s->weight = weight;
+ s->stability_time = *stability_time;
+
+ fres_contract_del_spare_capacity(*contract);
+ ret = fres_contract_add_spare_capacity(*contract, s);
+
+ if (ret)
+ goto err;
+
+ return FRSH_NO_ERROR;
+err:
+ forb_sequence_free_buf(&s->variants, forb_no_destructor);
+ free(s);
+ return errno;
+}
+
+int frsh_contract_get_reclamation_params
+ (const frsh_contract_t *contract,
+ struct timespec *stability_time,
+ struct timespec *budget_max,
+ struct timespec *period_min,
+ frsh_granularity_t *granularity,
+ frsh_utilization_set_t *utilization_set,
+ int *importance,
+ int *weight)
+{
+ fres_block_spare_capacity *s;
+
+ if (!contract || !*contract)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ s = fres_contract_get_spare_capacity(*contract);
+
+ if (budget_max)
+ *budget_max = s->budget;
+ if (period_min)
+ *period_min = s->period;
+ if (granularity)
+ *granularity = s->granularity;
+ /*
+ * TODO:
+ * support utilization-set for discrete spare
+ * capacity distribution.
+ */
+ if (importance)
+ *importance = s->importance;
+ if (weight)
+ *weight = s->weight;
+ if (stability_time)
+ *stability_time = s->stability_time;
+
+ return FRSH_NO_ERROR;
+}
+
+int frsh_vres_get_remaining_stability_time
+ (frsh_vres_id_t vres,
+ struct timespec *stability_time)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_resource_get_capacity
+ (const frsh_resource_type_t resource_type,
+ const frsh_resource_id_t resource_id,
+ const int importance,
+ uint32_t *capacity)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_resource_get_total_weight
+ (const frsh_resource_type_t resource_type,
+ const frsh_resource_id_t resource_id,
+ const int importance,
+ uint32_t *total_weight)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_vres_decrease_capacity
+ (frsh_vres_id_t vres_id,
+ struct timespec new_budget,
+ struct timespec new_period)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
--- /dev/null
+/**
+ * @file frsh_synchobj.c
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ *
+ * @brief FRSH core synchronization objects related functions
+ * not implamented in managers.
+ *
+ *
+ */
+#include <fres_vres.h>
+#include <fra_generic.h>
+#include <fres_synchobj.h>
+
+#include <frsh_core.h>
+
+int frsh_synchobj_create(frsh_synchobj_handle_t *synch_handle)
+{
+ if (!synch_handle)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ *synch_handle = fres_synchobj_new();
+ if (!(*synch_handle)) goto err;
+
+ return 0;
+err:
+ return errno;
+}
+
+int frsh_synchobj_destroy(const frsh_synchobj_handle_t synch_handle)
+{
+ return fres_synchobj_destroy(synch_handle);
+}
+
+static void
+__frsh_synchobj_check_wcet_and_deadline(frsh_thread_id_t thread,
+ fres_thread_vres_t *th_vres,
+ bool *was_deadline_missed,
+ bool *was_budget_overrun)
+{
+ fosa_clock_id_t th_clockid;
+ fosa_abs_time_t curr_time, curr_exec_time;
+ frsh_vres_id_t vres;
+ fres_block_basic *b;
+ fres_block_timing_reqs *t;
+
+ if (!was_deadline_missed && !was_budget_overrun)
+ return;
+
+ *was_deadline_missed = false;
+ *was_budget_overrun = false;
+
+ fosa_thread_get_cputime_clock(thread, &th_clockid);
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, &curr_time);
+ fosa_clock_get_time(th_clockid, &curr_exec_time);
+
+ curr_time = fosa_abs_time_decr(curr_time, th_vres->job_start_time);
+ curr_exec_time = fosa_abs_time_decr(curr_exec_time,
+ th_vres->job_cpu_time);
+
+ vres = th_vres->vres;
+ b = fres_contract_get_basic(vres->perceived);
+ t = fres_contract_get_timing_reqs(vres->perceived);
+
+ if (was_deadline_missed &&
+ fosa_abs_time_smaller_or_equal(t->deadline, curr_time))
+ *was_deadline_missed = true;
+
+ if (was_budget_overrun &&
+ fosa_abs_time_smaller_or_equal(b->budget, curr_exec_time))
+ *was_budget_overrun = false;
+}
+
+static void
+__frsh_synchobj_set_wcet_and_deadline(frsh_thread_id_t thread,
+ fres_thread_vres_t *th_vres)
+{
+ fosa_clock_id_t th_clockid;
+
+ fosa_thread_get_cputime_clock(thread, &th_clockid);
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME,
+ &th_vres->job_start_time);
+ fosa_clock_get_time(th_clockid, &th_vres->job_cpu_time);
+
+}
+
+int frsh_synchobj_wait
+ (const frsh_synchobj_handle_t synch_handle,
+ frsh_rel_time_t *next_budget,
+ frsh_rel_time_t *next_period,
+ bool *was_deadline_missed,
+ bool *was_budget_overrun)
+{
+ frsh_thread_id_t thread = fosa_thread_self();
+ fres_thread_vres_t *th_vres;
+ int ret = 0;
+
+ th_vres = fra_get_thread_vres(&thread, FRSH_RT_PROCESSOR);
+ if (!th_vres) goto out;
+
+ __frsh_synchobj_check_wcet_and_deadline(thread,
+ th_vres,
+ was_deadline_missed,
+ was_budget_overrun);
+
+ ret = fres_synchobj_wait_with_timeout(synch_handle, NULL);
+ if (ret) goto out;
+
+ __frsh_synchobj_set_wcet_and_deadline(thread, th_vres);
+ frsh_vres_get_budget_and_period(th_vres->vres,
+ next_budget,
+ next_period);
+
+out:
+ return ret;
+}
+
+int frsh_synchobj_wait_with_timeout
+ (const frsh_synchobj_handle_t synch_handle,
+ const frsh_abs_time_t *abs_timeout,
+ bool *timed_out,
+ frsh_rel_time_t *next_budget,
+ frsh_rel_time_t *next_period,
+ bool *was_deadline_missed,
+ bool *was_budget_overrun)
+{
+ frsh_thread_id_t thread = fosa_thread_self();
+ fres_thread_vres_t *th_vres;
+ int ret = 0;
+
+ th_vres = fra_get_thread_vres(&thread, FRSH_RT_PROCESSOR);
+ if (!th_vres) goto out;
+
+ __frsh_synchobj_check_wcet_and_deadline(thread,
+ th_vres,
+ was_deadline_missed,
+ was_budget_overrun);
+
+ ret = fres_synchobj_wait_with_timeout(synch_handle, abs_timeout);
+ if (ret == ETIMEDOUT) *timed_out = true;
+ else if (ret != 0) goto out;
+
+ __frsh_synchobj_set_wcet_and_deadline(thread, th_vres);
+ frsh_vres_get_budget_and_period(th_vres->vres,
+ next_budget,
+ next_period);
+
+out:
+ return ret;
+}
+
+int frsh_synchobj_signal(const frsh_synchobj_handle_t synch_handle)
+{
+ return fres_synchobj_signal(synch_handle);
+}
+
+int frsh_timed_wait
+ (const frsh_abs_time_t *abs_time,
+ frsh_rel_time_t *next_budget,
+ frsh_rel_time_t *next_period,
+ bool *was_deadline_missed,
+ bool *was_budget_overrun)
+{
+ frsh_thread_id_t thread = fosa_thread_self();
+ fres_thread_vres_t *th_vres;
+ int ret = 0;
+
+ th_vres = fra_get_thread_vres(&thread, FRSH_RT_PROCESSOR);
+ if (!th_vres) goto out;
+
+ __frsh_synchobj_check_wcet_and_deadline(thread,
+ th_vres,
+ was_deadline_missed,
+ was_budget_overrun);
+
+ ret = clock_nanosleep(FOSA_CLOCK_REALTIME,
+ TIMER_ABSTIME,
+ abs_time, NULL);
+
+ __frsh_synchobj_set_wcet_and_deadline(thread, th_vres);
+ frsh_vres_get_budget_and_period(th_vres->vres,
+ next_budget,
+ next_period);
+
+out:
+ return ret;
+}
+
+int frsh_vresperiod_wait
+ (unsigned long period_num,
+ frsh_rel_time_t *next_budget,
+ frsh_rel_time_t *next_period,
+ bool *was_deadline_missed,
+ bool *was_budget_overran)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_get_period_number(const frsh_vres_id_t vres, long *period_num)
+
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
--- /dev/null
+/**
+ * @file frsh_thread.c
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ *
+ * @brief FRSH core thread related functions not implamented in managers..
+ *
+ *
+ */
+#include <semaphore.h>
+
+#include <fres_contract.h>
+#include <fres_contract_idl.h>
+#include <frsh_core.h>
+#include <frsh_error.h>
+#include <fres_blocks.h>
+#include <string.h>
+#include <fcb.h>
+#include <fra_generic.h>
+
+#include "frsh_forb.h"
+
+#ifdef CONFIG_AQUOSA
+#include <aqcpu_res.h>
+#endif
+#ifdef CONFIG_CPUCG
+#include <cpucg_res.h>
+#endif
+#ifdef CONFIG_DISKBFQ
+#include <diskbfq_res.h>
+#endif
+
+/**
+ * frsh_thread_bind(), bind a thread to a vres
+ *
+ * possible return values:
+ * FRSH_NO_ERROR
+ * FRSH_ERR_NOT_INITIALIZED
+ * FRSH_BAD_ARGUMENT(*) (invalid or dummy vres)
+ * FRSH_ERR_NOT_CONTRACTED_VRES(*)
+ * FRSH_ERR_ALREADY_BOUND(*)
+ * FRSH_ERR_INTERNAL_ERROR(*) (something wrong with AQuoSA or with the service thread internal data structures)
+ */
+int frsh_thread_bind
+ (const frsh_vres_id_t vres,
+ const frsh_thread_id_t thread)
+{
+ int ret;
+ ret = fra_insert_thread_vres(&thread, vres->allocator->res_type, vres);
+ if (ret) goto err;
+
+ if (vres->allocator->bind_thread) {
+ ret = vres->allocator->bind_thread(vres, thread);
+ } else {
+ ret = FRSH_ERR_NOT_IMPLEMENTED;
+ }
+ if (ret) goto err_delete;
+
+ return FRSH_NO_ERROR;
+
+err_delete:
+ fra_delete_thread_vres(&thread, vres->allocator->res_type);
+err:
+ return FRSH_ERR_INTERNAL_ERROR;
+}
+
+/*
+ * frsh_thread_unbind(), unbind a thread from a vres
+ *
+ * @FIXME:
+ * Notice that, since we don't know from which VRES the
+ * thread should be unbound, we unboind it from all the
+ * ones it is attached to!
+ *
+ * possible return values:
+ * FRSH_NO_ERROR
+ * FRSH_ERR_NOT_INITIALIZED
+ * FRSH_BAD_ARGUMENT(*) (invalid thread)
+ * FRSH_ERR_NOT_BOUND(*)
+ * FRSH_ERR_INTERNAL_ERROR(*) (something wrong with AQuoSA or with the service thread internal data structures)
+ */
+int frsh_thread_unbind(const frsh_thread_id_t thread)
+{
+ fres_vres_t *vres;
+ int ret;
+
+ /* Unbound from FRSH_RT_PROCESSOR resource (if any) */
+ vres = fra_get_vres_thread_vres(&thread, FRSH_RT_PROCESSOR);
+ if (vres) {
+ if (vres->allocator->unbind_thread) {
+ ret = vres->allocator->unbind_thread(thread);
+ } else {
+ ret = FRSH_ERR_NOT_IMPLEMENTED;
+ }
+ if (ret) goto err;
+
+ ret = fra_delete_thread_vres(&thread, vres->allocator->res_type);
+ if (ret) goto err;
+ }
+
+ /* Unbound from FRSH_RT_DISK resource (if any) */
+ vres = fra_get_vres_thread_vres(&thread, FRSH_RT_DISK);
+ if (vres) {
+ if (vres->allocator->unbind_thread) {
+ ret = vres->allocator->unbind_thread(thread);
+ } else {
+ ret = FRSH_ERR_NOT_IMPLEMENTED;
+ }
+ if (ret) goto err;
+
+ ret = fra_delete_thread_vres(&thread, vres->allocator->res_type);
+ if (ret) goto err;
+ }
+
+ return FRSH_NO_ERROR;
+err:
+ return FRSH_ERR_INTERNAL_ERROR;
+}
+
+/**
+ * structure used to pass the new created thread (or better its wrapper) the
+ * arguments it needs to bind itself to the vres.
+ */
+typedef struct wrapper_pthread_arg {
+ frsh_thread_id_t parent_thread_id;
+ frsh_thread_id_t *thread_id;
+ frsh_thread_code_t pthread_code; /**< function to be running in thread */
+ void *pthread_arg; /**< thread arguments*/
+ frsh_vres_id_t vres;
+ sem_t *stopper; /**< semaphore to synchronize frsh call and wrapper thread */
+ int errcode;
+} wrapper_pthread_arg_t;
+
+/*
+ * typedef struct {
+ * pthread_t pthread_id;
+ * pid_t linux_pid;
+ * pid_t linux_tid;
+ * } FOSA_THREAD_ID_T_OPAQUE;
+ */
+
+/**
+ * Wrapper thread
+ *
+ * possible exit status:
+ * FRSH_ERR_INTENRAL_ERROR (something wrong with threads and signal handling)
+ * FRSH_ERR_TOO_MANY_TASKS(*)
+ * FRSH_ERR_BAD_ARGUMENT(*) (invalid vres)
+ * FRSH_ERR_NOT_CONTRACTED_VRES(*)
+ * whatever the user provided code 'pthread_code' returns
+ */
+static void* wrapper_pthread(void *arg)
+{
+ wrapper_pthread_arg_t* pth = (wrapper_pthread_arg_t*) arg;
+ frsh_thread_id_t* thread_id = pth->thread_id;
+ void *thread_arg = pth->pthread_arg;
+ frsh_thread_code_t thread_code = pth->pthread_code;
+
+ /* bind this thread to vres */
+ *thread_id = fosa_thread_self();
+ pth->errcode = frsh_thread_bind(pth->vres, *thread_id);
+
+ sem_post(pth->stopper);
+ /* No access to pth is allowed after this point, it can vanish already */
+
+ if (pth->errcode) return NULL;
+
+ /* execute thread code */
+ return thread_code(thread_arg);
+}
+
+/*
+ * API call for 'frsh_thread_create_and_bind()', as said prepares the
+ * wrapper code argument data structure, create the new thread and wait
+ * its acknowledgment before stepping over
+ *
+ * possible return values:
+ * FRSH_NO_ERROR
+ * FRSH_ERR_NOT_INITIALIZED
+ * FRSH_ERR_BAD_ARGUMENT (NULL thread or thread_code)
+ * whatever 'fosa_thread_create()' returns
+ * FRSH_ERR_INTERNAL_ERROR
+ */
+int frsh_thread_create_and_bind
+ (const frsh_vres_id_t vres,
+ frsh_thread_id_t *thread,
+ frsh_thread_attr_t *attr,
+ frsh_thread_code_t thread_code,
+ void *arg)
+{
+ wrapper_pthread_arg_t wp_arg;
+ sem_t stopper;
+ int ret;
+
+ sem_init(&stopper, 0, 0);
+
+ if (!thread || !thread_code || !attr)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ wp_arg.parent_thread_id = fosa_thread_self();
+ wp_arg.thread_id = thread;
+ wp_arg.pthread_code = thread_code;
+ wp_arg.pthread_arg = arg;
+ wp_arg.vres = vres;
+ wp_arg.stopper = &stopper;
+
+ /* create the wrapper thread */
+ pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
+ pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
+ ret = fosa_thread_create(thread, attr, wrapper_pthread,
+ (void*)&wp_arg);
+
+ if (ret != 0)
+ return(ret);
+
+ sem_wait(&stopper);
+
+ return (wp_arg.errcode);
+}
+
+int frsh_thread_create_in_background
+ (frsh_thread_code_t thread_code,
+ const void *thread_arg,
+ const frsh_contract_label_t contract_label,
+ frsh_thread_attr_t *attr,
+ frsh_thread_id_t *thread,
+ frsh_vres_id_t *vres_id)
+{
+ frsh_contract_t contract;
+ fosa_rel_time_t zero_msec = fosa_msec_to_rel_time(0);
+ int ret = 0;
+
+ /* Background contract creation and negotiation */
+ frsh_contract_init(&contract);
+ frsh_contract_set_resource_and_label(&contract,
+ FRSH_RT_PROCESSOR,
+ 0,
+ contract_label);
+ frsh_contract_set_basic_params(&contract,
+ &zero_msec,
+ &zero_msec,
+ FRSH_WT_INDETERMINATE,
+ FRSH_CT_BACKGROUND);
+
+ /* It will be accepted: we are asking for 0 budget over 0 period */
+ ret = frsh_contract_negotiate(&contract, vres_id);
+ if (ret !=0) goto error;
+
+ ret = fosa_thread_create(thread, attr, thread_code, (void*) thread_arg);
+ if (ret != 0) goto error;
+
+ ret = fra_insert_thread_vres(thread, FRSH_RT_PROCESSOR, *vres_id);
+ if (ret) goto error;
+
+ return 0;
+error:
+ return ret;
+}
+
+int frsh_thread_get_vres_id
+ (const frsh_thread_id_t thread,
+ frsh_vres_id_t *vres_id)
+{
+ if (!vres_id)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ /*
+ * @FIXME:
+ * Why PROCESSOR and not DISK or NETWORK (or whatever) ??
+ */
+ *vres_id = fra_get_vres_thread_vres(&thread,
+ FRSH_RT_PROCESSOR);
+
+ return vres_id ? 0 : EINVAL;
+}
+
+int frsh_service_thread_set_data
+ (const struct timespec *budget,
+ const struct timespec *period,
+ bool *accepted)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_service_thread_get_data
+ (frsh_rel_time_t *budget,
+ frsh_rel_time_t *period)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_vres_set_notification(
+ frsh_vres_id_t vres,
+ const frsh_signal_t budget_overrun_signal,
+ const frsh_signal_info_t budget_overrun_siginfo,
+ const frsh_signal_t deadline_miss_signal,
+ const frsh_signal_info_t deadline_miss_siginfo)
+{
+ fres_block_basic *b;
+
+ /* deadline and period must be coherent between each other */
+ b = fres_contract_get_basic(vres->allocated);
+
+ /* signal delivery can only be requested for BUONDED workloads */
+ if (b &&
+ (b->workload == FRSH_WT_INDETERMINATE &&
+ (deadline_miss_signal != FRSH_NULL_SIGNAL ||
+ budget_overrun_signal != FRSH_NULL_SIGNAL)))
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ /* TODO - handle overrun and deadline signals */
+/* vres->budget_overrun_signal = budget_overrun_signal; */
+/* vres->budget_overrun_siginfo = budget_overrun_siginfo; */
+/* vres->deadline_miss_signal = deadline_miss_signal; */
+/* vres->deadline_miss_siginfo = deadline_miss_siginfo; */
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
--- /dev/null
+/**************************************************************************/
+/* Copyright (C) 2010 Czech Technical University in Prague */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file frsh_transaction.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ *
+ * @brief Implementation of FRSH transaction negotiation.
+ */
+
+#include <frsh.h>
+#include <frsh_transaction.h>
+#include <fres_transaction.h>
+#include <fcb.h>
+#include "frsh_forb.h"
+#include <fra_generic.h>
+
+int
+frsh_transaction_init(frsh_transaction_t *transaction,
+ char *name)
+{
+ int ret = 0;
+ if (!transaction) {
+ ret = FRSH_ERR_BAD_ARGUMENT;
+ goto err;
+ }
+ *transaction = fres_transaction_new();
+ (*transaction)->name = name;
+err:
+ return ret;
+}
+
+void
+frsh_transaction_destroy(frsh_transaction_t *transaction)
+{
+ fres_transaction_destroy(*transaction);
+}
+
+int
+frsh_transaction_add_contract(frsh_transaction_t *transaction,
+ frsh_contract_t *contract,
+ int id)
+{
+ int ret;
+ if (!transaction || !*transaction ||
+ !contract || !*contract ||
+ id < 0) {
+ ret = FRSH_ERR_BAD_ARGUMENT;
+ goto err;
+ }
+
+ ret = fres_transaction_add_contract(*transaction, *contract);
+ if (ret == -1)
+ ret = errno;
+ else
+ ret = 0;
+err:
+ return ret;
+}
+
+int
+frsh_transaction_negotiate(frsh_transaction_t *trans)
+{
+ int ret;
+ struct forb_env env;
+
+ if (!trans || !*trans) {
+ ret = FRSH_ERR_BAD_ARGUMENT;
+ goto err;
+ }
+ ret = fres_contract_broker_negotiate_transaction(
+ frsh_forb_global.fcb, *trans, &env);
+ if (forb_exception_occurred(&env)) {
+ ret = fres_forbex2err(&env);
+ goto err;
+ }
+err:
+ return ret;
+}
+
+int
+frsh_transaction_cancel(frsh_transaction_t *trans)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int
+frsh_transaction_wait_for_name(frsh_transaction_t *transaction,
+ const char *name)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int
+frsh_transaction_alloc_vres(frsh_transaction_t *t,
+ int index,
+ frsh_vres_id_t *vres)
+{
+ int ret;
+ struct forb_env env;
+ fres_contract_id_t id;
+ ret = fres_contract_broker_allocate_transaction_vres(
+ frsh_forb_global.fcb, (*t)->name, index, &id, &env);
+ if (forb_exception_occurred(&env)) {
+ ret = fres_forbex2err(&env);
+ goto err;
+ }
+ if (ret)
+ goto err;
+ *vres = fra_get_vres(&id);
+ assert(*vres != NULL);
+
+err:
+ return ret;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file frsh_vres.c
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ * @date Wed Feb 20 14:53:22 2009
+ *
+ * @brief Core of FRSH_FORB framework
+ *
+ */
+
+
+#include <frsh_core.h>
+#include <fra_generic.h>
+#include <frsh_resources.h>
+
+#include "frsh_forb.h"
+
+#ifdef CONFIG_AQUOSA
+#include <aqcpu_res.h>
+#endif
+#ifdef CONFIG_CPUCG
+#include <cpucg_res.h>
+#endif
+#ifdef CONFIG_DISKBFQ
+#include <diskbfq_res.h>
+#endif
+
+int frsh_vres_get_priority
+ (frsh_vres_id_t vres_id,
+ int *priority)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_vres_get_contract
+ (const frsh_vres_id_t vres,
+ frsh_contract_t *contract)
+{
+ if (!vres) return FRSH_ERR_BAD_ARGUMENT;
+
+ /* TODO: Reference counting */
+ *contract = vres->perceived;
+
+ return 0;
+}
+
+int frsh_resource_get_vres_from_label
+ (const char *contract_label,
+ const frsh_resource_type_t resource_type,
+ const frsh_resource_id_t resource_id,
+ frsh_vres_id_t *vres)
+{
+ fres_block_resource *r;
+ fres_block_label *label;
+
+ if (!contract_label || !vres) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+ r = malloc(sizeof(*r));
+ if (!r) return ENOMEM;
+ r->resource_type = resource_type;
+ r->resource_id = resource_id;
+
+ label = malloc(sizeof(*label));
+ if (!label) {
+ free(r);
+ return ENOMEM;
+ }
+ strncpy(label->label, contract_label, sizeof(label->label));
+ label->label[sizeof(label->label)-1] = '\0';
+
+ *vres = fres_vreses_find_label(label, r);
+ if (*vres) return FRSH_NO_ERROR;
+
+ return FRSH_ERR_CONTRACT_LABEL_UNKNOWN;
+}
+
+int frsh_vres_get_renegotiation_status
+ (const frsh_vres_id_t vres,
+ frsh_renegotiation_status_t *renegotiation_status)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_group_get_status
+ (const frsh_group_id_t group,
+ frsh_renegotiation_status_t *status,
+ frsh_vres_group_t *new_vres)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_vres_get_budget_and_period
+ (const frsh_vres_id_t vres,
+ frsh_rel_time_t *budget,
+ frsh_rel_time_t *period)
+{
+ fres_block_basic *basic;
+
+ if (!vres) return FRSH_ERR_BAD_ARGUMENT;
+
+ /* TODO: Reference counting */
+ basic = fres_contract_get_basic(vres->perceived);
+ if (!basic) return FRSH_ERR_NOT_INITIALIZED;
+
+ if (budget)
+ *budget = basic->budget;
+ if (period)
+ *period = basic->period;
+
+ return 0;
+}
+
+int frsh_vres_get_usage
+ (const frsh_vres_id_t vres,
+ frsh_rel_time_t *spent)
+{
+ if (!vres || !spent) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+ if (vres->allocator->vres_get_usage) {
+ return vres->allocator->vres_get_usage(vres, spent);
+ } else {
+ return FRSH_ERR_NOT_IMPLEMENTED;
+ }
+}
+
+int frsh_vres_get_job_usage
+ (const frsh_vres_id_t vres,
+ frsh_rel_time_t *spent)
+{
+ if (!vres || !spent) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+ if (vres->allocator->vres_get_job_usage) {
+ return vres->allocator->vres_get_job_usage(vres, spent);
+ } else {
+ return FRSH_ERR_NOT_IMPLEMENTED;
+ }
+}
+
+int frsh_vres_get_remaining_budget
+ (const frsh_vres_id_t vres,
+ frsh_rel_time_t *budget)
+{
+ if (!vres || !budget) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+ if (vres->allocator->vres_get_remaining_budget) {
+ return vres->allocator->vres_get_remaining_budget(vres, budget);
+ } else {
+ return FRSH_ERR_NOT_IMPLEMENTED;
+ }
+}
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+CFLAGS += -DWVTEST_CONFIGURED
+
+wvtest_SCRIPTS += negotiation.sh
+test_PROGRAMS += negotiation
+negotiation_SOURCES = negotiation.c
+negotiation_LIBS = wvtest
+
+test_PROGRAMS += spare_capacity
+spare_capacity_SOURCES = spare_capacity.c
+
+ifeq ($(CONFIG_AQUOSA),y)
+test_PROGRAMS += cpu_spare_capacity
+cpu_spare_capacity_SOURCES = cpu_spare_capacity.c
+
+test_PROGRAMS += cpu_renegotiation
+cpu_renegotiation_SOURCES = cpu_renegotiation.c
+endif
+
+test_PROGRAMS += dummy_renegotiation
+dummy_renegotiation_SOURCES = dummy_renegotiation.c
+
+wvtest_SCRIPTS += dummy_spare_capacity.sh
+test_PROGRAMS += dummy_spare_capacity
+dummy_spare_capacity_SOURCES = dummy_spare_capacity.c
+dummy_spare_capacity_LIBS = wvtest
+
+wvtest_SCRIPTS += trans_nego.sh
+test_PROGRAMS += trans_nego
+trans_nego_SOURCES = trans_nego.c
+trans_nego_LIBS = wvtest
+test_PROGRAMS += trans_nego2
+trans_nego2_SOURCES = trans_nego2.c
+trans_nego2_LIBS = wvtest
+
+test_PROGRAMS += negobench
+negobench_SOURCES = negobench.c
+
+test_PROGRAMS += renegobench
+renegobench_SOURCES = renegobench.c
+
+test_PROGRAMS += scbench
+scbench_SOURCES = scbench.c
+
+lib_LOADLIBES += pthread rt frsh
+
+ifeq ($(CONFIG_FWP),y)
+SUBDIRS= fwptest pingpong
+endif
+
+ifeq ($(CONFIG_ORTE_TEST),y)
+test_PROGRAMS += orte_test
+orte_test_SOURCES+= orte_test.c
+lib_LOADLIBES += pthread rt fwp fna frsh
+endif
--- /dev/null
+#include <frsh.h>
+#include <aqcpu_res.h>
+#include <error.h>
+#include <signal.h>
+#include <getopt.h>
+#include <ul_logreg.h>
+
+volatile int finish = 0;
+
+void int_handler(int signal)
+{
+ finish = 1;
+}
+
+void* work_thread()
+{
+ int ret;
+ unsigned long i = 0;
+ volatile int j;
+ frsh_vres_id_t vres_id;
+ frsh_rel_time_t budget;
+ frsh_rel_time_t period;
+
+ while(!finish) {
+ i++;
+
+ for (j=0; j<1000000; j++);
+
+ ret = frsh_thread_get_vres_id(fosa_thread_self(), &vres_id);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_get_vres_id");
+
+ ret = frsh_vres_get_budget_and_period(vres_id, &budget, &period);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_vres_get_budget_and_period");
+
+ printf("Consuming budget %ld ms - %lu\n",
+ fosa_rel_time_to_msec(budget), i);
+ }
+
+ return EXIT_SUCCESS;
+}
+
+static struct option long_opts[] = {
+ { "loglevel", 1, 0, 'l' },
+ { 0, 0, 0, 0}
+};
+
+static void
+usage(void)
+{
+ printf("usage: cpu_renegotiation [ options ]\n");
+ printf(" -l, --loglevel <number>|<domain>=<number>,...\n");
+}
+
+
+#define MSEC(x) { x/1000, (x%1000) * 1000000 }
+frsh_utilization_set_t utilization_set = {
+ .size = 3,
+ .utilizations = {
+ { .budget = MSEC(10), .period = MSEC(100), .deadline = MSEC(100) },
+ { .budget = MSEC(20), .period = MSEC(100), .deadline = MSEC(100) },
+ { .budget = MSEC(30), .period = MSEC(100), .deadline = MSEC(100) },
+ },
+};
+
+int main(int argc, char *argv[])
+{
+ frsh_vres_id_t vres;
+ frsh_thread_attr_t attr;
+ frsh_thread_id_t thread;
+ frsh_contract_t contract;
+ int ret;
+ char opt;
+
+ while ((opt = getopt_long(argc, argv, "l:", &long_opts[0], NULL)) != EOF) {
+ switch (opt) {
+ case 'l':
+ ul_log_domain_arg2levels(optarg);
+ break;
+ case 'h':
+ /*default:*/
+ usage();
+ exit(opt == 'h' ? 0 : 1);
+ }
+ }
+
+ ret = frsh_init();
+ if (ret) PERROR_AND_EXIT(ret, "frsh_init");
+
+ signal(SIGINT, int_handler);
+ signal(SIGTERM, int_handler);
+
+ /* Contract negotiation for CPU */
+ ret = frsh_contract_init(&contract);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ int variant = 0;
+ bool first = true;
+ while (!finish) {
+
+ ret = frsh_contract_set_basic_params(&contract,
+ &utilization_set.utilizations[variant].budget,
+ &utilization_set.utilizations[variant].period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+
+ ret = frsh_contract_set_resource_and_label(&contract, FRSH_RT_PROCESSOR,
+ FRSH_CPU_ID_DEFAULT, "renegotiation test");
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ if (first) {
+ ret = frsh_contract_negotiate(&contract, &vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+
+ printf("Aqcpu vres negotiated, vres-ID: %p\n", vres);
+ pthread_attr_init(&attr);
+ ret = frsh_thread_create_and_bind(vres, &thread, &attr,
+ work_thread, (void*) NULL);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_thread_create_and_bind");
+ first = false;
+ } else {
+ ret = frsh_contract_renegotiate_sync(&contract, vres);
+ if (ret == 0) {
+ printf("Renegotiation accepted\n");
+ } else if (ret == FRSH_ERR_CONTRACT_REJECTED) {
+ printf("Renegotiaton REJECTED\n");
+ } else
+ PERROR_AND_EXIT(ret, "frsh_contract_renegotiate_sync");
+ }
+ sleep(5);
+ variant++;
+ if (variant >= utilization_set.size) variant = 0;
+ }
+
+ pthread_join(thread.pthread_id, (void**) NULL);
+
+ ret = frsh_contract_cancel(vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_cancel");
+
+ return 0;
+}
+
--- /dev/null
+#include <frsh.h>
+#include <aqcpu_res.h>
+#include <error.h>
+#include <signal.h>
+#include <getopt.h>
+#include <ul_logreg.h>
+
+volatile int finish = 0;
+
+void int_handler(int signal)
+{
+ finish = 1;
+}
+
+void* work_thread()
+{
+ int ret;
+ unsigned long i = 0;
+ volatile int j;
+ frsh_vres_id_t vres_id;
+ frsh_rel_time_t budget;
+ frsh_rel_time_t period;
+
+ while(!finish) {
+ i++;
+
+ for (j=0; j<1000000; j++);
+
+ ret = frsh_thread_get_vres_id(fosa_thread_self(), &vres_id);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_get_vres_id");
+
+ ret = frsh_vres_get_budget_and_period(vres_id, &budget, &period);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_vres_get_budget_and_period");
+
+ printf("Consuming budget %ld ms - %lu\n",
+ fosa_rel_time_to_msec(budget), i);
+ }
+
+ return EXIT_SUCCESS;
+}
+
+static struct option long_opts[] = {
+ { "loglevel", 1, 0, 'l' },
+ { 0, 0, 0, 0}
+};
+
+static void
+usage(void)
+{
+ printf("usage: cpu_spare_capacity [ options ]\n");
+ printf(" -l, --loglevel <number>|<domain>=<number>,...\n");
+}
+
+
+#define MSEC(x) { x/1000, (x%1000) * 1000000 }
+frsh_utilization_set_t utilization_set = {
+ .size = 2,
+ .utilizations = {
+ { .budget = MSEC(20), .period = MSEC(100), .deadline = MSEC(100) },
+ { .budget = MSEC(50), .period = MSEC(100), .deadline = MSEC(100) },
+ },
+};
+
+int main(int argc, char *argv[])
+{
+ frsh_vres_id_t vres;
+ frsh_thread_attr_t attr;
+ frsh_thread_id_t thread;
+ frsh_contract_t contract;
+ frsh_rel_time_t zero = fosa_msec_to_rel_time(0);
+ int ret;
+ char opt;
+
+ while ((opt = getopt_long(argc, argv, "l:", &long_opts[0], NULL)) != EOF) {
+ switch (opt) {
+ case 'l':
+ ul_log_domain_arg2levels(optarg);
+ break;
+ case 'h':
+ /*default:*/
+ usage();
+ exit(opt == 'h' ? 0 : 1);
+ }
+ }
+
+ ret = frsh_init();
+ if (ret) PERROR_AND_EXIT(ret, "frsh_init");
+
+ signal(SIGINT, int_handler);
+ signal(SIGTERM, int_handler);
+
+ /* Contract negotiation for CPU */
+ ret = frsh_contract_init(&contract);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ ret = frsh_contract_set_basic_params(&contract,
+ &utilization_set.utilizations[0].budget,
+ &utilization_set.utilizations[0].period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+
+ ret = frsh_contract_set_resource_and_label(&contract, FRSH_RT_PROCESSOR,
+ FRSH_CPU_ID_DEFAULT, "spare cap test");
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ ret = frsh_contract_set_reclamation_params(&contract,
+ &zero,
+ &utilization_set.utilizations[utilization_set.size-1].budget,
+ &utilization_set.utilizations[utilization_set.size-1].period,
+ FRSH_GR_DISCRETE,
+ &utilization_set,
+ 0,
+ 0);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_reclamation_params");
+
+ ret = frsh_contract_negotiate(&contract, &vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+
+ printf("Aqcpu vres negotiated, vres-ID: %p\n", vres);
+ pthread_attr_init(&attr);
+ ret = frsh_thread_create_and_bind(vres, &thread, &attr,
+ work_thread, (void*) NULL);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_thread_create_and_bind");
+
+ pthread_join(thread.pthread_id, (void**) NULL);
+
+ ret = frsh_contract_cancel(vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_cancel");
+
+ return 0;
+}
+
--- /dev/null
+#include <frsh.h>
+#include <error.h>
+#include <signal.h>
+#include <getopt.h>
+#include <ul_logreg.h>
+#include <res_dummy.h>
+
+volatile int finish = 0;
+
+void int_handler(int signal)
+{
+ finish = 1;
+}
+
+static struct option long_opts[] = {
+ { "loglevel", 1, 0, 'l' },
+ { 0, 0, 0, 0}
+};
+
+static void
+usage(void)
+{
+ printf("usage: cpu_renegotiation [ options ]\n");
+ printf(" -l, --loglevel <number>|<domain>=<number>,...\n");
+}
+
+
+#define MSEC(x) { x/1000, (x%1000) * 1000000 }
+frsh_utilization_set_t utilization_set = {
+ .size = 3,
+ .utilizations = {
+ { .budget = MSEC(10), .period = MSEC(100), .deadline = MSEC(100) },
+ { .budget = MSEC(20), .period = MSEC(100), .deadline = MSEC(100) },
+ { .budget = MSEC(30), .period = MSEC(100), .deadline = MSEC(100) },
+ },
+};
+
+int main(int argc, char *argv[])
+{
+ frsh_vres_id_t vres;
+ frsh_contract_t contract;
+ int ret;
+ char opt;
+
+ while ((opt = getopt_long(argc, argv, "l:", &long_opts[0], NULL)) != EOF) {
+ switch (opt) {
+ case 'l':
+ ul_log_domain_arg2levels(optarg);
+ break;
+ case 'h':
+ /*default:*/
+ usage();
+ exit(opt == 'h' ? 0 : 1);
+ }
+ }
+
+ ret = frsh_init();
+ if (ret) PERROR_AND_EXIT(ret, "frsh_init");
+
+ signal(SIGINT, int_handler);
+ signal(SIGTERM, int_handler);
+
+ /* Contract negotiation for CPU */
+ ret = frsh_contract_init(&contract);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ int variant = 0;
+ bool first = true;
+ while (!finish) {
+
+ ret = frsh_contract_set_basic_params(&contract,
+ &utilization_set.utilizations[variant].budget,
+ &utilization_set.utilizations[variant].period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+
+ ret = frsh_contract_set_resource_and_label(&contract,
+ DUMMY_RESOURCE_TYPE, DUMMY_RESOURCE_ID,
+ "renegotiation test");
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ if (first) {
+ ret = frsh_contract_negotiate(&contract, &vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+ first = false;
+ } else {
+ ret = frsh_contract_renegotiate_sync(&contract, vres);
+ if (ret == 0) {
+ printf("Renegotiation accepted\n");
+ } else if (ret == FRSH_ERR_CONTRACT_REJECTED) {
+ printf("Renegotiaton REJECTED\n");
+ } else
+ PERROR_AND_EXIT(ret, "frsh_contract_renegotiate_sync");
+ }
+ sleep(5);
+ variant++;
+ if (variant >= utilization_set.size) variant = 0;
+ }
+
+ ret = frsh_contract_cancel(vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_cancel");
+
+ return 0;
+}
+
--- /dev/null
+#include <frsh.h>
+#include <error.h>
+#include <signal.h>
+#include <getopt.h>
+#include <ul_logreg.h>
+#include <res_dummy.h>
+#include <semaphore.h>
+#include <wvtest.h>
+
+#define MSEC(x) { x/1000, (x%1000) * 1000000 }
+frsh_utilization_set_t utilization_set = {
+ .size = 2,
+ .utilizations = {
+ { .budget = MSEC(20), .period = MSEC(100), .deadline = MSEC(100) },
+ { .budget = MSEC(50), .period = MSEC(100), .deadline = MSEC(100) },
+ },
+};
+
+frsh_vres_id_t vres[5];
+
+void
+get_min_max_budget(int count, int *min, int*max)
+{
+ frsh_contract_t c;
+ fosa_rel_time_t budget;
+ int i, b;
+
+ *max = 0;
+ *min = 10000;
+
+ for (i=0; i<count; i++) {
+ WVFRSH(frsh_vres_get_contract(vres[i], &c));
+ WVPASS(fres_contract_get_budget(&c, &budget));
+ b = fosa_rel_time_to_msec(budget);
+ if (b < *min)
+ *min = b;
+ if (b > *max)
+ *max = b;
+ }
+}
+
+WVTEST_MAIN("spare capacity")
+{
+ frsh_contract_t contract;
+ frsh_rel_time_t zero = fosa_msec_to_rel_time(0);
+ int ret;
+ int min, max;
+
+/* ul_log_domain_arg2levels(optarg); */
+
+ setenv("WVTEST_DIE_FAST", "", 1);
+ WVFRSH(frsh_init());
+
+ /* Contract negotiation for CPU */
+ ret = WVFRSH(frsh_contract_init(&contract));
+
+ ret = WVFRSH(frsh_contract_set_basic_params(&contract,
+ &utilization_set.utilizations[0].budget,
+ &utilization_set.utilizations[0].period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR));
+
+ ret = WVFRSH(frsh_contract_set_resource_and_label(&contract ,
+ DUMMY_RESOURCE_TYPE, DUMMY_RESOURCE_ID,
+ "spare cap test"));
+
+ ret = WVFRSH(frsh_contract_set_reclamation_params(&contract,
+ &zero,
+ &utilization_set.utilizations[utilization_set.size-1].budget,
+ &utilization_set.utilizations[utilization_set.size-1].period,
+ FRSH_GR_DISCRETE,
+ &utilization_set,
+ 0,
+ 0));
+
+ WVFRSH(frsh_contract_negotiate(&contract, &vres[0]));
+ get_min_max_budget(1, &min, &max);
+ WVPASS(min == 50 && max == 50);
+
+ WVFRSH(frsh_contract_negotiate(&contract, &vres[1]));
+ get_min_max_budget(2, &min, &max);
+ WVPASS(min == 20 && max == 50);
+
+ WVFRSH(frsh_contract_negotiate(&contract, &vres[2]));
+ get_min_max_budget(3, &min, &max);
+ WVPASS(min == 20 && max == 50);
+
+ WVFRSH(frsh_contract_negotiate(&contract, &vres[3]));
+ get_min_max_budget(4, &min, &max);
+ WVPASS(min == 20 && max == 20);
+
+
+ ret = WVFRSH(frsh_contract_cancel(vres[0]));
+ ret = WVFRSH(frsh_contract_cancel(vres[1]));
+ ret = WVFRSH(frsh_contract_cancel(vres[2]));
+ ret = WVFRSH(frsh_contract_cancel(vres[3]));
+ frsh_destroy();
+}
+
--- /dev/null
+#!/bin/bash
+
+. $(dirname $0)/wvtest.sh
+
+setup_dummy
+WVPASS dummy_spare_capacity
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+ifeq ($(CONFIG_FWP),y)
+test_PROGRAMS += fwpreceiver fwpsender fwpnego
+fwpreceiver_SOURCES+= fwpreceiver.c
+fwpsender_SOURCES+= fwpsender.c
+fwpnego_SOURCES = fwpnego.c
+lib_LOADLIBES += pthread rt fwp fna frsh
+endif
--- /dev/null
+#include <frsh.h>
+#include <error.h>
+#include <res_dummy.h>
+
+#define N 3
+
+int b[N] = { 10, 20, 30 };
+
+int main(int argc, char *argv[])
+{
+ int ret;
+ frsh_contract_t contract[N];
+ frsh_vres_id_t vres[N];
+ frsh_rel_time_t budget, period, deadline;
+ int i;
+
+ ret = frsh_init();
+ if (ret) PERROR_AND_EXIT(ret, "frsh_init");
+
+ /* Negotiate N contracts */
+ for (i=0; i<N; i++) {
+ ret = frsh_contract_init(&contract[i]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ ret = frsh_contract_set_resource_and_label(
+ &contract[i],
+ FRSH_RT_NETWORK, FRSH_NETPF_FWP,
+ NULL);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ frsh_network_bytes_to_budget(FRSH_NETPF_FWP, b[i], &budget);
+ period = fosa_msec_to_rel_time(1000);
+ deadline = fosa_msec_to_rel_time(500);
+ ret = frsh_contract_set_basic_params(&contract[i],
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+
+ ret = frsh_contract_set_timing_reqs(&contract[i],
+ false, &deadline);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_timing_reqs");
+
+ ret = frsh_contract_negotiate(&contract[i], &vres[i]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+ }
+ for (i=0; i<N; i++) {
+ frsh_network_bytes_to_budget(FRSH_NETPF_FWP, 2*b[i], &budget);
+ period = fosa_msec_to_rel_time(1100);
+ ret = frsh_contract_set_basic_params(&contract[i],
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params reneg");
+
+ ret = frsh_contract_renegotiate_sync(&contract[i], vres[i]);
+
+ }
+
+ /* Cancel N contracts */
+ for (i=0; i<N; i++) {
+ ret = frsh_contract_cancel(vres[i]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_cancel");
+ }
+ return 0;
+}
--- /dev/null
+#include <frsh.h>
+#include "test_config.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <pthread.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+char msg[MSGBUFFSIZE];
+
+frsh_resource_id_t resource_id = TEST_RESOURCE_ID;
+frsh_stream_id_t stream_id = TEST_STREAM_ID;
+long int num_msg = TEST_NUM_MSG;
+size_t msg_size = MSGBUFFSIZE;
+
+void* receiver()
+{
+ size_t len;
+ frsh_receive_endpoint_t repoint;
+ int count;
+ //struct timespec recvtime;
+ frsh_network_address_t from;
+ frsh_receive_endpoint_protocol_info_t recv_pinfo;
+ frsh_endpoint_queueing_info_t qinfo;
+
+ recv_pinfo.body = NULL;
+ /* local_addr should be handled when creating socket */
+ if (frsh_receive_endpoint_create(resource_id, stream_id, qinfo, recv_pinfo,
+ &repoint) != 0){
+ return NULL;
+ }
+ printf("Receive endpoint created\n");
+
+ count = 1;
+ while (count != num_msg){
+ count++;
+ if ((frsh_receive_sync(repoint, msg, msg_size, &len,
+ &from))){
+ perror("Error while receiving data");
+ return NULL;
+ }
+ else printf("Received - %s\n", msg);
+ }
+
+ /* TODO: destroy vres and send enpoint */
+
+ return NULL;
+}
+
+int main(int argc, char* argv[])
+{
+ pthread_attr_t thattr;
+ pthread_t thread;
+ int ret;
+ int opt;
+
+ opterr = 0;
+
+ while ((opt = getopt (argc, argv, "p:m:")) != -1) {
+
+ switch (opt) {
+ case 'p':
+ stream_id = atoi(optarg);
+ break;
+ case 'm':
+ num_msg = atoi(optarg);
+ case '?':
+ printf("Usage: %s -p stream_id -m num_msg\n",
+ argv[0]);
+ }
+ }
+
+ ret = frsh_init();
+ if (ret) PERROR_AND_EXIT(ret, "frsh_init");
+
+ pthread_attr_init(&thattr);
+ pthread_create(&thread, &thattr, receiver, NULL);
+ pthread_join(thread, (void**) NULL);
+
+ printf("Test PASSED!\n");
+ return 0;
+}
--- /dev/null
+/**
+ * \file fwpsender.c
+ *
+ */
+#include <frsh.h>
+#include "test_config.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <pthread.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+char msg[MSGBUFFSIZE];
+
+frsh_resource_id_t resource_id = TEST_RESOURCE_ID;
+frsh_stream_id_t stream_id = TEST_STREAM_ID;
+long int num_msg = TEST_NUM_MSG;
+size_t msg_size = MSGBUFFSIZE;
+
+int exit_flag = 0;
+int node_id = 0;
+
+void* sender(void * arg)
+{
+ frsh_send_endpoint_t sepoint;
+ frsh_vres_id_t vres;
+ frsh_send_endpoint_protocol_info_t send_pinfo;
+ frsh_contract_t contract;
+ frsh_rel_time_t budget, period;
+ int count, ret;
+ /*struct timespec sendtime;*/
+
+ send_pinfo.body = NULL;
+ if (frsh_send_endpoint_create(resource_id, node_id, stream_id,
+ send_pinfo, &sepoint)< 0) {
+ return NULL;
+ }
+
+ /* Contract negotiation */
+ ret = frsh_contract_init(&contract);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ frsh_network_bytes_to_budget(resource_id, msg_size, &budget);
+ period = fosa_msec_to_rel_time(1000);
+ ret = frsh_contract_set_basic_params(&contract,
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+ ret = frsh_contract_set_resource_and_label(&contract,FRSH_RT_NETWORK,
+ resource_id, "net_cont1");
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ ret = frsh_contract_negotiate(&contract, &vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+
+ printf("Send endpoint created\n");
+ frsh_send_endpoint_bind(vres, sepoint);
+ printf("Send endpoint bounded\n");
+
+ sleep(2);
+ //fwp_set_rt_prio(90);
+
+ count = 1;
+ while (count != num_msg) {
+ count++;
+ sprintf(msg,"msg%d",count);
+ frsh_send_async(sepoint, msg, msg_size);
+
+ printf("%s sent\n",msg);
+ }
+
+ /* TODO: destroy vres and send enpoint */
+
+ while (!(exit_flag)) {
+ sleep(1);
+ }
+
+ return NULL;
+}
+
+int main(int argc, char* argv[])
+{
+ pthread_attr_t thattr;
+ pthread_t thread;
+ int opt;
+ int ret;
+
+ opterr = 0;
+ while ((opt = getopt (argc, argv, "n:p:s:m:")) != -1) {
+
+ switch (opt) {
+ case 'n':
+ node_id = inet_addr(optarg);
+ break;
+ case 'p':
+ stream_id = atoi(optarg);
+ break;
+ case 'm':
+ num_msg = atoi(optarg);
+ break;
+ case 's':
+ msg_size = atoi(optarg);
+ break;
+ case '?':
+ printf("Usage: %s -n node_id -p stream_id"
+ "-m num_msg -s msg_size\n",
+ argv[0]);
+ }
+ }
+
+ ret = frsh_init();
+ if (ret) PERROR_AND_EXIT(ret, "frsh_init");
+
+ pthread_attr_init(&thattr);
+ pthread_create(&thread, &thattr, sender, NULL);
+ pthread_join(thread, (void**) NULL);
+
+ printf("Test PASSED!\n");
+ return 0;
+}
--- /dev/null
+#include <frsh.h>
+#include "test_config.h"
+
+
+
--- /dev/null
+/**
+ * The test:
+ * - creates vres
+ * - creates send and receive endpoint
+ * - binds that endpoint to vres
+ * - in cycle (NUM loops) sends/receives messages
+ * - destroys vres
+ *
+ */
+#ifndef TEST_CONFIG_H
+#define TEST_CONFIG_H
+
+#include <frsh.h>
+
+#define MSGBUFFSIZE 65000
+#define TEST_RESOURCE_ID FRSH_NETPF_FWP
+#define TEST_STREAM_ID 65111
+/* Number of test messages sent/received
+ * 0 - infinite
+ */
+#define TEST_NUM_MSG 40
+
+#endif /* TEST_CONFIG_H */
--- /dev/null
+#include <frsh.h>
+#include <error.h>
+#include <res_dummy.h>
+#include <time.h>
+
+int n = 1000;
+
+int main(int argc, char *argv[])
+{
+ int ret;
+ frsh_contract_t *contract;
+ frsh_vres_id_t *vres;
+ frsh_rel_time_t budget, period, deadline;
+ int i;
+
+ if (argc > 1) {
+ n = atol(argv[1]);
+ if (n <= 0) {
+ fprintf(stderr, "First argument must be greater than zero\n");
+ exit(1);
+ }
+ }
+ fprintf(stderr, "Going to negotiate %d contracts\n", n);
+ contract = malloc(n*sizeof(*contract));
+ vres = malloc(n*sizeof(*vres));
+
+ ret = frsh_init();
+ if (ret) PERROR_AND_EXIT(ret, "frsh_init");
+
+ /* Negotiate N contracts */
+ for (i=0; i<n; i++) {
+ struct timespec t_start, t_end;
+ clock_gettime(CLOCK_MONOTONIC, &t_start);
+ ret = frsh_contract_init(&contract[i]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ ret = frsh_contract_set_resource_and_label(
+ &contract[i],
+ DUMMY_RESOURCE_TYPE, DUMMY_RESOURCE_ID,
+ NULL);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ budget = fosa_msec_to_rel_time(10);
+ period = fosa_msec_to_rel_time(100);
+ period = fosa_msec_to_rel_time(50);
+ ret = frsh_contract_set_basic_params(&contract[i],
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+
+ ret = frsh_contract_set_timing_reqs(&contract[i],
+ false, &deadline);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_timing_reqs");
+
+ ret = frsh_contract_negotiate(&contract[i], &vres[i]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+ clock_gettime(CLOCK_MONOTONIC, &t_end);
+ uint64_t ns;
+ ns = (uint64_t)(t_end.tv_sec - t_start.tv_sec)*1000000000;
+ ns += t_end.tv_nsec - t_start.tv_nsec;
+ printf("%d %d.%09d\n", i, (int)(ns/1000000000), (int)(ns%1000000000));
+ }
+ /* Cancel N contracts */
+ for (i=0; i<n; i++) {
+ ret = frsh_contract_cancel(vres[i]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_cancel");
+ }
+ free(contract);
+ free(vres);
+ return 0;
+}
--- /dev/null
+#include <frsh.h>
+#include <error.h>
+#include <res_dummy.h>
+#include <getopt.h>
+#include <ul_logreg.h>
+#include <wvtest.h>
+
+#define N 3
+
+int b[N] = { 10, 20, 30 };
+
+// TODO: Allow specifying loglevel in evironment
+
+// static struct option long_opts[] = {
+// { "loglevel", 1, 0, 'l' },
+// { 0, 0, 0, 0}
+// };
+
+// static void
+// usage(void)
+// {
+// printf("usage: negotiation [ options ]\n");
+// printf(" -l, --loglevel <number>|<domain>=<number>,...\n");
+// }
+
+int ret;
+frsh_contract_t contract[N], c;
+frsh_vres_id_t vres[N];
+frsh_rel_time_t budget, period, deadline;
+int i;
+
+WVTEST_MAIN("basic negotiation")
+{
+// char opt;
+
+// while ((opt = getopt_long(argc, argv, "l:", &long_opts[0], NULL)) != EOF) {
+// switch (opt) {
+// case 'l':
+// break;
+// case 'h':
+// /\*default:*\/
+// usage();
+// exit(opt == 'h' ? 0 : 1);
+// }
+// }
+
+ setenv("WVTEST_DIE_FAST", "", 1);
+ ret = WVFRSH(frsh_init());
+
+ /* Negotiate N contracts */
+ for (i=0; i<N; i++) {
+ ret = WVFRSH(frsh_contract_init(&contract[i]));
+
+ ret = WVFRSH(frsh_contract_set_resource_and_label(
+ &contract[i],
+ DUMMY_RESOURCE_TYPE, DUMMY_RESOURCE_ID,
+ NULL));
+
+ budget = fosa_msec_to_rel_time(b[i]);
+ period = fosa_msec_to_rel_time(100);
+ deadline = fosa_msec_to_rel_time(50);
+ ret = WVFRSH(frsh_contract_set_basic_params(&contract[i],
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR));
+
+ ret = WVFRSH(frsh_contract_set_timing_reqs(&contract[i],
+ false, &deadline));
+
+ ret = WVFRSH(frsh_contract_negotiate(&contract[i], &vres[i]));
+ WVFRSH(frsh_vres_get_contract(vres[i], &c));
+ WVPASS(fres_contract_get_budget(&c, &budget));
+ WVPASS(fosa_rel_time_to_msec(budget) == b[i]);
+ }
+}
+
+WVTEST_MAIN("renegotiation")
+{
+ for (i=0; i<2; i++) {
+ budget = fosa_msec_to_rel_time(2*b[i]);
+ period = fosa_msec_to_rel_time(110);
+ ret = WVFRSH(frsh_contract_set_basic_params(&contract[i],
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR));
+
+ ret = WVFRSH(frsh_contract_renegotiate_sync(&contract[i], vres[i]));
+ WVFRSH(frsh_vres_get_contract(vres[i], &c));
+ WVPASS(fres_contract_get_budget(&c, &budget));
+ WVPASS(fosa_rel_time_to_msec(budget) == 2*b[i]);
+ }
+
+ budget = fosa_msec_to_rel_time(2*b[2]);
+ period = fosa_msec_to_rel_time(110);
+ ret = WVFRSH(frsh_contract_set_basic_params(&contract[2],
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR));
+
+ WVPASS(frsh_contract_renegotiate_sync(&contract[2], vres[2]) == FRSH_ERR_CONTRACT_REJECTED);
+ WVFRSH(frsh_vres_get_contract(vres[i], &c));
+ WVPASS(fres_contract_get_budget(&c, &budget));
+ WVPASS(fosa_rel_time_to_msec(budget) == b[i]);
+}
+
+WVTEST_MAIN("cancelation")
+{
+ /* Cancel N contracts */
+ for (i=0; i<N; i++) {
+ ret = WVFRSH(frsh_contract_cancel(vres[i]));
+ }
+
+ frsh_destroy();
+}
--- /dev/null
+#!/bin/bash
+
+. $(dirname $0)/wvtest.sh
+
+setup_dummy
+WVPASS negotiation
--- /dev/null
+/**
+ * \file distributed.c
+ *
+ * This a test application that:
+ * - creates vres
+ * - creates send and receive endpoint
+ * - binds that endpoint to vres
+ * - in cycle (NUM loops) sends messages in separate thread and
+ * prints send time
+ * - receives messages in separate receiver thread
+ * - destroys vres
+ *
+ */
+#include "frsh.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <pthread.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#define NUM 10
+#define PORT 65111
+#define PROTO FRSH_NETPF_FWP
+
+int exit_flag = 0;
+
+void* sender()
+{
+ frsh_send_endpoint_t sepoint;
+ frsh_vres_id_t vres;
+ frsh_send_endpoint_protocol_info_t send_pinfo;
+ frsh_contract_t contract;
+ frsh_rel_time_t budget, period;
+ char msg1[10];
+ int count, ret;
+ /*struct timespec sendtime;*/
+
+ send_pinfo.body = NULL;
+ if (frsh_send_endpoint_create(PROTO, inet_addr("127.0.0.1"), PORT,
+ send_pinfo, &sepoint)< 0) {
+ return NULL;
+ }
+
+ /* Contract negotiation */
+ ret = frsh_contract_init(&contract);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ budget = fosa_msec_to_rel_time(100);
+ period = fosa_msec_to_rel_time(1000);
+ ret = frsh_contract_set_basic_params(&contract,
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+ ret = frsh_contract_set_resource_and_label(&contract,FRSH_RT_NETWORK,
+ FRSH_NETPF_FWP,
+ "fwp_cont1");
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ ret = frsh_contract_negotiate(&contract, &vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+
+ printf("Send endpoint created\n");
+ frsh_send_endpoint_bind(vres, sepoint);
+ printf("Send endpoint bounded\n");
+
+ sleep(2);
+ //fwp_set_rt_prio(90);
+
+ count = 0;
+ while (count < NUM){
+ count++;
+ sprintf(msg1,"msg%d",count);
+ frsh_send_async(sepoint, msg1, sizeof(msg1));
+
+ printf("%s sent\n",msg1);
+ /*clock_gettime(CLOCK_MONOTONIC, &sendtime);
+ FWP_DEBUG("Sent %d: sec = %ld nsec = %ld \n", count,
+ sendtime.tv_sec, sendtime.tv_nsec);
+ usleep(1000);*/
+ }
+
+ while (!(exit_flag)) {
+ sleep(1);
+ }
+
+ return NULL;
+}
+
+void* receiver()
+{
+ size_t len;
+ char buffer[30];
+ frsh_receive_endpoint_t repoint;
+ int count;
+ struct timespec recvtime;
+ frsh_network_address_t from;
+ frsh_receive_endpoint_protocol_info_t recv_pinfo;
+ frsh_endpoint_queueing_info_t qinfo;
+ frsh_resource_id_t resource_id;
+ frsh_stream_id_t stream;
+ frsh_endpoint_queueing_info_t queueing_info;
+ frsh_receive_endpoint_protocol_info_t protocol_info;
+
+ recv_pinfo.body = NULL;
+ /* local_addr should be handled when creating socket */
+// if (frsh_receive_endpoint_create(PROTO, PORT, qinfo, recv_pinfo,
+ if (frsh_receive_endpoint_create(PROTO, 0, qinfo, recv_pinfo,
+ &repoint) != 0){
+ return NULL;
+ }
+ printf("Receive endpoint created\n");
+
+ frsh_receive_endpoint_get_params(repoint,&resource_id,&stream,&queueing_info,&protocol_info);
+
+ printf("Receive port :%d\n",stream);
+
+
+ for (count = 1; count <= NUM; count++) {
+
+ if ((frsh_receive_sync(repoint, buffer, sizeof(buffer), &len,
+ &from))){
+ perror("Error while receiving data");
+ return NULL;
+ }
+ else printf("Received - %s\n", buffer);
+
+ clock_gettime(CLOCK_MONOTONIC, &recvtime);
+ printf("Received %d: sec = %ld nsec = %ld \n", count,
+ recvtime.tv_sec, recvtime.tv_nsec);
+ }
+
+ exit_flag = 1;
+
+ return NULL;
+}
+
+int main()
+{
+ pthread_attr_t thattr;
+ pthread_t thread;
+ int ret;
+
+ printf("Start\n");
+ ret = frsh_init();
+ if (ret) PERROR_AND_EXIT(ret, "frsh_init");
+
+ /*if (frsh_distributed_init()) {
+ fprintf(stderr,"FRSH distributed modul initialization failed.\n");
+ }*/
+
+ pthread_attr_init(&thattr);
+ pthread_create(&thread, &thattr, receiver, NULL);
+ pthread_create(&thread, &thattr, sender, NULL);
+ pthread_join(thread, (void**) NULL);
+
+ printf("Test PASSED!\n");
+ return 0;
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+ifeq ($(CONFIG_FWP),y)
+test_PROGRAMS += ping pong
+pong_SOURCES+= pong.c
+ping_SOURCES+= ping.c
+lib_LOADLIBES += pthread rt fwp fna frsh
+endif
--- /dev/null
+/**
+ * \file fwpsender.c
+ *
+ */
+#include <frsh.h>
+#include "test_config.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <pthread.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+char msg[MSGBUFFSIZE];
+
+frsh_resource_id_t resource_id = TEST_RESOURCE_ID;
+frsh_stream_id_t stream_id = TEST_STREAM_ID;
+long int num_msg = TEST_NUM_MSG;
+size_t msg_size = MSGBUFFSIZE;
+
+int exit_flag = 0;
+int node_id = 0;
+
+/** statistics */
+long unsigned int max = 0; /* maximum delay */
+long unsigned int min = ~0; /* minimum delay */
+long unsigned int avg = 0; /* average delay */
+
+
+inline void timespec_sub(struct timespec *diff, const struct timespec *left,
+ const struct timespec *right)
+{
+ diff->tv_sec = left->tv_sec - right->tv_sec;
+ diff->tv_nsec = left->tv_nsec - right->tv_nsec;
+
+ if (diff->tv_nsec < 0){
+ --diff->tv_sec;
+ diff->tv_nsec += 1000000000;
+ }
+}
+
+void* sender(void * arg)
+{
+ frsh_send_endpoint_t sepoint;
+ frsh_vres_id_t vres;
+ frsh_send_endpoint_protocol_info_t send_pinfo;
+ frsh_contract_t contract;
+ frsh_rel_time_t budget, period;
+ int count, ret;
+ struct timespec sendtime;
+
+ send_pinfo.body = NULL;
+ if (frsh_send_endpoint_create(resource_id, node_id, stream_id,
+ send_pinfo, &sepoint)< 0) {
+ return NULL;
+ }
+
+ /* Contract negotiation */
+ ret = frsh_contract_init(&contract);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ frsh_network_bytes_to_budget(resource_id, msg_size, &budget);
+ period = fosa_msec_to_rel_time(100);
+ ret = frsh_contract_set_basic_params(&contract,
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+ ret = frsh_contract_set_resource_and_label(&contract,FRSH_RT_NETWORK,
+ resource_id, "net_cont1");
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ ret = frsh_contract_negotiate(&contract, &vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+
+ printf("Send endpoint created\n");
+ frsh_send_endpoint_bind(vres, sepoint);
+ printf("Send endpoint bounded\n");
+
+ sleep(2);
+ //fwp_set_rt_prio(90);
+
+ count = 0;
+ while (count != num_msg) {
+ count++;
+ clock_gettime(CLOCK_MONOTONIC, &sendtime);
+ sprintf(msg,"msg%d-%ld-%ld", count,
+ sendtime.tv_sec, sendtime.tv_nsec);
+ frsh_send_async(sepoint, msg, msg_size);
+
+ printf("%s sent\n",msg);
+ }
+
+ /* TODO: destroy vres and send enpoint */
+
+ while (!(exit_flag)) {
+ sleep(1);
+ }
+
+ return NULL;
+}
+
+void* receiver()
+{
+ size_t len;
+ frsh_receive_endpoint_t repoint;
+ int count;
+ frsh_network_address_t from;
+ frsh_receive_endpoint_protocol_info_t recv_pinfo;
+ frsh_endpoint_queueing_info_t qinfo;
+ struct timespec recvtime;
+ struct timespec sendtime;
+ struct timespec difftime;
+ long int tmp;
+
+ recv_pinfo.body = NULL;
+ /* local_addr should be handled when creating socket */
+ if (frsh_receive_endpoint_create(resource_id, stream_id + 1, qinfo, recv_pinfo,
+ &repoint) != 0){
+ return NULL;
+ }
+ printf("Receive endpoint created\n");
+
+ count = 0;
+ while (count != num_msg){
+ count++;
+ if ((frsh_receive_sync(repoint, msg, msg_size, &len,
+ &from))) {
+ perror("Error while receiving data");
+ return NULL;
+ }
+
+ sscanf(msg,"msg%d-%ld-%ld", &count,
+ &sendtime.tv_sec, &sendtime.tv_nsec);
+ clock_gettime(CLOCK_MONOTONIC, &recvtime);
+ timespec_sub(&difftime, &recvtime, &sendtime);
+ tmp = difftime.tv_sec * 1000 +
+ difftime.tv_nsec / 1000000;
+
+ if (tmp > max)
+ max = tmp;
+ if (tmp < min)
+ min = tmp;
+ avg += tmp;
+
+ printf("Ping: Received - %s\n", msg);
+ }
+
+ printf("Min= %ld ms Max = %ld ms Avg = %ld ms\n", min, max, avg/count);
+ /* TODO: destroy vres and send enpoint */
+
+ exit_flag = 0;
+
+ return NULL;
+}
+
+int main(int argc, char* argv[])
+{
+ pthread_attr_t thattr;
+ pthread_t thread;
+ int opt;
+ int ret;
+
+ opterr = 0;
+ while ((opt = getopt (argc, argv, "n:p:s:m:")) != -1) {
+
+ switch (opt) {
+ case 'n':
+ node_id = inet_addr(optarg);
+ break;
+ case 'p':
+ stream_id = atoi(optarg);
+ break;
+ case 'm':
+ num_msg = atoi(optarg);
+ break;
+ case 's':
+ msg_size = atoi(optarg);
+ break;
+ case '?':
+ printf("Usage: %s -n node_id -p stream_id"
+ "-m num_msg -s msg_size\n",
+ argv[0]);
+ }
+ }
+
+ ret = frsh_init();
+ if (ret) PERROR_AND_EXIT(ret, "frsh_init");
+
+ pthread_attr_init(&thattr);
+ pthread_create(&thread, &thattr, receiver, NULL);
+ pthread_create(&thread, &thattr, sender, NULL);
+ pthread_join(thread, (void**) NULL);
+
+ printf("Test PASSED!\n");
+ return 0;
+}
--- /dev/null
+#include <frsh.h>
+#include "test_config.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <pthread.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+char msg[MSGBUFFSIZE];
+
+frsh_resource_id_t resource_id = TEST_RESOURCE_ID;
+frsh_stream_id_t stream_id = TEST_STREAM_ID;
+long int num_msg = TEST_NUM_MSG;
+size_t msg_size = MSGBUFFSIZE;
+
+frsh_send_endpoint_t sepoint;
+frsh_vres_id_t vres;
+
+/** statistics */
+long unsigned int max = 0; /* maximum delay */
+long unsigned int min = ~0; /* minimum delay */
+long unsigned int avg = 0; /* average delay */
+
+inline void timespec_sub(struct timespec *diff, const struct timespec *left,
+ const struct timespec *right)
+{
+ diff->tv_sec = left->tv_sec - right->tv_sec;
+ diff->tv_nsec = left->tv_nsec - right->tv_nsec;
+
+ if (diff->tv_nsec < 0){
+ --diff->tv_sec;
+ diff->tv_nsec += 1000000000;
+ }
+}
+
+void
+create_send_endpoint(frsh_network_address_t node_id, frsh_stream_id_t stream_id)
+{
+ frsh_send_endpoint_protocol_info_t send_pinfo;
+ frsh_contract_t contract;
+ frsh_rel_time_t budget, period;
+ int ret;
+
+ send_pinfo.body = NULL;
+ if (frsh_send_endpoint_create(resource_id, node_id, stream_id,
+ send_pinfo, &sepoint) < 0) {
+ return;
+ }
+
+ /* Contract negotiation */
+ ret = frsh_contract_init(&contract);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ frsh_network_bytes_to_budget(resource_id, msg_size, &budget);
+ period = fosa_msec_to_rel_time(100);
+ ret = frsh_contract_set_basic_params(&contract,
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+ ret = frsh_contract_set_resource_and_label(&contract,FRSH_RT_NETWORK,
+ resource_id, "net_cont1");
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ ret = frsh_contract_negotiate(&contract, &vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+
+ printf("Send endpoint created\n");
+ frsh_send_endpoint_bind(vres, sepoint);
+ printf("Send endpoint bounded\n");
+}
+
+void* receiver()
+{
+ size_t len;
+ frsh_receive_endpoint_t repoint;
+ int count;
+ //struct timespec recvtime;
+ frsh_network_address_t from;
+ frsh_receive_endpoint_protocol_info_t recv_pinfo;
+ frsh_endpoint_queueing_info_t qinfo;
+ int first = 1;
+
+ struct timespec recvtime;
+ struct timespec sendtime;
+ struct timespec difftime;
+ long int tmp;
+
+ recv_pinfo.body = NULL;
+ /* local_addr should be handled when creating socket */
+ if (frsh_receive_endpoint_create(resource_id, stream_id, qinfo, recv_pinfo,
+ &repoint) != 0){
+ return NULL;
+ }
+ printf("Receive endpoint created\n");
+
+ count = 0;
+ while (count != num_msg){
+ count++;
+ if ((frsh_receive_sync(repoint, msg, msg_size, &len,
+ &from))){
+ perror("Error while receiving data");
+ return NULL;
+ }
+
+ if (first) {
+ create_send_endpoint(from, stream_id + 1);
+ first = 0;
+ }
+
+ frsh_send_async(sepoint, msg, msg_size);
+ printf("pong - %s\n", msg);
+
+ sscanf(msg,"msg%d-%ld-%ld", &count,
+ &sendtime.tv_sec, &sendtime.tv_nsec);
+ clock_gettime(CLOCK_MONOTONIC, &recvtime);
+ timespec_sub(&difftime, &recvtime, &sendtime);
+ printf("Pong: Received - %s\n time= %ld us\n", msg,
+ difftime.tv_nsec / 1000);
+
+ tmp = difftime.tv_sec * 1000 +
+ difftime.tv_nsec / 1000000;
+
+ if (tmp > max)
+ max = tmp;
+ if (tmp < min)
+ min = tmp;
+ avg += tmp;
+ }
+
+ printf("Min= %ld ms Max = %ld ms Avg = %ld ms\n", min, max, avg/count);
+ sleep(3); /* wait to send back packet */
+ /* TODO: destroy vres and send enpoint */
+
+ return NULL;
+}
+
+int main(int argc, char* argv[])
+{
+ pthread_attr_t thattr;
+ pthread_t thread;
+ int ret;
+ int opt;
+
+ opterr = 0;
+
+ while ((opt = getopt (argc, argv, "p:m:")) != -1) {
+
+ switch (opt) {
+ case 'p':
+ stream_id = atoi(optarg);
+ break;
+ case 'm':
+ num_msg = atoi(optarg);
+ case '?':
+ printf("Usage: %s -p stream_id -m num_msg\n",
+ argv[0]);
+ }
+ }
+
+ ret = frsh_init();
+ if (ret) PERROR_AND_EXIT(ret, "frsh_init");
+
+ pthread_attr_init(&thattr);
+ pthread_create(&thread, &thattr, receiver, NULL);
+ pthread_join(thread, (void**) NULL);
+
+ printf("Test PASSED!\n");
+ return 0;
+}
--- /dev/null
+/**
+ * The test:
+ * - creates vres
+ * - creates send and receive endpoint
+ * - binds that endpoint to vres
+ * - in cycle (NUM loops) sends/receives messages
+ * - destroys vres
+ *
+ */
+#ifndef TEST_CONFIG_H
+#define TEST_CONFIG_H
+
+#include <frsh.h>
+
+#define MSGBUFFSIZE 65000
+#define TEST_RESOURCE_ID FRSH_NETPF_FWP
+#define TEST_STREAM_ID 65111
+/* Number of test messages sent/received
+ * 0 - infinite
+ */
+#define TEST_NUM_MSG 30
+
+#endif /* TEST_CONFIG_H */
--- /dev/null
+/* This program benchmarks renegotiation */
+
+#include <frsh.h>
+#include <error.h>
+#include <res_dummy.h>
+#include <time.h>
+
+#define N 1000
+
+int main(int argc, char *argv[])
+{
+ int ret;
+ frsh_contract_t contract[N];
+ frsh_vres_id_t vres[N];
+ frsh_rel_time_t budget, period, deadline;
+ int i;
+
+ ret = frsh_init();
+ if (ret) PERROR_AND_EXIT(ret, "frsh_init");
+
+ /* Negotiate N contracts */
+ for (i=0; i<N; i++) {
+ struct timespec t_start, t_end;
+ ret = frsh_contract_init(&contract[i]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ ret = frsh_contract_set_resource_and_label(
+ &contract[i],
+ DUMMY_RESOURCE_TYPE, DUMMY_RESOURCE_ID,
+ NULL);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ budget = fosa_msec_to_rel_time(10);
+ period = fosa_msec_to_rel_time(100);
+ period = fosa_msec_to_rel_time(50);
+ ret = frsh_contract_set_basic_params(&contract[i],
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+
+ ret = frsh_contract_set_timing_reqs(&contract[i],
+ false, &deadline);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_timing_reqs");
+
+ ret = frsh_contract_negotiate(&contract[i], &vres[i]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+ clock_gettime(CLOCK_MONOTONIC, &t_start);
+ ret = frsh_contract_renegotiate_sync(&contract[i], vres[i]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_renegotiate_sync");
+ clock_gettime(CLOCK_MONOTONIC, &t_end);
+ uint64_t ns;
+ ns = (uint64_t)(t_end.tv_sec - t_start.tv_sec)*1000000000;
+ ns += t_end.tv_nsec - t_start.tv_nsec;
+ printf("%d %d.%09d\n", i, (int)(ns/1000000000), (int)(ns%1000000000));
+ }
+ /* Cancel N contracts */
+ for (i=0; i<N; i++) {
+ ret = frsh_contract_cancel(vres[i]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_cancel");
+ }
+ return 0;
+}
--- /dev/null
+/* This program benchmarks negotiation of contracts with reclamation
+ * parameters set */
+
+#include <frsh.h>
+#include <error.h>
+#include <res_dummy.h>
+#include <time.h>
+
+#define MSEC(x) { x/1000, (x%1000) * 1000000 }
+frsh_utilization_set_t utilization_set = {
+ .size = 2,
+ .utilizations = {
+ { .budget = MSEC(1), .period = MSEC(1000), .deadline = MSEC(100) },
+ { .budget = MSEC(3), .period = MSEC(1000), .deadline = MSEC(100) },
+ },
+};
+
+#include <frsh.h>
+#include <error.h>
+#include <res_dummy.h>
+#include <time.h>
+
+#define N 1000
+
+int main(int argc, char *argv[])
+{
+ int ret;
+ frsh_contract_t contract[N];
+ frsh_vres_id_t vres[N];
+ int i;
+
+ ret = frsh_init();
+ if (ret) PERROR_AND_EXIT(ret, "frsh_init");
+
+ /* Negotiate N contracts */
+ for (i=0; i<N; i++) {
+ struct timespec t_start, t_end;
+ clock_gettime(CLOCK_MONOTONIC, &t_start);
+ ret = frsh_contract_init(&contract[i]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ ret = frsh_contract_set_resource_and_label(
+ &contract[i],
+ DUMMY_RESOURCE_TYPE, DUMMY_RESOURCE_ID,
+ NULL);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ ret = frsh_contract_set_basic_params(&contract[i],
+ &utilization_set.utilizations[0].budget,
+ &utilization_set.utilizations[0].period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+
+ frsh_rel_time_t zero = fosa_msec_to_rel_time(0);
+ ret = frsh_contract_set_reclamation_params(&contract[i],
+ &zero,
+ &utilization_set.utilizations[utilization_set.size-1].budget,
+ &utilization_set.utilizations[utilization_set.size-1].period,
+ FRSH_GR_DISCRETE,
+ &utilization_set,
+ 0,
+ 0);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_reclamation_params");
+
+ ret = frsh_contract_negotiate(&contract[i], &vres[i]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+ clock_gettime(CLOCK_MONOTONIC, &t_end);
+ printf("%d %g\n", i, (float)(t_end.tv_sec+1e-9*t_end.tv_nsec) - (t_start.tv_sec+1e-9*t_start.tv_nsec));
+ }
+ /* Cancel N contracts */
+ for (i=0; i<N; i++) {
+ ret = frsh_contract_cancel(vres[i]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_cancel");
+ }
+ return 0;
+}
--- /dev/null
+#include <frsh.h>
+#include <error.h>
+#include <res_dummy.h>
+
+#define NUM_CONTRACTS 3
+#define NUM_VARIANTS 3
+
+#define MSEC(x) fosa_msec_to_rel_time(x)
+
+struct contract_data {
+ fosa_rel_time_t stability_time;
+ int importance;
+ int weight;
+ frsh_utilization_t variants[NUM_VARIANTS];
+};
+
+int main(int argc, char *argv[])
+{
+ struct contract_data d[NUM_CONTRACTS] = {
+ { /* Contract 1 */
+ .stability_time = MSEC(0), .importance = 0, .weight = 1,
+ .variants = {
+ { .budget = MSEC(10), .period = MSEC(100), .deadline = MSEC(100) },
+ { .budget = MSEC(20), .period = MSEC(100), .deadline = MSEC(100) },
+ { .budget = MSEC(30), .period = MSEC(100), .deadline = MSEC(100) },
+ }
+ },
+ { /* Contract 2 */
+ .stability_time = MSEC(1000), .importance = 0, .weight = 1,
+ .variants = {
+ { .budget = MSEC(40), .period = MSEC(100), .deadline = MSEC(100) },
+ { .budget = MSEC(40), .period = MSEC( 80), .deadline = MSEC( 80) },
+ { .budget = MSEC(40), .period = MSEC( 60), .deadline = MSEC( 60) },
+ }
+ },
+ { /* Contract 3 */
+ .stability_time = MSEC(10*1000), .importance = 0, .weight = 1,
+ .variants = {
+ { .budget = MSEC(10), .period = MSEC(100), .deadline = MSEC(50) },
+ { .budget = MSEC(20), .period = MSEC( 80), .deadline = MSEC(40) },
+ { .budget = MSEC(30), .period = MSEC( 60), .deadline = MSEC(30) },
+ }
+ },
+ };
+ int ret;
+ frsh_contract_t contract[NUM_CONTRACTS];
+ frsh_vres_id_t vres[NUM_CONTRACTS];
+ int i, j;
+
+ ret = frsh_init();
+ if (ret) PERROR_AND_EXIT(ret, "frsh_init");
+
+ /* Negotiate contracts */
+ for (i=0; i<NUM_CONTRACTS; i++) {
+ char label[40];
+ ret = frsh_contract_init(&contract[i]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ ret = frsh_contract_set_resource_and_label(
+ &contract[i],
+ DUMMY_RESOURCE_TYPE, DUMMY_RESOURCE_ID,
+ (sprintf(label, "spare_cap_test %d", i),label));
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ ret = frsh_contract_set_basic_params(&contract[i],
+ &d[i].variants[0].budget,
+ &d[i].variants[0].period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+
+ ret = frsh_contract_set_timing_reqs(&contract[i], false, &d[i].variants[0].deadline);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_timing_reqs");
+
+ frsh_utilization_set_t utilization_set = { .size = NUM_VARIANTS };
+ for (j=0; j<NUM_VARIANTS; j++)
+ utilization_set.utilizations[j] = d[i].variants[j];
+ ret = frsh_contract_set_reclamation_params(&contract[i],
+ &d[i].stability_time,
+ &d[i].variants[NUM_VARIANTS-1].budget,
+ &d[i].variants[NUM_VARIANTS-1].period,
+ FRSH_GR_DISCRETE,
+ &utilization_set,
+ d[i].importance,
+ d[i].weight);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_reclamation_params");
+
+ char s[1000];
+ memset(s, 0, sizeof(s));
+ fres_contract_to_string(s, sizeof(s), contract[i]);
+ puts(s);
+
+ ret = frsh_contract_negotiate(&contract[i], &vres[i]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+ }
+
+ printf("Waiting for stability period to end\n");
+ sleep(2);
+ printf("Trying to renegotiate the 3rd contract again\n");
+ ret = frsh_contract_renegotiate_sync(&contract[2], vres[2]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+
+ /* Cancel contracts */
+ for (i=0; i<NUM_CONTRACTS; i++) {
+ ret = frsh_contract_cancel(vres[i]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_cancel");
+ }
+ return 0;
+}
--- /dev/null
+#include <frsh.h>
+#include <wvtest.h>
+#include <res_dummy.h>
+#include "trans_nego.h"
+
+WVTEST_MAIN("transaction negotiation")
+{
+ frsh_contract_t contract[3];
+ frsh_contract_label_t label[3];
+ frsh_rel_time_t budget, period;
+ int i;
+ frsh_transaction_t t;
+ frsh_vres_id_t vres0, vres1;
+
+ WVFRSH(frsh_init());
+
+ WVFRSH(frsh_transaction_init(&t, "test"));
+
+ for (i = TEST_CONTRACT_0; i <= TEST_CONTRACT_2; i++) {
+ WVFRSH(frsh_contract_init(&contract[i]));
+ sprintf(label[i], "contract%d", i);
+ WVFRSH(frsh_contract_set_resource_and_label(
+ &contract[i],
+ DUMMY_RESOURCE_TYPE, i,
+ label[i]));
+
+ budget = fosa_msec_to_rel_time(10);
+ period = fosa_msec_to_rel_time(100);
+ WVFRSH(frsh_contract_set_basic_params(&contract[i],
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR));
+
+ WVFRSH(frsh_transaction_add_contract(&t, &contract[i], i));
+ }
+ WVPASS(frsh_transaction_alloc_vres(&t, TEST_CONTRACT_0, &vres0) == FRES_ERR_TRANSACTION_NOT_FOUND);
+ WVFRSH(frsh_transaction_negotiate(&t));
+
+ WVFRSH(fra_dummy_init_and_activate_id(0));
+ WVFRSH(frsh_transaction_alloc_vres(&t, TEST_CONTRACT_0, &vres0));
+
+ WVPASS(frsh_transaction_alloc_vres(&t, TEST_CONTRACT_1, &vres1) == FRES_ERR_NO_RESOURCE_ALLOCATOR);
+ WVFRSH(fra_dummy_init_and_activate_id(1));
+ WVFRSH(frsh_transaction_alloc_vres(&t, TEST_CONTRACT_1, &vres1));
+ WVPASS(frsh_transaction_alloc_vres(&t, TEST_CONTRACT_2+1, &vres1) == FRSH_ERR_TOO_LARGE);
+ /* TEST_CONTRACT_2 is allocated in trans_nego2.c */
+
+ WVPASS(frsh_contract_cancel(vres1) == FRES_ERR_VRES_PART_OF_TRANSACTION);
+
+ frsh_destroy();
+}
--- /dev/null
+#ifndef TRANS_NEGO_H
+#define TRANS_NEGO_H
+
+enum {
+ TEST_CONTRACT_0 = 0,
+ TEST_CONTRACT_1 = 1,
+ TEST_CONTRACT_2 = 2,
+};
+
+#endif
--- /dev/null
+#!/bin/bash
+
+. $(dirname $0)/wvtest.sh
+
+WVSTART Setup
+WVPASS fcb -dfcb.pid
+WVPASS frm_dummy -dfrm0.pid -i0
+WVPASS frm_dummy -dfrm1.pid -i1
+WVPASS frm_dummy -dfrm2.pid -i2
+
+trap '
+WVSTART Kill
+WVPASS kill `cat fcb.pid`
+WVPASS rm fcb.pid
+WVPASS kill `cat frm0.pid`
+WVPASS rm frm0.pid
+WVPASS kill `cat frm1.pid`
+WVPASS rm frm1.pid
+WVPASS kill `cat frm2.pid`
+WVPASS rm frm2.pid
+' 0
+
+WVPASS trans_nego
+WVPASS trans_nego2
--- /dev/null
+#include <frsh.h>
+#include <wvtest.h>
+#include <res_dummy.h>
+#include "trans_nego.h"
+
+WVTEST_MAIN("transaction negotiation - remote part")
+{
+ frsh_transaction_t t;
+ frsh_vres_id_t vres1, vres2;
+
+ WVFRSH(frsh_init());
+ WVFRSH(fra_dummy_init_and_activate_id(1));
+ WVFRSH(fra_dummy_init_and_activate_id(2));
+#if 0
+ WVFRSH(frsh_transaction_wait_for_name(&t, "test"));
+#else
+ WVFRSH(frsh_transaction_init(&t, "test"));
+#endif
+ WVPASS(frsh_transaction_alloc_vres(&t, TEST_CONTRACT_1, &vres1) ==
+ FRES_ERR_VRES_ALREADY_ALLOCATED);
+ WVFRSH(frsh_transaction_alloc_vres(&t, TEST_CONTRACT_2, &vres2));
+ frsh_destroy();
+}
--- /dev/null
+. $(dirname $0)/../../../wvtest.sh
+
+setup_dummy() {
+ WVSTART Setup
+ WVPASS fcb -dfcb.pid
+ WVPASS frm_dummy -dfrm.pid
+ trap '
+WVSTART Kill
+WVPASS kill `cat fcb.pid`
+WVPASS rm fcb.pid
+WVPASS kill `cat frm.pid`
+WVPASS rm frm.pid
+' 0
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+SUBDIRS=$(ALL_OMK_SUBDIRS)
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+default_CONFIG = CONFIG_ACPI_BATTERY=y
+
+ifeq ($(CONFIG_ACPI_BATTERY),y)
+shared_LIBRARIES = acpi_battery
+
+acpi_battery_SOURCES = fra_acpi_battery.c
+acpi_battery_LIBS += fosa rt acpi
+
+include_HEADERS = fra_acpi_battery.h
+
+SUBDIRS=tests
+endif
--- /dev/null
+/**
+ * @file fres_acpi_cpu.c
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ * Michael Trimarchi <trimarchimichael@yahoo.it>
+ *
+ * @brief Implementation of shared CPU related ACPI functions.
+ *
+ */
+
+#include "fra_acpi_battery.h"
+
+static global_t acpi_globals;
+
+static int which_batt;
+static battery_t *battery;
+
+static int battery_initialized = 0;
+
+int fra_battery_init()
+{
+ if (battery_initialized == 1) return 0;
+
+ init_acpi_batt(&acpi_globals);
+ init_acpi_acadapt(&acpi_globals);
+
+ battery_initialized = 1;
+
+ return 0;
+}
+
+int fra_battery_expiration(fosa_rel_time_t *expiration)
+{
+ int i, ret;
+ long rmng_msec;
+
+ if (!battery_initialized) return EINVAL;
+
+ read_acpi_acstate(&acpi_globals);
+ if (acpi_globals.adapt.ac_state != P_BATT)
+ return EAGAIN;
+
+ rmng_msec = 0;
+ for (i = 0; i < acpi_globals.batt_count; i++) {
+ ret = read_acpi_batt(i);
+ if (ret == SUCCESS) {
+ rmng_msec +=
+ (long) batteries[i].remaining_time * 60000;
+ }
+ }
+
+ *expiration = fosa_msec_to_rel_time(rmng_msec);
+
+ return 0;
+}
+
--- /dev/null
+#ifndef ACPI_BATTERY
+#define ACPI_BATTERY
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <limits.h>
+#include <string.h>
+#include <libacpi.h>
+
+#include <fosa.h>
+
+int fra_battery_init();
+
+int fra_battery_expiration(fosa_abs_time_t *expiration);
+
+#endif
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+test_PROGRAMS = acpi_battery_test
+acpi_battery_test_SOURCES = acpi_battery_test.c
+lib_LOADLIBES += pthread rt frsh
--- /dev/null
+#include <frsh.h>
+
+int main()
+{
+ int terror;
+ frsh_vres_id_t vres;
+ frsh_contract_t contract;
+ frsh_rel_time_t budget, period;
+ frsh_rel_time_t current, duration, expiration;
+ unsigned long duration_msec, duration_step;
+
+ PXW(frsh_init());
+
+ PXW(frsh_contract_init(&contract));
+
+ duration_msec = duration_step = 1000UL * 60UL * 10UL;
+
+ budget = fosa_msec_to_rel_time(10);
+ period = fosa_msec_to_rel_time(100);
+ PXW(frsh_contract_set_basic_params(&contract,
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR));
+
+ PXW(frsh_contract_set_resource_and_label(&contract, FRSH_RT_PROCESSOR, 0,"TEST_VRES"));
+
+ PXW(frsh_contract_set_min_budget_pow(&contract, FRSH_PLT_HIGH, &budget));
+
+ PXW(frsh_contract_set_min_budget_pow(&contract, FRSH_PLT_MEDIUM, &budget));
+
+ PXW(frsh_contract_set_min_budget_pow(&contract, FRSH_PLT_LOW, &budget));
+
+ terror = frsh_battery_get_expiration(&expiration);
+ if (terror == EAGAIN)
+ PERROR_AND_EXIT(terror, "frsh_battery_get_expiration: system running on AC");
+ if (terror)
+ PERROR_AND_EXIT(terror, "frsh_battery_get_expiration");
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t);
+ printf("System battery wil expire in %lu seconds\n",
+ fosa_rel_time_to_msec(fosa_abs_time_decr(expiration, current)) / 1000UL);
+
+ printf("Starting with minumum diration = %lu seconds\n"
+ " ans stepping by %lu seconds.\n",
+ duration_msec / 1000UL,
+ duration_step / 1000UL);
+
+ duration = fosa_msec_to_rel_time(duration_msec);
+ PXW(frsh_contract_set_min_expiration(&contract, duration));
+
+ PXW(frsh_contract_get_min_expiration(&contract, &duration));
+
+ PXW(frsh_contract_negotiate(&contract, &vres));
+ printf("Aqcpu vres negotiated, vres-ID: %p\n", vres);
+
+ while (1) {
+ duration_msec += duration_step;
+ duration = fosa_msec_to_rel_time(duration_msec);
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t);
+ printf(" Renegotiating the contract with minimum expiration %lu sec.\n"
+ " System expiration time: %lu seconds\n",
+ fosa_rel_time_to_msec(duration) / 1000UL,
+ fosa_rel_time_to_msec(fosa_abs_time_decr(expiration, current)) / 1000UL);
+
+ PXW(frsh_contract_set_min_expiration(&contract, duration));
+
+ PXW(frsh_battery_get_expiration(&expiration));
+ terror = frsh_contract_renegotiate_sync(&contract, vres);
+ if (terror == FRSH_ERR_CONTRACT_REJECTED) {
+ PERROR_FRESCOR(terror, "frsh_contract_renegotiate_sync");
+ goto out;
+ }
+ if (terror) PERROR_AND_EXIT(terror, "frsh_contract_renegotiate_sync");
+
+ sleep(3);
+ }
+
+out:
+ PXW(frsh_contract_cancel(vres));
+
+ printf("Test PASSED!\n");
+
+ return 0;
+}
+
--- /dev/null
+CONFIG_AQUOSA=y
+CFLAGS+=-save-temps
+CONFIG_FWP=n
+CONFIG_RESOURCE_DUMMY=n
+CONFIG_RESOURCE_ITEM=n
+CONFIG_RESOURCE_CLUSTER_TREE=n
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+default_CONFIG = CONFIG_ACPI_CPU=y
+
+ifeq ($(CONFIG_ACPI_CPU),y)
+shared_LIBRARIES = acpi_cpu
+
+acpi_cpu_SOURCES = fra_acpi_cpu.c
+acpi_cpu_LIBS += fosa rt m cpufreq
+
+include_HEADERS = fra_acpi_cpu.h
+
+SUBDIRS=tests
+
+endif
--- /dev/null
+/**
+ * @file fres_acpi_cpu.c
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ * Michael Trimarchi <trimarchimichael@yahoo.it>
+ *
+ * @brief Implementation of shared CPU related ACPI functions.
+ *
+ */
+
+#include "fra_acpi_cpu.h"
+
+static int frequency_initialized = 0;
+
+static unsigned long freqs[3];
+
+int fra_CPU_power_init(int cpu)
+{
+ int ret;
+ int i, j, freq_num = 0;
+ struct cpufreq_available_governors *governors, *g;
+ struct cpufreq_available_frequencies *frequencies, *f;
+
+ if (frequency_initialized == 1) return 0;
+
+ ret = cpufreq_cpu_exists(cpu);
+ if (ret) return EINVAL;
+
+ governors = cpufreq_get_available_governors(cpu);
+ if (!governors) return EINVAL;
+ for (g = governors; g != NULL; g = g->next)
+ if (strncmp("userspace", g->governor, sizeof(*g->governor)) == 0)
+ break;
+ cpufreq_put_available_governors(governors);
+
+ if (g == NULL) return EINVAL;
+
+ ret = cpufreq_modify_policy_governor(cpu, "userspace");
+ if (ret) return EPERM;
+
+
+ frequencies = cpufreq_get_available_frequencies(cpu);
+ if (!frequencies) return EINVAL;
+ for (f = frequencies; f; f = f->next, freq_num++)
+ ;
+
+ f = frequencies;
+ i = j = 0;
+ while (f) {
+ if (i == 0 ||
+ i == ((int)ceil((double)freq_num / 2.0f)) ||
+ i == freq_num - 1) {
+ freqs[j] = f->frequency;
+ j++;
+ }
+ i++;
+ f = f->next;
+ }
+ cpufreq_put_available_frequencies(frequencies);
+
+ frequency_initialized = 1;
+
+ return 0;
+}
+
+int fra_CPU_get_power(int cpu, int *level)
+{
+ unsigned long freq;
+ int i;
+
+ if (!frequency_initialized) return EINVAL;
+
+ freq = cpufreq_get(cpu);
+ for (i = 0; i < 3; i++)
+ if (freqs[i] == freq) {
+ *level = i;
+ return 0;
+ }
+
+ return EINVAL;
+}
+
+int fra_CPU_set_power(int cpu, int level)
+{
+ if (!frequency_initialized || level >= 3)
+ return EINVAL;
+
+ return cpufreq_set_frequency(cpu, freqs[level]);
+}
+
+int fra_CPU_get_speed(int cpu, int level, double *ratio)
+{
+ if (!frequency_initialized || level >= 3)
+ return EINVAL;
+
+ *ratio = (double) freqs[level] / freqs[0];
+
+ return 0;
+}
+
--- /dev/null
+#ifndef ACPI_CPU
+#define ACPI_CPU
+
+#include <string.h>
+#include <math.h>
+#include <cpufreq.h>
+
+#include <fosa.h>
+
+int fra_CPU_power_init(int cpu);
+
+int fra_CPU_get_power(int cpu, int *level);
+
+int fra_CPU_set_power(int cpu, int level);
+
+int fra_CPU_get_speed(int cpu, int level, double *ratio);
+
+#endif
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+test_PROGRAMS = acpi_cpu_test
+acpi_cpu_test_SOURCES = acpi_cpu_test.c
+lib_LOADLIBES += pthread rt frsh
--- /dev/null
+#include <frsh.h>
+
+int main()
+{
+ frsh_power_level_t level;
+ int power_levels;
+ double speed;
+ int terror;
+
+ PXW(frsh_init());
+
+ PXW(frsh_resource_get_num_power_levels(FRSH_RT_PROCESSOR, 0, &power_levels));
+ printf("Number of power levels suppoerted: %d\n", power_levels);
+
+ if (power_levels == 1)
+ PERROR_AND_EXIT(EINVAL, "Different power levels not supported");
+
+ PXW(frsh_resource_get_power_level(FRSH_RT_PROCESSOR, 0, &level));
+ PXW(frsh_resource_get_speed(FRSH_RT_PROCESSOR, 0, level, &speed));
+ printf("Starting with power level %d, speed = %f\n", level, speed);
+
+ sleep(3);
+ PXW(frsh_resource_set_power_level(FRSH_RT_PROCESSOR, 0, FRSH_PLT_HIGH));
+ PXW(frsh_resource_get_power_level(FRSH_RT_PROCESSOR, 0, &level));
+ PXW(frsh_resource_get_speed(FRSH_RT_PROCESSOR, 0, level, &speed));
+ printf("%d (FRSH_PLT_HIGH) correctly set, speed = %f\n", level, speed);
+
+ sleep(3);
+ PXW(frsh_resource_set_power_level(FRSH_RT_PROCESSOR, 0, FRSH_PLT_MEDIUM));
+ PXW(frsh_resource_get_power_level(FRSH_RT_PROCESSOR, 0, &level));
+ PXW(frsh_resource_get_speed(FRSH_RT_PROCESSOR, 0, level, &speed));
+ printf("%d (FRSH_PLT_MEDIUM) correctly set, speed = %f\n", level, speed);
+
+ sleep(3);
+ PXW(frsh_resource_set_power_level(FRSH_RT_PROCESSOR, 0, FRSH_PLT_LOW));
+ PXW(frsh_resource_get_power_level(FRSH_RT_PROCESSOR, 0, &level));
+ PXW(frsh_resource_get_speed(FRSH_RT_PROCESSOR, 0, level, &speed));
+ printf("%d (FRSH_PLT_LOW) correctly set, speed = %f\n", level, speed);
+
+ return 0;
+}
+
--- /dev/null
+CONFIG_AQUOSA=y
+CFLAGS+=-save-temps
+CONFIG_FWP=n
+CONFIG_RESOURCE_DUMMY=n
+CONFIG_RESOURCE_ITEM=n
+CONFIG_RESOURCE_CLUSTER_TREE=n
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+default_CONFIG = CONFIG_ACPI_LCD=y
+
+ifeq ($(CONFIG_ACPI_LCD),y)
+shared_LIBRARIES = acpi_lcd
+
+acpi_lcd_SOURCES = fra_acpi_lcd.c
+acpi_lcd_LIBS += fosa rt m acpi
+
+include_HEADERS = fra_acpi_lcd.h
+
+SUBDIRS=tests
+endif
+
--- /dev/null
+/**
+ * @file fres_acpi_cpu.c
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ * Michael Trimarchi <trimarchimichael@yahoo.it>
+ *
+ * @brief Implementation of LCD related ACPI functions.
+ *
+ */
+
+#include "fra_acpi_lcd.h"
+
+static unsigned long bright[3];
+
+static lcd_type_t lcd_initialized = NONE;
+
+static int __parse_proc_brightness(FILE *fd)
+{
+ char buffer[1024];
+ int bright_buf[100], n_bright = 0;
+ char *token, *ptr = buffer;
+
+ if (!fscanf(fd, "levels:%[^\n]", buffer))
+ return -1;
+
+ while ((token = strtok(ptr, " ")) > 0 &&
+ n_bright < 100) {
+ bright_buf[n_bright] = atoi(token);
+
+ ptr = NULL;
+ n_bright++;
+ }
+
+ bright[0] = bright_buf[n_bright - 1];
+ bright[1] = bright_buf[((int)ceil((double)n_bright / 2.0f))];
+ bright[3] = bright_buf[0];
+
+ return 0;
+}
+
+static inline int __setup_lcd_type()
+{
+ int ret = 0;
+ FILE *fd;
+
+ if (lcd_initialized != NONE)
+ return 0;
+
+ fd = fopen(PROC_LCD_PATH_1 "/brightness", "r");
+ if (fd) {
+ ret = __parse_proc_brightness(fd);
+ if (ret) goto end;
+
+ lcd_initialized = PROC_1;
+
+ goto end;
+ }
+
+ fd = fopen(PROC_LCD_PATH_2 "/brightness", "r");
+ if (fd) {
+ ret = __parse_proc_brightness(fd);
+ if (ret) goto end;
+
+ lcd_initialized = PROC_2;
+
+ goto end;
+ }
+
+ fd = fopen(SYS_LCD_PATH_1 "/brightness", "r");
+ if (fd) {
+ /* @TODO: to be done! */
+
+ lcd_initialized = SYS_1;
+
+ goto end;
+ }
+
+ ret = system("smartdimmer -g");
+ if (ret) {
+ fprintf(stderr, "Problems using smartdimmer\n");
+ return errno;
+ }
+
+ bright[0] = 100;
+ bright[1] = 43;
+ bright[3] = 15;
+
+ lcd_initialized = NV;
+
+ goto end;
+
+ return EINVAL;
+
+end:
+ fclose(fd);
+ return ret;
+}
+
+static int __set_proc_brightness(FILE *fd, int level)
+{
+ int ret;
+
+ ret = fprintf(fd, "%d", bright[level]);
+ if (ret <= 0) {
+ fprintf(stderr,
+ "Could not set brightness level %d\n",
+ level);
+ return errno;
+ }
+
+ return 0;
+}
+
+static int __set_lcd_brightness(int level)
+{
+ FILE *fd;
+ int ret = 0;
+ char str[128];
+
+ if (lcd_initialized == NONE || level >= 3)
+ return EINVAL;
+
+ if (lcd_initialized == PROC_1) {
+ fd = fopen(PROC_LCD_PATH_1 "/brightness", "w");
+ if (!fd)
+ goto err;
+
+ ret = __set_proc_brightness(fd, level);
+ if (ret)
+ return EINVAL;
+ } else if (lcd_initialized == PROC_2) {
+ fd = fopen(PROC_LCD_PATH_2 "/brightness", "w");
+ if (!fd)
+ goto err;
+
+ ret = __set_proc_brightness(fd, level);
+ if (ret)
+ return EINVAL;
+ } else if (lcd_initialized == SYS_1) {
+ /* @TODO: to be done! */
+ } else if (lcd_initialized == NV) {
+ sprintf(str, "smartdimmer -s %lu", bright[level]);
+ ret = system(str);
+ if (ret) {
+ fprintf(stderr,
+ "Could not set brightness level %d\n",
+ level);
+ return errno;
+ }
+ }
+
+ fclose(fd);
+err:
+ return ret;
+}
+
+int fra_LCD_power_init(int lcd)
+{
+ return __setup_lcd_type();
+}
+
+int fra_LCD_get_power(int lcd, int *level)
+{
+ /**
+ * @TODO: to be implemented!
+ **/
+ return EINVAL;
+}
+
+int fra_LCD_set_power(int lcd, int level)
+{
+ return __set_lcd_brightness(level);
+}
+
+int fra_LCD_get_speed(int lcd, int level, double *ratio)
+{
+ if (lcd_initialized == NONE || level >= 3)
+ return EINVAL;
+
+ *ratio = bright[level]/bright[0];
+
+ return 0;
+}
+
--- /dev/null
+#ifndef ACPI_LCD
+#define ACPI_LCD
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <math.h>
+
+#include <fosa.h>
+
+#define PROC_LCD_PATH_1 "/proc/acpi/video/VID/LCD/"
+#define PROC_LCD_PATH_2 "/proc/acpi/video/VID1/LCD/"
+#define SYS_LCD_PATH_1 "/sys/class/backlight/acpi_video0/"
+
+typedef enum lcd_type {
+ NONE = 0,
+ PROC_1 = 1,
+ PROC_2 = 2,
+ SYS_1 = 3,
+ NV = 4
+} lcd_type_t;
+
+int fra_LCD_power_init(int lcd);
+
+int fra_LCD_get_power(int lcd, int *level);
+
+int fra_LCD_set_power(int lcd, int level);
+
+int fra_LCD_get_speed(int lcd, int level, double *ratio);
+
+#endif
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+test_PROGRAMS = acpi_lcd_test
+acpi_lcd_test_SOURCES = acpi_lcd_test.c
+lib_LOADLIBES += pthread rt frsh
--- /dev/null
+#include <frsh.h>
+
+int main()
+{
+ frsh_power_level_t level;
+ int power_levels;
+ double speed;
+ int terror;
+
+ PXW(frsh_init());
+
+ PXW(frsh_resource_get_num_power_levels(FRSH_RT_LCD, 0, &power_levels));
+ printf("Number of power levels suppoerted: %d\n", power_levels);
+
+ if (power_levels == 1)
+ PERROR_AND_EXIT(EINVAL, "Different power levels not supported");
+
+ PXW(frsh_resource_get_power_level(FRSH_RT_LCD, 0, &level));
+ PXW(frsh_resource_get_speed(FRSH_RT_LCD, 0, level, &speed));
+ printf("Starting with power level %d, speed = %f\n", level, speed);
+
+ sleep(3);
+ PXW(frsh_resource_set_power_level(FRSH_RT_LCD, 0, FRSH_PLT_HIGH));
+ PXW(frsh_resource_get_power_level(FRSH_RT_LCD, 0, &level));
+ PXW(frsh_resource_get_speed(FRSH_RT_LCD, 0, level, &speed));
+ printf("%d (FRSH_PLT_HIGH) correctly set, speed = %f\n", level, speed);
+
+ sleep(3);
+ PXW(frsh_resource_set_power_level(FRSH_RT_LCD, 0, FRSH_PLT_MEDIUM));
+ PXW(frsh_resource_get_power_level(FRSH_RT_LCD, 0, &level));
+ PXW(frsh_resource_get_speed(FRSH_RT_LCD, 0, level, &speed));
+ printf("%d (FRSH_PLT_MEDIUM) correctly set, speed = %f\n", level, speed);
+
+ sleep(3);
+ PXW(frsh_resource_set_power_level(FRSH_RT_LCD, 0, FRSH_PLT_LOW));
+ PXW(frsh_resource_get_power_level(FRSH_RT_LCD, 0, &level));
+ PXW(frsh_resource_get_speed(FRSH_RT_LCD, 0, level, &speed));
+ printf("%d (FRSH_PLT_LOW) correctly set, speed = %f\n", level, speed);
+
+ return 0;
+}
+
--- /dev/null
+CONFIG_AQUOSA=y
+CFLAGS+=-save-temps
+CONFIG_FWP=n
+CONFIG_RESOURCE_DUMMY=n
+CONFIG_RESOURCE_ITEM=n
+CONFIG_RESOURCE_CLUSTER_TREE=n
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+default_CONFIG = CONFIG_RESOURCE_CLUSTER_TREE=y
+
+ifeq ($(CONFIG_RESOURCE_CLUSTER_TREE),y)
+CFLAGS += -std=gnu99 -DFRESCOR
+
+bin_PROGRAMS = frm_cluster_tree
+frm_cluster_tree_SOURCES = frm_cluster_tree.c ct_wsn.c cluster_tree_blocks.c
+#frm_cluster_tree.c cluster_tree_block.c
+frm_cluster_tree_CLIENT_IDL = cluster_tree_idl.idl
+frm_cluster_tree_LIBS = frm forb contract fosa rt ulut fcb_client m
+
+# shared_LIBRARIES = frs_cluster_tree
+# frs_cluster_tree_SOURCES = frs_cluster_tree.c cluster_tree_block.c
+# frs_cluster_tree_LIBS = frs
+# frs_cluster_tree_CLIENT_IDL = res_cluster_tree_idl.idl
+
+include_HEADERS = cluster_tree.h
+include_GEN_HEADERS = cluster_tree_idl.h
+
+endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file cluster_tree.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Wed Feb 18 16:15:21 2009
+ *
+ * @brief Contract block for cluster tree resource
+ *
+ *
+ */
+
+
+#ifndef CLUSTER_TREE_H
+#define CLUSTER_TREE_H
+
+#include <cluster_tree_idl.h>
+#include <fres_contract.h>
+#include <fres_container.h>
+
+int fres_block_register_cluster_tree();
+
+/* Define fres_container_(add|get|del)_cluster_tree_traffic. */
+FRES_CONTAINER_ACCESSOR(CLUSTER_TREE_TRAFFIC, cluster_tree_traffic);
+
+/* Define fres_contract_(add|get|del)_cluster_tree_traffic. */
+FRES_CONTRACT_ACCESSOR(cluster_tree_traffic);
+
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file cluster_tree_blocks.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Fri Oct 31 17:23:25 2008
+ *
+ * @brief Description contract blocks specific to cluster tree resource.
+ */
+#include <cluster_tree_idl.h>
+#include <fres_container.h>
+
+static const struct fres_block_desc cluster_tree_traffic_desc = {
+ .size = sizeof(fres_block_cluster_tree_traffic),
+ .serialize = (fres_block_serialize_fnc_t*)fres_block_cluster_tree_traffic_serialize,
+ .deserialize = (fres_block_deserialize_fnc_t*)fres_block_cluster_tree_traffic_deserialize,
+ .duplicate = fres_block_duplicate_default
+};
+
+int fres_block_register_cluster_tree()
+{
+ return fres_block_register(FRES_BLOCK_CLUSTER_TREE_TRAFFIC,
+ &cluster_tree_traffic_desc);
+}
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------------------- //
+// Copyright (C) 2006 - 2008 FRESCOR consortium partners: //
+// //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// Scuola Superiore Sant'Anna, ITALY //
+// Kaiserslautern University, GERMANY //
+// Univ. Politécnica Valencia, SPAIN //
+// Czech Technical University in Prague, CZECH REPUBLIC //
+// ENEA SWEDEN //
+// Thales Communication S.A. FRANCE //
+// Visual Tools S.A. SPAIN //
+// Rapita Systems Ltd UK //
+// Evidence ITALY //
+// //
+// See http://www.frescor.org for a link to partners' websites //
+// //
+// FRESCOR project (FP6/2005/IST/5-034026) is funded //
+// in part by the European Union Sixth Framework Programme //
+// The European Union is not liable of any use that may be //
+// made of this code. //
+// //
+// //
+// based on previous work (FSF) done in the FIRST project //
+// //
+// Copyright (C) 2005 Mälardalen University, SWEDEN //
+// Scuola Superiore S.Anna, ITALY //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// //
+// FSF API web pages: http:marte.unican.es/fsf/docs //
+// http:shark.sssup.it/contrib/first/docs/ //
+// //
+// This file is part of FORB (Frescor Object Request Broker) //
+// //
+// FORB is free software; you can redistribute it and/or modify it //
+// under terms of the GNU General Public License as published by the //
+// Free Software Foundation; either version 2, or (at your option) any //
+// later version. FORB is distributed in the hope that it will be //
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty //
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
+// General Public License for more details. You should have received a //
+// copy of the GNU General Public License along with FORB; see file //
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, //
+// Cambridge, MA 02139, USA. //
+// //
+// As a special exception, including FORB header files in a file, //
+// instantiating FORB generics or templates, or linking other files //
+// with FORB objects to produce an executable application, does not //
+// by itself cause the resulting executable application to be covered //
+// by the GNU General Public License. This exception does not //
+// however invalidate any other reasons why the executable file might be //
+// covered by the GNU Public License. //
+////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @file cluster_tree_idl.idl
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Fri Oct 31 17:17:49 2008
+ *
+ * @brief
+ *
+ *
+ */
+module fres {
+ module block {
+ module cluster_tree {
+ struct node_params {
+ unsigned short node_id; /**< ID number of a sensor node */
+ double interarrival_time; /**< time between two consecutive packets [sec] */
+ unsigned short payload; /**< size of generated payload (MSDU) [bits] */
+ };
+
+
+ struct traffic {
+ sequence<node_params> nodes; /**< array of node traffic */
+ };
+ };
+ };
+};
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file ct_wsn.c
+ * @author Petr Jurcik, 2008
+ *
+ * @brief Contains support functions for FRESCOR admission test (the worst-case analysis)
+ *
+ */
+
+
+#include "ct_wsn.h"
+
+/* local function prototypes */
+static int total_routers(int max_routers, int height);
+static double full_TS_bandwidth(int SO, unsigned short mpdu, int ack_enable);
+static void gama_factor_down(int max_routers, int height, int *p_bif);
+static void gama_factor_up(int max_routers, int height, int *p_bif);
+static BETA concat(BETA beta1, BETA beta2);
+static BETA aggr(BETA beta, ALPHA alpha2);
+static Z zigbee(int SO, int BO, unsigned short mpdu, int ack_enable);
+static int add_node(TRAFFIC *p_traffic, TRAFFIC_NODE_ALPHA node);
+static int update_node(TRAFFIC *p_traffic, TRAFFIC_NODE_PARAMS node_params);
+
+
+/**
+* CT_WSN The worst-case analysis using Network Calculus framework.
+*
+* @param[in] topology_params topology parameters
+* @param[in] application_params application parameters
+* @param[out] p_output_params output paramaters
+*
+* @return status code
+*/
+int ct_wsn(TOPOLOGY_PARAMS topology_params, APPLICATION_PARAMS application_params, OUTPUT_PARAMS *p_output_params)
+{
+ int i, j, BO, nbr_TS_data, L_CFP_max, nbr;
+ Z z;
+ BETA beta_data, beta_conn, beta_eq, *p_BETA_up, *p_BETA_down;
+ ALPHA alpha_data_out, alpha_height_in, alpha_agg;
+ int *p_bif_down; /* downstream bandwidth increase factor */
+ int *p_bif_up; /* upstream bandwidth increase factor */
+ double r_data_max;
+ double *p_bandwidth_per_depth_up, *p_bandwidth_per_depth_down;
+ int *p_slot_nbr_for_each_router_per_sd_up, *p_slot_nbr_for_each_router_per_sd_down;
+ int *p_total_number_of_ts_per_sd_up, *p_total_number_of_ts_per_sd_down;
+ int total_number_of_ts_for_end_nodes_per_sd;
+ double *p_q1_up, *p_sigma, *p_q2_up, *p_q_up, *p_b_up_bar;
+ double *p_q1_down, *p_tau, *p_q2_down, *p_q3_down, *p_q_down, *p_b_down_bar;
+ double d_data, d_e2e_1, d_e2e_2;
+
+ p_output_params->error_code = 0;
+
+ /* maximum number of child routers and end-nodes must be less than or equal to 7 */
+ if(topology_params.max_routers + topology_params.max_end_nodes > 7)
+ {
+ p_output_params->error_code = 1;
+ return -1;
+ }
+
+ /* MAC Protocol Data Unit (MPDU) must be smaller than 1016 bist (aMaxPHYPacketSize parameters) */
+ if((application_params.alpha_data.b > 1016) || (application_params.alpha_data.b < 0))
+ {
+ p_output_params->error_code = 2;
+ return -1;
+ }
+
+ /* minimum Beacon Order (BO) as a function of number of routers and Superframe Order (SO) */
+ BO = (int) ceil(log(total_routers(topology_params.max_routers, topology_params.height) * pow(2, topology_params.SO))/log(2));
+
+ /* computation of the IEEE 802.15.4 parameters */
+ z = zigbee(topology_params.SO, BO, application_params.alpha_data.b, application_params.ack_enable);
+
+ nbr_TS_data = (int) ceil(application_params.alpha_data.r/z.R_TS); /* the number of time slots for sensor-based data flow from end-node */
+ beta_data.R = nbr_TS_data * z.R_TS; /* [bps] the quaranteed bandwidth provided to each end-node */
+ beta_data.T = (z.BI - nbr_TS_data * z.TS); /* [sec] the maximum latency of the service provided to each end-node */
+ L_CFP_max = 16 - (int) ceil(aMinCAPLength/z.TS); /* maximum CFP length */
+
+ if((p_bif_down = (int *) calloc(topology_params.height+1, sizeof(int))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ if((p_bif_up = (int *) calloc(topology_params.height+1, sizeof(int))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ gama_factor_down(topology_params.max_routers, topology_params.height, p_bif_down);
+ gama_factor_up(topology_params.max_routers, topology_params.height, p_bif_up);
+
+ if(topology_params.h_sink == 0)
+ nbr = p_bif_up[topology_params.height-1];
+ else
+ nbr = p_bif_down[topology_params.h_sink-1];
+
+ /* [bps] the maximum data rate for end-node */
+ r_data_max = floor((L_CFP_max - nbr_TS_data * topology_params.max_end_nodes)/topology_params.max_routers)*(z.R_TS/(nbr*(topology_params.max_end_nodes + topology_params.sensing_cap)));
+
+ if(application_params.alpha_data.r > r_data_max)
+ {
+ p_output_params->error_code = 4;
+ return -1;
+ }
+
+ /* the output flow of each end-node */
+ alpha_data_out.r = application_params.alpha_data.r; /* [bps] */
+ alpha_data_out.b = (unsigned short) ceil(application_params.alpha_data.b + application_params.alpha_data.r * beta_data.T); /* [bits] */
+
+
+ /* the input arrival curve of the router at the maximum depth H */
+ alpha_height_in.r = (topology_params.max_end_nodes + topology_params.sensing_cap) * application_params.alpha_data.r; /* [bps] */
+ alpha_height_in.b = (unsigned short) ceil((topology_params.max_end_nodes + topology_params.sensing_cap) * application_params.alpha_data.b + topology_params.max_end_nodes * application_params.alpha_data.r * beta_data.T); /* [bits] */
+
+ /* ------------------------- BANDWIDTH REQUIREMENT --------------------------------------- */
+ if((p_bandwidth_per_depth_up = (double *) calloc(topology_params.height+1, sizeof(double))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ if((p_slot_nbr_for_each_router_per_sd_up = (int *) calloc(topology_params.height+1, sizeof(int))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ if((p_total_number_of_ts_per_sd_up = (int *) calloc(topology_params.height+1, sizeof(int))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ if((p_total_number_of_ts_per_sd_down = (int *) calloc(topology_params.h_sink, sizeof(int))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ if((p_BETA_up = (BETA *) calloc(topology_params.height+1, sizeof(BETA))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ if((p_bandwidth_per_depth_down = (double *) calloc(topology_params.height+1, sizeof(double))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ if((p_slot_nbr_for_each_router_per_sd_down = (int *) calloc(topology_params.height+1, sizeof(int))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ if((p_BETA_down = (BETA *) calloc(topology_params.height+1, sizeof(BETA))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ total_number_of_ts_for_end_nodes_per_sd = topology_params.max_end_nodes * nbr_TS_data;
+
+ for(i=0; i<=topology_params.height; i++)
+ {
+ p_bandwidth_per_depth_up[i] = p_bif_up[i] * alpha_height_in.r; /* [bps] the outgoing upstream data rate r* */
+ p_bandwidth_per_depth_down[i] = p_bif_down[i] * alpha_height_in.r; /* [bps] the outgoing downstream data rate r* */
+ p_slot_nbr_for_each_router_per_sd_up[i] = (int) ceil(p_bandwidth_per_depth_up[i]/z.R_TS); /* number of slots required by each router */
+ p_slot_nbr_for_each_router_per_sd_down[i] = (int) ceil(p_bandwidth_per_depth_down[i]/z.R_TS); /* number of slots required from parent router */
+ p_total_number_of_ts_per_sd_up[i] = total_number_of_ts_for_end_nodes_per_sd + topology_params.max_routers * p_slot_nbr_for_each_router_per_sd_up[i]; /* total number of time slots for all end-nodes/routers in each superframe duration */
+ p_BETA_up[i].R = p_slot_nbr_for_each_router_per_sd_up[i] * z.R_TS; /* bandwidth quaranteed for each router */
+ p_BETA_down[i].R = p_slot_nbr_for_each_router_per_sd_down[i] * z.R_TS; /* bandwidth quaranteed for each router */
+ }
+
+ for(i=0; i<topology_params.h_sink; i++)
+ {
+ p_total_number_of_ts_per_sd_down[i] = p_slot_nbr_for_each_router_per_sd_down[i] + (topology_params.max_routers - 1) * p_slot_nbr_for_each_router_per_sd_up[topology_params.height-1-i] + total_number_of_ts_for_end_nodes_per_sd;
+ }
+
+ p_BETA_up[0].T = z.BI - z.SD - (p_slot_nbr_for_each_router_per_sd_up[0]-nbr_TS_data)*z.TS; /* [sec] latency of service curve Ti */
+ p_BETA_down[0].T = (topology_params.max_routers - 1) * p_slot_nbr_for_each_router_per_sd_up[topology_params.height-1] * z.TS; /* [sec] */
+
+ for(i=1; i<=topology_params.height; i++)
+ {
+ p_BETA_up[i].T = (z.BI - z.SD - (p_slot_nbr_for_each_router_per_sd_up[i] - p_slot_nbr_for_each_router_per_sd_up[i-1]) * z.TS); /* [sec] latency of service curve Ti */
+ p_BETA_down[i].T = (z.BI - z.SD - (p_slot_nbr_for_each_router_per_sd_down[i] - p_slot_nbr_for_each_router_per_sd_down[i-1]) * z.TS); /* [sec]latency of service curve Ti */
+ }
+
+ if(topology_params.h_sink > 0)
+ p_BETA_up[topology_params.height-1].T = p_BETA_up[topology_params.height-1].T - (p_slot_nbr_for_each_router_per_sd_down[0] * z.TS); /* [sec] T(0) */
+
+ (*p_output_params).p_number_of_time_slots[0] = topology_params.max_end_nodes * nbr_TS_data;
+ for(i=1; i<=topology_params.height; i++)
+ {
+ (*p_output_params).p_number_of_time_slots[i] = p_total_number_of_ts_per_sd_up[i-1];
+ }
+
+ if(topology_params.h_sink > 0)
+ {
+ for(i=0; i<topology_params.h_sink; i++)
+ {
+ p_output_params->p_number_of_time_slots[i+topology_params.height] = p_total_number_of_ts_per_sd_down[i];
+ }
+ }
+
+ free((void *)p_slot_nbr_for_each_router_per_sd_down);
+ p_slot_nbr_for_each_router_per_sd_down = NULL;
+
+ free((void *)p_total_number_of_ts_per_sd_up);
+ p_total_number_of_ts_per_sd_up = NULL;
+
+ free((void *)p_total_number_of_ts_per_sd_down);
+ p_total_number_of_ts_per_sd_down = NULL;
+
+ free((void *)p_slot_nbr_for_each_router_per_sd_up);
+ p_slot_nbr_for_each_router_per_sd_up = NULL;
+
+ /* ------------------------- BUFFERING REQUIREMENT --------------------------------------- */
+ /* upstream buffer requirements*/
+
+ if((p_q1_up = (double *) calloc(topology_params.height+1,sizeof(double))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ if((p_sigma = (double *) calloc(topology_params.height+1, sizeof(double))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ if((p_q2_up = (double *) calloc(topology_params.height+1, sizeof(double))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ if((p_q_up = (double *) calloc(topology_params.height+1, sizeof(double))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ if((p_b_up_bar = (double *) calloc(topology_params.height+1, sizeof(double))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ for(i=0; i<=topology_params.height; i++)
+ {
+ p_q1_up[i] = p_bif_up[i] * alpha_height_in.b; /* first term - burst [bits] [Q_H, Q_H-1, .., Q_0] */
+ p_sigma[i] = p_bif_up[i] * p_BETA_up[i].T * alpha_height_in.r; /* [bps][SIGMA_H-1, SIGMA_H-2, ...., SIGMA_0, X] */
+ p_q2_up[i] = 0;
+ }
+
+ for(i=0; i<=topology_params.height; i++)
+ {
+ for(j=0; j<=i; j++)
+ {
+ p_q2_up[i] = p_q2_up[i] + pow(topology_params.max_routers,i-j) * p_sigma[j]; /* second term - cummulative effect of service latency [Q_H, Q_H-1, .., Q_1] */
+ }
+ }
+
+ for(i=0; i<=topology_params.height; i++)
+ {
+ p_q_up[i] = p_q1_up[i] + p_q2_up[i]; /* [bits] [Q_H, Q_H-1, .., Q_0] = b* */
+ p_b_up_bar[i] = p_q_up[i] - p_sigma[i]; /* [b(H)_, b(H-1)_, .., b0_] */
+ }
+
+ p_q_up[topology_params.height] = p_b_up_bar[topology_params.height];
+
+ free((void *)p_sigma);
+ p_sigma = NULL;
+
+ free((void *)p_q1_up);
+ p_q1_up = NULL;
+
+ free((void *)p_bif_up);
+ p_bif_up = NULL;
+
+ /* downstream buffer requirements*/
+ if((p_q1_down = (double *) calloc(topology_params.height+1, sizeof(double))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ if((p_tau = (double *) calloc(topology_params.height+1, sizeof(double))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ if((p_q2_down = (double *) calloc(topology_params.height+1, sizeof(double))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ if((p_q3_down = (double *) calloc(topology_params.height+1, sizeof(double))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ if((p_q_down = (double *) calloc(topology_params.height+1, sizeof(double))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ if((p_b_down_bar = (double *) calloc(topology_params.height+1, sizeof(double))) == NULL)
+ {
+ p_output_params->error_code = 3;
+ return -1;
+ }
+
+ for(i=0; i<=topology_params.height; i++)
+ {
+ p_q1_down[i] = p_bif_down[i] * alpha_height_in.b; /* [bits] [Q_0, Q_1, .., Q_H] */
+ p_tau[i] = p_bif_down[i] * p_BETA_down[i].T * alpha_height_in.r; /* [bps][TAU_0, TAU_1, ...., TAU_H] */
+ p_q2_down[i] = 0;
+ p_q3_down[i] = 0;
+ }
+
+ for(i=0; i<topology_params.height; i++)
+ {
+ for(j=0; j<=i; j++)
+ {
+ p_q2_down[i] = p_q2_down[i] + p_q2_up[topology_params.height-j-1]; /* cummulative effect of downstream latency [Q_0, Q_1, .., Q_(H-1),0] */
+ }
+ p_q2_down[i] = (topology_params.max_routers - 1) * p_q2_down[i];
+ }
+
+ p_q3_down[0] = p_tau[0];
+
+ for(i=1; i<topology_params.height; i++)
+ {
+ p_q3_down[i] = p_q3_down[i-1] + p_tau[i]; /* cummulative effect of upstream latency [Q_0, Q_1, .., Q_(H-1),0] */
+ }
+
+ for(i=0; i<=topology_params.height; i++)
+ {
+ p_q_down[i] = p_q1_down[i] + p_q2_down[i] + p_q3_down[i]; /* [bits] [Q_0, Q_1, .., Q_(H-1),X] = b* */
+ p_b_down_bar[i] = p_q_down[i] - p_tau[i]; /* [b0_, b1_, .., b(H-1)_] */
+ }
+
+ p_b_down_bar[topology_params.height] = p_q_down[topology_params.height-1] + alpha_height_in.b; /* [bH_] */
+
+ p_output_params->p_buffer_requirements[0] = (int) ceil(alpha_data_out.b); /* [bits] */
+ for(i=1; i<=topology_params.height+1; i++)
+ {
+ p_output_params->p_buffer_requirements[i] = (int) ceil(p_q_up[i-1]); /* [bits] */
+ }
+
+ for(i=0; i<topology_params.h_sink; i++)
+ {
+ p_output_params->p_buffer_requirements[i+topology_params.height+1] = (int) ceil(p_q_down[i]); /* [bits] */
+ }
+
+ if(topology_params.h_sink > 0)
+ {
+ if(topology_params.h_sink < topology_params.height)
+ {
+ p_output_params->p_buffer_requirements[topology_params.h_sink+topology_params.height+1] = (int) ceil((alpha_height_in.b + topology_params.max_routers * p_q_up[topology_params.height-topology_params.h_sink-1] + p_q_down[topology_params.h_sink-1])); /* [bits] */
+
+ }else
+ {
+ p_output_params->p_buffer_requirements[topology_params.h_sink+topology_params.height+1] = (int) ceil(p_b_down_bar[topology_params.height]); /* [bits] */
+ }
+ }
+
+
+ free((void *)p_q3_down);
+ p_q3_down = NULL;
+
+ free((void *)p_q2_down);
+ p_q2_down = NULL;
+
+ free((void *)p_tau);
+ p_tau = NULL;
+
+ free((void *)p_q1_down);
+ p_q1_down = NULL;
+
+ free((void *)p_q2_up);
+ p_q2_up = NULL;
+
+ free((void *)p_bif_down);
+ p_bif_down = NULL;
+
+ /* ------------------------- PER-HOP DELAY BOUND --------------------------------------- */
+ /* upstream */
+ d_data = application_params.alpha_data.b/beta_data.R + beta_data.T; /* [sec] delay of end node Ddata*/
+
+ d_e2e_1 = d_data;
+ for(i=0; i<topology_params.height; i++)
+ {
+ d_e2e_1 = d_e2e_1 + p_b_up_bar[i]/p_BETA_up[i].R + p_BETA_up[i].T; /* [sec] end-to-end delay */
+ }
+
+ /* downstream */
+ if(topology_params.h_sink > 0)
+ {
+ for(i=0; i<topology_params.h_sink; i++)
+ {
+ d_e2e_1 = d_e2e_1 + p_b_down_bar[i]/p_BETA_down[i].R + p_BETA_down[i].T; /* [sec] end-to-end delay De2eEND_NODE_UP*/
+ }
+ }
+
+ /* --------------------- E2E Service curve - DELAY BOUND ----------------------------------- */
+ /* downstream */
+ if(topology_params.h_sink > 0)
+ {
+ beta_conn.R = p_BETA_down[topology_params.h_sink-1].R;
+ beta_conn.T = p_BETA_down[topology_params.h_sink-1].T;
+
+ if(topology_params.h_sink > 1)
+ {
+ for(i=topology_params.h_sink; i>=2; i--)
+ {
+ alpha_agg.b = (unsigned short) (p_b_down_bar[i-1] - p_q_down[i-2]); /* division of the input flow to one upstream flow and the rest */
+ alpha_agg.r = p_bandwidth_per_depth_down[i-1] - p_bandwidth_per_depth_down[i-2];
+ beta_eq = aggr(beta_conn, alpha_agg); /* equivalent service curve for one upstream flow */
+ beta_conn = concat(beta_eq, p_BETA_down[i-2]); /* concatenation of the service curves */
+ }
+ }
+
+ /* root */
+ alpha_agg.b = (unsigned short) (p_b_down_bar[0] - p_q_up[topology_params.height-1]); /* division of the input flow to one upstream flow and the rest */
+ alpha_agg.r = p_bandwidth_per_depth_down[0] - p_bandwidth_per_depth_up[topology_params.height-1];
+ beta_eq = aggr(beta_conn, alpha_agg); /* equivalent service curve for one upstream flow */
+ beta_conn = concat(beta_eq, p_BETA_up[topology_params.height-1]); /* concatenation of the service curves */
+ }else
+ {
+ beta_conn.R = p_BETA_up[topology_params.height-1].R;
+ beta_conn.T = p_BETA_up[topology_params.height-1].T;
+ }
+
+ /* upstream */
+ if(topology_params.height > 1)
+ {
+ for(i=topology_params.height; i>=2; i--)
+ {
+ alpha_agg.b = (unsigned short) (p_b_up_bar[i-1] - p_q_up[i-2]); /* division of the input flow to one upstream flow and the rest */
+ alpha_agg.r = p_bandwidth_per_depth_up[i-1] - p_bandwidth_per_depth_up[i-2];
+ beta_eq = aggr(beta_conn, alpha_agg); /* equivalent service curve for one upstream flow */
+ beta_conn = concat(beta_eq, p_BETA_up[i-2]); /* concatenation of the service curves */
+ }
+ }
+
+ /* at the maximum depth */
+ alpha_agg.b = (unsigned short) (p_b_up_bar[0] - alpha_data_out.b); /* [kbits] */
+ alpha_agg.r = p_bandwidth_per_depth_up[0] - alpha_data_out.r; /* [kbps] */
+ beta_eq = aggr(beta_conn, alpha_agg);
+ beta_conn = concat(beta_eq, beta_data);
+
+ d_e2e_2 = (application_params.alpha_data.b/beta_conn.R) + beta_conn.T; /* [sec] */
+
+ p_output_params->d_e2e = (d_e2e_2 < d_e2e_1) ? d_e2e_2 : d_e2e_1;
+ p_output_params->total_number_of_rouers = total_routers(topology_params.max_routers, topology_params.height);
+
+
+ free((void *)p_b_down_bar);
+ p_b_down_bar = NULL;
+
+ free((void *)p_q_down);
+ p_q_down = NULL;
+
+ free((void *)p_b_up_bar);
+ p_b_up_bar = NULL;
+
+ free((void *)p_q_up);
+ p_q_up = NULL;
+
+ free((void *)p_BETA_down);
+ p_BETA_down = NULL;
+
+ free((void *)p_bandwidth_per_depth_down);
+ p_bandwidth_per_depth_down = NULL;
+
+ free((void *)p_BETA_up);
+ p_BETA_up = NULL;
+
+ free((void *)p_bandwidth_per_depth_up);
+ p_bandwidth_per_depth_up = NULL;
+
+ return 0;
+}
+
+#ifdef _NOT_FRESCOR_
+/**
+* TRAFFIC_FILL extract sensory traffic from contract.
+*
+* @param[in] contract application contract
+* @param[in,out] p_cum_traffic cumulative traffic extracted through all contracts
+*
+* @return status code
+ */
+int traffic_fill(CONTRACT contract, TRAFFIC *p_cum_traffic)
+{
+ TRAFFIC_NODE_PARAMS node_params;
+ TRAFFIC_NODE_ALPHA node_alpha;
+ int i;
+
+
+ for(i=0; i<contract.length; i++)
+ {
+ node_params = contract.p_buffer[i];
+
+ /*search for duplicity */
+ if(update_node(p_cum_traffic, node_params) == -1)
+ {
+ /* node does not exist, add new node to traffic array */
+ /* conversion from user-defined parameters to arrival curve */
+
+ node_alpha.node_id = node_params.node_id;
+ node_alpha.alpha.b = node_params.payload;
+ node_alpha.alpha.r = node_params.payload/node_params.interarrival_time;
+
+ if(add_node(p_cum_traffic, node_alpha) == -1)
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+#else
+
+/**
+* TRAFFIC_FILL find the maximum arrival curve in a WSN.
+*
+* @param[in] contract application contract
+* @param[out] p_cum_traffic cumulative traffic extracted through all contracts
+*
+* @return status code
+ */
+
+int traffic_fill(CORBA_sequence_fres_block_cluster_tree_node_params *p_seq, TRAFFIC *p_cum_traffic)
+{
+ TRAFFIC_NODE_PARAMS node_params;
+ TRAFFIC_NODE_ALPHA node_alpha;
+ fres_block_cluster_tree_node_params *fres_node_params;
+ int i;
+
+ for (i=0; i<p_seq->_length; i++) {
+ fres_node_params = &p_seq->_buffer[i];
+
+ node_params.node_id = fres_node_params->node_id;
+ node_params.payload = fres_node_params->payload;
+ node_params.interarrival_time = fres_node_params->interarrival_time;
+
+ /*search for duplicity */
+ if(update_node(p_cum_traffic, node_params) == -1)
+ {
+ /* node does not exist, add new node to traffic array */
+ /* conversion from user-defined parameters to arrival curve */
+
+ node_alpha.node_id = node_params.node_id;
+ node_alpha.alpha.b = node_params.payload;
+ node_alpha.alpha.r = node_params.payload/node_params.interarrival_time;
+
+ if(add_node(p_cum_traffic, node_alpha) == -1)
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+#endif
+
+/**
+* MAX_ALPHA find the maximal arrival curve of sensory data traffic.
+*
+* @param[in] traffic applications' traffic
+*
+* @return ALPHA the maximal arrival curve
+ */
+ALPHA max_alpha(TRAFFIC traffic)
+{
+ ALPHA alpha_data_max;
+ int i;
+
+ alpha_data_max.r = 0;
+ alpha_data_max.b = 0;
+
+ /* search for maximum arrical curve */
+ for(i=0; i<traffic.length; i++)
+ {
+ alpha_data_max.b = max(alpha_data_max.b, traffic.p_nodes[i].alpha.b);
+ alpha_data_max.r = max(alpha_data_max.r, traffic.p_nodes[i].alpha.r);
+ }
+
+ alpha_data_max.b += MHR + MFR; /* add overhead: MPDU = MHR + MSDU + MFR */
+
+ return alpha_data_max;
+
+}
+
+
+/* ------------- support functions ------------ */
+
+/*
+* TOTAL_ROUTERS Compute the total number of routers in a WSN.
+*
+* @param[in] max_routers maximum number of child routers that can be associated to a parent router
+* @param[in] height height of the tree (maximum depth)
+*
+* @return total number of routers in a WSN
+*
+* @note H-1 = 1 + N_{router}^{MAX}
+* H-2 = (1 + N_{router}^{MAX}) + (N_{router}^{MAX})^2
+* H-3 = (1 + N_{router}^{MAX} + (N_{router}^{MAX})^2) + (N_{router}^{MAX})^3
+*/
+static int total_routers(int max_routers, int height)
+{
+ int i;
+ int routers_nbr;
+
+ routers_nbr = 1 + max_routers;
+
+ for(i=1; i<height; i++)
+ {
+ routers_nbr = routers_nbr + (int) pow(max_routers, i+1);
+ }
+
+ return routers_nbr;
+}
+
+
+/**
+ * FULL_TS_BANDWIDTH Compute the guaranteed bandwidth of one time slot GTS with 100% duty cycle (i.e. SO = BO).
+ *
+ * @param[in] SO [0-14] Superframe Order
+ * @param[in] mpdu [bits] user-defined maximum length of MAC data Frame (MPDU)
+ * @param[in] ack_enable [FALSE, TRUE] enable data frame acknowledgment
+ *
+ * @return [bps] guaranteed bandwidth of one time slot GTS with 100% duty cycle
+ */
+static double full_TS_bandwidth(int SO, unsigned short mpdu, int ack_enable)
+{
+ double mpdu_time = (double) mpdu/data_rate; /* [sec] MPDU duration */
+ double aMaxPHYPacketSize_time = (double) aMaxPHYPacketSize/data_rate; /* [sec] duration of the the maximum MPDU */
+ double aMaxSIFSFrameSize_time = (double) aMaxSIFSFrameSize/data_rate; /* [sec] */
+ double macAckWaitDuration_time = (double) macAckWaitDuration/data_rate; /* [sec] */
+
+ double SIFS_time = (double) SIFS/data_rate; /* [sec] */
+ double LIFS_time = (double) LIFS/data_rate; /* [sec] */
+
+ double IFS_time;
+ int mpdu_nbr; /* number of MPDU */
+ double TS_remain;
+ double mpdu_remain;
+ double mpdu_remain_time;
+
+ double SD = aBaseSuperframeDuration * pow(2, SO); /* [sec] Superframe duration */
+ double TS = SD/16; /* [sec] a time slot duration */
+
+ if(mpdu == 0) /* The MPDU length is not specified. */
+ {
+ IFS_time = LIFS_time;
+
+ if(ack_enable > 0)
+ IFS_time = IFS_time + macAckWaitDuration_time;
+
+ mpdu_nbr = (int) floor(TS/(aMaxPHYPacketSize_time + IFS_time)); /* The number of MPDU with maximum standard defined length transmitted during one time slot */
+ TS_remain = TS - mpdu_nbr * (aMaxPHYPacketSize_time + IFS_time); /* The remaining time at the end of TS */
+
+ if(ack_enable > 0)
+ TS_remain = TS_remain - macAckWaitDuration_time; /* [sec] The remaining time for last MPDU */
+
+ if((TS_remain - LIFS_time) > aMaxSIFSFrameSize_time)
+ {
+ mpdu_remain_time = TS_remain - LIFS_time; /* [sec] */
+ mpdu_remain = mpdu_remain_time * data_rate; /* The length of the MPDU followed by the LIFS and fitted into the remaining TS time */
+
+ }else
+ {
+ mpdu_remain_time = min(max((TS_remain - SIFS_time),0), aMaxSIFSFrameSize_time); /* [sec] */
+ mpdu_remain = mpdu_remain_time * data_rate; /* The length of the MPDU followed by the SIFS and fitted into the remaining TS time */
+ }
+
+ return (mpdu_nbr * aMaxPHYPacketSize + mpdu_remain)/SD; /* [bps] */
+
+ }else /* The MPDU length is specified (mpdu) */
+ {
+ if(mpdu >= aMaxSIFSFrameSize)
+ IFS_time = LIFS_time;
+ else
+ IFS_time = SIFS_time;
+
+ if(ack_enable > 0)
+ IFS_time = IFS_time + macAckWaitDuration_time;
+
+ mpdu_nbr = (int) floor(TS/(mpdu_time + IFS_time)); /* The number of MPDU with maximum user defined length transmitted during one time slot */
+ TS_remain = TS - mpdu_nbr * (mpdu_time + IFS_time); /* The remaining time at the end of TS */
+
+ if(ack_enable > 0)
+ TS_remain = TS_remain - macAckWaitDuration_time; /* [sec]The remaining time for last MPDU */
+
+ if((TS_remain - LIFS_time) > aMaxSIFSFrameSize_time)
+ {
+ mpdu_remain_time = TS_remain - LIFS_time; /* [sec] */
+ mpdu_remain = mpdu_remain_time * data_rate; /* The length of the MPDU followed by the LIFS and fitted into the remaining TS time */
+ }else
+ {
+ mpdu_remain_time = min(max((TS_remain - SIFS_time), 0), aMaxSIFSFrameSize_time); /* [sec] */
+ mpdu_remain = mpdu_remain_time * data_rate; /* The length of the MPDU followed by the SIFS and fitted into the remaining TS time */
+ }
+
+ return (mpdu_nbr * mpdu + mpdu_remain)/SD; /* [bps] */
+ }
+}
+
+/**
+* GAMA_FACTOR_DOWN Bandwith increase factor at a given depth (for downstream flows).
+* The factor represents the ratio of the additional bandwidth that a router,
+* at a depth must provide to its downstream child router as compared to the bandwidth at the lowest depth (H).
+*
+* @param[in] max_routers maximum number of child routers that can be associated to a parent router
+* @param[in] height height of the tree (maximum depth)
+* @param[out] p_bif bandwith increase factor at a given depth
+*/
+static void gama_factor_down(int max_routers, int height, int *p_bif)
+{
+ int i;
+
+ p_bif[0] = (int) pow(max_routers, height);
+
+ for(i=1; i<=height; i++)
+ {
+ p_bif[i]= p_bif[i-1]+ (int) pow(max_routers, (height-i));
+ }
+}
+
+/**
+* GAMA_FACTOR_UP Bandwith increase factor at a given depth (for upstream flows).
+* The factor represents the ratio of the additional bandwidth that a router,
+* at a depth must provide to its downstream child router as compared to the bandwidth at the lowest depth (H).
+*
+* @param[in] max_routers maximum number of child routers that can be associated to a parent router
+* @param[in] height height of the tree (maximum depth)
+* @param[out] p_bif bandwith increase factor at a given depth
+*/
+static void gama_factor_up(int max_routers, int height, int *p_bif)
+{
+ int i;
+
+ p_bif[0] = 1; /* Number of routers at maximum dept */
+
+ for(i=1; i<=height; i++)
+ {
+ p_bif[i]= p_bif[i-1]+ (int) pow(max_routers, i);
+ }
+}
+
+/**
+* CONCAT The concatenation of two service curves.
+*
+* @param[in] beta1 first service curve
+* @param[in] beta2 second service curve
+*
+* @return the concatenated final service curve
+*/
+static BETA concat(BETA beta1, BETA beta2)
+{
+ BETA beta;
+
+ beta.R = min(beta1.R, beta2.R);
+ beta.T = beta1.T + beta2.T;
+
+ return beta;
+}
+
+/**
+* AGGR A FIFO node multiplexes two flows (flow 1 an flow 2). The flow 2 is
+* constrained by an arrival curve <EM>alpha2</EM>. The service curve <EM>beta</EM> is
+* guaranteed to the aggregate of flows. Then, for any <EM>teta</EM>>=0, the returning
+* service curve <EM>beta1</EM> is guaranteed to flow 1.
+*
+* @param[in] beta service curve guaranteed to the aggregate of flows
+* @param[in] alpha2 arrival curve of the flow 2
+*
+* @return service curve guaranteed to the flow 1
+*/
+static BETA aggr(BETA beta, ALPHA alpha2)
+{
+ BETA beta1;
+ double teta = beta.T + (alpha2.b/beta.R);
+
+ beta1.R = beta.R - alpha2.r;
+ beta1.T = ((alpha2.b + (alpha2.r * (beta.T - teta)))/beta1.R) + beta.T;
+
+ return beta1;
+}
+
+/**
+* ZIGBEE ZigBee/IEEE 802.15.4 parameters relating to SO and BO.
+*
+* @param[in] SO [0-14] Superframe Order
+* @param[in] BO [0-14] Beacon Order
+* @param[in] mpdu [bits] user-defined maximum length of MAC data Frame (MPDU)
+* @param[in] ack_enable [FALSE, TRUE] enable data frame acknowledgment
+*
+* @return structure Z
+ */
+static Z zigbee(int SO, int BO, unsigned short mpdu, int ack_enable)
+{
+ double R_TS_full;
+ Z z;
+
+ z.BI = aBaseSuperframeDuration * pow(2, BO); /* [sec] Beacon Interval */
+ z.SD = aBaseSuperframeDuration * pow(2, SO); /* [sec] Superframe Duration */
+ z.duty_cycle = z.SD/z.BI;
+ z.TS = z.SD/16; /* [sec] Time Slot duration */
+
+ if(BO < SO)
+ BO = SO;
+
+ if(SO < 0)
+ SO = 0;
+
+ if(BO < 0)
+ BO = 0;
+
+ if(BO > 14)
+ BO = 14;
+
+ R_TS_full = full_TS_bandwidth(SO, mpdu, ack_enable); /* [bps] the guaranteed bandwidth of the GTS time slot at 100% duty cycle */
+ z.R_TS = R_TS_full * z.duty_cycle; /* [bps] the guaranteed bandwidth of the GTS time slot with chosen duty cycle */
+
+ return z;
+}
+
+
+/**
+* ADD_NODE add node to the dynamic array.
+*
+* @param[out] p_traffic array of nodes
+* @param[in] node new node
+*
+* @return status code
+ */
+static int add_node(TRAFFIC *p_traffic, TRAFFIC_NODE_ALPHA node)
+{
+ TRAFFIC_NODE_ALPHA *p_nodes_old;
+
+ p_nodes_old = p_traffic->p_nodes;
+
+ if((p_traffic->p_nodes = (TRAFFIC_NODE_ALPHA *) realloc(p_traffic->p_nodes, (p_traffic->length+1) * sizeof(TRAFFIC_NODE_ALPHA))) == NULL)
+ {
+ p_traffic->p_nodes = p_nodes_old;
+ return -1;
+ }
+
+ p_traffic->p_nodes[p_traffic->length] = node; /* add new node in the end */
+ p_traffic->length++;
+
+ return 0;
+}
+
+/**
+* UPDATE_NODE if the node already exist then update its traffic; otherwise return -1.
+*
+* @param[out] p_traffic array of nodes
+* @param[in] node_params new node
+*
+* @return status code (0: node exist + traffic updated; -1: node does not exist)
+ */
+static int update_node(TRAFFIC *p_traffic, TRAFFIC_NODE_PARAMS node_params)
+{
+ int i;
+
+ for(i=0; i<p_traffic->length; i++)
+ {
+ if(node_params.node_id == p_traffic->p_nodes[i].node_id)
+ {
+ p_traffic->p_nodes[i].alpha.b += node_params.payload;
+ p_traffic->p_nodes[i].alpha.r = p_traffic->p_nodes[i].alpha.r + node_params.payload/node_params.interarrival_time;
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file ct_wsn.h
+ * @author Petr Jurcik, 2008
+ *
+ * @brief Function prototypes and type definition
+ *
+ * @note error codes: \n
+ * 1 - The maximum number of child routers and end-nodes is greater than 7. \n
+ * 2 - The /f$ MPDU_{max} /f$ size is greater than 1016 bits (aMaxPHYPacketSize parameters) or less than 0. \n
+ * 3 - Memory allocation error. \n
+ * 4 - The total data rate is not feasible. Reduce data rate. \n
+ */
+
+#ifndef _CTWSN_H_
+#define _CTWSN_H_
+
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#ifdef FRESCOR
+#include <cluster_tree_idl.h>
+#endif
+
+#ifdef __GNUC__
+#include <math.h>
+#define max(a,b) fmax(a,b)
+#define min(a,b) fmin(a,b)
+#endif
+
+#define TRUE 1
+#define FALSE 0
+
+/* error codes */
+#define TOO_MANY_NODES 1 /**< The maximum number of child routers and end-nodes is greater than 7. */
+#define WRONG_MPDU_SIZE 2 /**< The /f$ MPDU_{max} /f$ size is greater than 1016 bits (aMaxPHYPacketSize parameters) or less than 0 */
+#define MEMORY_ALLOCATION_ERROR 3 /**< Memory allocation error */
+#define HIGH_DATA_RATE 4 /**< The total data rate is not feasible. Reduce data rate */
+
+/* IEEE 802.15.4 standard related constants */
+static const int data_rate = 250000; /* data rate at 2.4 GHz [bps]*/
+static const double aBaseSuperframeDuration = 0.01536; /* [sec] */
+static const int MHR = 88; /* MAC Header (16-bit addresses) [bits] */
+static const int MFR = 16; /* MAC Footer [bits] */
+
+
+static const int aMaxPHYPacketSize = 1016; /* the maximum length of MAC data Frame (MPDU) defined in the standard [bits] */
+static const int aMaxSIFSFrameSize = 144; /* the maximum size of MPDU that can be followed by the SIFS [bits] */
+static const double aMinCAPLength = 0.00704; /* aMinCAPLength = 440 Symbols = 7.04 ms (2.4 GHz, 250 kbps) [sec] */
+
+static const int macAckWaitDuration = 216; /* [bits] the maximum number of bits to wait for ACK frame [bits] */
+
+static const int SIFS = 48; /**< short IFS, minimum (aMinSIFSPeriod) = 48 [bits] */
+static const int LIFS = 768; /**< long IFS, minimum (aMinLIFSPeriod) = 160 [bits] */
+
+
+/*********************************************************
+* structure type definition
+*********************************************************/
+
+/**
+* rate-latency service curve (Network Calculus)
+*/
+typedef struct {
+ double R; /**< forwarding rate; R >= r [bps] */
+ double T; /**< latency of forwarding data [sec] */
+} BETA;
+
+/**
+* (b,r) arrival curve (Network Calculus)
+*/
+typedef struct {
+ double r; /**< the average arrival rate of sensory data flow [bps] */
+ unsigned short b; /**< the burst of sensory data flow [bits] */
+} ALPHA;
+
+/**
+* topology parameters
+*/
+typedef struct {
+ unsigned short max_routers; /**< /f$ N_{router}^{MAX} /f$ maximum number of routers that can be associated to a router */
+ unsigned short max_end_nodes; /**< /f$ N_{end-node}^{MAX} /f$ maximum number of end-nodes that can be associated to a router */
+ unsigned short height; /**< H height of cluster-tree WSN */
+ unsigned short h_sink; /**< /f$ H_{sink} /f$ the depth of the sink router */
+ unsigned short SO; /**< Superframe Order [0-14] */
+ int sensing_cap; /**< sensing capability of the routers [FALSE, TRUE] */
+} TOPOLOGY_PARAMS;
+
+/**
+* application parameters
+*/
+typedef struct {
+ int ack_enable; /**< enable data frame acknowledgment [FALSE, TRUE] */
+ ALPHA alpha_data; /**< maximum arrival curve of sensory data */
+} APPLICATION_PARAMS;
+
+/**
+* output parameters
+*/
+typedef struct{
+ unsigned short error_code; /**< return error code */
+ double d_e2e; /**< the worst-case end to end deadline [sec] */
+ unsigned short total_number_of_rouers; /**< total number of routers in a WSN */
+ unsigned short *p_number_of_time_slots; /**< total number of time slots provided by a router at depth /f$ H_{UP}, H-1_{UP}, ... , H_{sink}-1_{DOWN} /f$ */
+ int *p_buffer_requirements; /**< the buffer requirement by a router at depth /f$ H+1_{UP}, H_{UP}, ... , H_{sink}_{DOWN} /f$ [bits] */
+} OUTPUT_PARAMS;
+
+/* user-define sensor traffic of a node */
+typedef struct{
+ int node_id; /**< ID number of a sensor node */
+ double interarrival_time; /**< time between two consecutive packets [sec] */
+ unsigned short payload; /**< size of generated payload (MSDU) [bits] */
+} TRAFFIC_NODE_PARAMS;
+
+/**
+* Sensor traffic of a node
+*/
+typedef struct{
+ int node_id; /**< ID number of a sensor node */
+ ALPHA alpha; /**< (b,r) arrival curve */
+} TRAFFIC_NODE_ALPHA;
+
+/**
+* WSN traffic extracted from contracts
+*/
+typedef struct{
+ int length; /**< number of nodes */
+ TRAFFIC_NODE_ALPHA *p_nodes; /**< arrray of nodes */
+}TRAFFIC;
+
+/**
+* IEEE 802.15.4 parameters
+*/
+typedef struct {
+ double duty_cycle; /**< duty cycle [0.01 %] */
+ double R_TS; /**< The maximum bandwidth guaranteed by a GTS time slot for given SO and duty cycle [bps] */
+ double BI; /**< Beacon Interval [sec] */
+ double SD; /**< Superframe Duration [sec] */
+ double TS; /**< Time slot duration [sec] */
+} Z;
+
+
+#ifndef FRESCOR /* required only for standalone application (without FRESCOR) */
+
+typedef struct{
+ int length; /* number of nodes */
+ TRAFFIC_NODE_PARAMS *p_buffer; /* array of nodes */
+} CONTRACT;
+
+#endif
+/*********************************************************
+* function prototypes
+*********************************************************/
+
+int ct_wsn(TOPOLOGY_PARAMS topology_params, APPLICATION_PARAMS application_params, OUTPUT_PARAMS *output_params); /**< worst-case analysis */
+ALPHA max_alpha(TRAFFIC traffic); /**< fint he maximal arrival curve of sensory data traffic */
+
+#ifndef FRESCOR
+int traffic_fill(CONTRACT contract, TRAFFIC *p_cum_traffic); /* standalone version (without FRESCOR) */
+#else
+int traffic_fill(CORBA_sequence_fres_block_cluster_tree_node_params *p_seq, TRAFFIC *p_cum_traffic);
+#endif
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file ct_wsn_test.c
+ * @author Petr Jurcik, 2008
+ *
+ * @brief The test function not requiring the FRESCOR framework (standalone version). (_NOT_FRESCOR_)
+ *
+ */
+
+#include "ct_wsn.h"
+
+
+int main(int argc, char *argv[])
+{
+ TOPOLOGY_PARAMS topology_params;
+ APPLICATION_PARAMS application_params;
+ OUTPUT_PARAMS output_params;
+
+ CONTRACT contracts[3];
+ TRAFFIC traffic;
+ int i, j;
+
+ topology_params.max_routers = 2;
+ topology_params.max_end_nodes = 2;
+ topology_params.height = 2;
+ topology_params.h_sink = 1;
+ topology_params.SO = 3;
+ topology_params.sensing_cap = FALSE;
+
+ /* -- contract initialization - */
+ contracts[0].length = 15;
+ contracts[1].length = 9;
+ contracts[2].length = 10;
+
+ for(i=0; i<sizeof(contracts)/sizeof(contracts[0]); i++)
+ {
+ if((contracts[i].p_buffer = (TRAFFIC_NODE_PARAMS *) calloc(contracts[i].length, sizeof(TRAFFIC_NODE_PARAMS))) == NULL)
+ return -1;
+
+ for(j=0; j<contracts[i].length; j++)
+ {
+ contracts[i].p_buffer[j].node_id = (int) (0xFF * (rand()/((double)RAND_MAX + 1))) + 1; /* [1 - FFFF] */
+ contracts[i].p_buffer[j].interarrival_time = 60 * (rand()/((double)RAND_MAX + 1)) + 0.0001; /* [0.0001 - 60.0 sec] */
+ contracts[i].p_buffer[j].payload = (int) (200 * (rand()/((double)RAND_MAX + 1))) + 1; /* [1 - 100 bits] */
+ }
+ }
+ /* -- end of contract initialization-- */
+
+ traffic.length = 0;
+ traffic.p_nodes = NULL;
+
+ /* for each contract */
+ for(i=0; i<sizeof(contracts)/sizeof(contracts[0]); i++)
+ {
+ if(traffic_fill(contracts[i], &traffic) == -1)
+ return -1;
+ }
+
+ application_params.ack_enable = FALSE;
+ application_params.alpha_data = max_alpha(traffic); /* find the maximal arrival curve from sensory traffic */
+
+ if((output_params.p_buffer_requirements = (int *) calloc(topology_params.height+topology_params.h_sink+2, sizeof(int))) == NULL)
+ return -1;
+
+ if((output_params.p_number_of_time_slots = (unsigned short *) calloc(topology_params.height+topology_params.h_sink, sizeof(int))) == NULL)
+ return -1;
+
+ if(ct_wsn(topology_params, application_params, &output_params) == -1)
+ {
+ printf("error-code: %d\n", output_params.error_code);
+ }
+ else{
+ printf("the worst-case end-to-end deadline: %f sec\n", output_params.d_e2e);
+ }
+
+ free((void *)output_params.p_number_of_time_slots);
+ output_params.p_number_of_time_slots = NULL;
+
+ free((void *)output_params.p_buffer_requirements);
+ output_params.p_buffer_requirements = NULL;
+
+ return 0;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file frm_cluster_tree.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Wed Feb 18 16:14:35 2009
+ *
+ * @brief Resource manager for cluster tree WSN
+ *
+ */
+
+
+#include <frm_generic.h>
+#include <forb.h>
+#include <error.h>
+#include <errno.h>
+#include <fres_sa_scenario.h>
+#include <stdbool.h>
+#include <ul_log.h>
+#include <stdio.h>
+#include <frsh_distributed.h>
+#include "ct_wsn.h"
+#include <cluster_tree.h>
+
+struct cluster_tree {
+ TOPOLOGY_PARAMS topology;
+};
+
+struct cluster_tree configuration = {
+ .topology = {
+ .max_routers = 2,
+ .max_end_nodes = 2,
+ .height = 2,
+ .h_sink = 1,
+ .SO = 3,
+ .sensing_cap = FALSE,
+ }
+};
+
+
+int admission_test(struct fres_sa_scenario *scenario, void *priv, bool *schedulable)
+{
+ struct cluster_tree *configuration = priv;
+ TOPOLOGY_PARAMS *topology = &configuration->topology;
+ struct fres_sa_contract *c;
+ APPLICATION_PARAMS application_params;
+ int ret;
+ OUTPUT_PARAMS output_params;
+ TRAFFIC cum_traffic;
+ frsh_rel_time_t min_deadline = fosa_msec_to_rel_time(0);
+
+ cum_traffic.length = 0;
+ cum_traffic.p_nodes = NULL;
+
+ fres_sa_scenario_for_each_no_cancel_contract(scenario, c) {
+ fres_block_cluster_tree_traffic *contract_traffic;
+ frsh_rel_time_t deadline;
+
+ /* Extract the cumulative traffic through all contracts */
+ contract_traffic = fres_contract_get_cluster_tree_traffic(c->contract);
+ if(traffic_fill(&contract_traffic->nodes, &cum_traffic) == -1) {
+ ret = -1;
+ goto err_free_traffic;
+ }
+
+ /* Find the most restricting deadline */
+ if (fres_contract_get_deadline(&c->contract, &deadline)) {
+ if (fosa_rel_time_is_null(min_deadline) ||
+ fosa_rel_time_smaller(deadline, min_deadline)) {
+ min_deadline = deadline;
+ }
+ }
+ }
+
+ application_params.ack_enable = FALSE;
+ application_params.alpha_data = max_alpha(cum_traffic); /* Find the maximal arrival curve from sensory traffic */
+
+ output_params.p_buffer_requirements =
+ (int *) malloc((topology->height+topology->h_sink+2)*sizeof(int));
+ if (output_params.p_buffer_requirements == NULL) {
+ ret = -1;
+ goto err_free_traffic;
+ }
+
+ output_params.p_number_of_time_slots =
+ (unsigned short *) malloc((topology->height+topology->h_sink)*sizeof(int));
+ if(output_params.p_number_of_time_slots == NULL) {
+ ret = -1;
+ goto err_free_req;
+ }
+
+ /* Call the real admission test */
+ ret = ct_wsn(*topology, application_params, &output_params);
+ if(ret == -1)
+ {
+ *schedulable = false;
+ printf("error-code: %d\n", output_params.error_code);
+ } else {
+ /* Compare the deadlines */
+ if (output_params.d_e2e > fosa_rel_time_to_double(min_deadline)) {
+ *schedulable = false;
+ } else {
+ *schedulable = true;
+ }
+ }
+
+ ret = 0;
+
+ free((void *)output_params.p_number_of_time_slots);
+err_free_req:
+ free((void *)output_params.p_buffer_requirements);
+err_free_traffic:
+ free(cum_traffic.p_nodes);
+ return ret;
+}
+
+static const struct fres_res_manager frm = {
+ .res_type = FRSH_RT_NETWORK,
+ .res_id = FRSH_NETPF_CLUSTER_TREE,
+ .admission_test = admission_test,
+ .priv = &configuration,
+};
+
+
+int main(int argc, char *argv[])
+{
+ forb_orb orb;
+ int ret;
+ forb_init_attr_t attr = { .orb_id = "org.frescor.frm.cluster_tree" };
+ orb = forb_init(&argc, &argv, &attr);
+ if (!orb) error(1, errno, "forb_init");
+
+ fres_block_register_cluster_tree();
+
+ ret = frm_register_and_run(orb, &frm);
+
+ if (ret != 0) {
+ error(1, errno, "frm_generic_run failed");
+ }
+
+ return 0;
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+default_CONFIG = CONFIG_AQUOSA=x
+
+ifeq ($(CONFIG_AQUOSA),y)
+SUBDIRS = lib mngr tests
+CFLAGS+= -Wall -Wextra -D_REENTRANT
+endif
+#include_HEADERS +=$(wildcard aquosa/qresmod/*.h)
+#include_HEADERS +=$(wildcard aquosa/rresmod/*.h)
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+shared_LIBRARIES = frshaqcpu
+CFLAGS += -I $(AQUOSA_ROOT)/include
+frshaqcpu_SOURCES += aqcpu_contract.c aqcpu_fra.c
+include_HEADERS += aqcpu_contract.h aqcpu_res.h
+frshaqcpu_LDFLAGS += -L $(AQUOSA_ROOT)/lib -Xlinker -rpath -Xlinker $(AQUOSA_ROOT)/lib
+frshaqcpu_LIBS += qreslib qsuplib
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file aqcpu_contract.c
+ * @author Martin Molnar <molnam1@fel.cvut.cz>
+ * @date Wed Feb 18 16:19:54 2009
+ *
+ * @brief
+ *
+ *
+ */
+
+
+#include "aqcpu_contract.h"
+
+int get_aqcpu_params(fres_vres_t *vres, aqcpu_params_t *params)
+{
+ fres_block_basic *basic;
+
+ /* get params from contract */
+ basic = fres_contract_get_basic(vres->new);
+
+ /* core contract parameters */
+ params->Q_min = params->Q = timespec_to_usec(basic->budget);
+ params->P = timespec_to_usec(basic->period);
+
+ /* AQuoSA specific configuration */
+ params->flags = 0x000;
+ params->flags |= QOS_F_PERSISTENT;
+
+ /* if we're negotiating for the service thread create
+ * a soft server */
+ /*if (contract == &service_th_contract) {
+ qres_contract.flags |= QOS_F_SOFT;
+ }*/
+
+ params->timeout = 0;
+
+ return 0;
+}
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file aqcpu_contract.h
+ * @author Martin Molnar <molnam1@fel.cvut.cz>
+ * @date Wed Feb 18 16:21:07 2009
+ *
+ * @brief
+ *
+ *
+ */
+
+
+#ifndef AQCPU_CONTRACT_H
+#include "aquosa/qres_lib.h"
+#include <fra_generic.h>
+
+typedef qres_params_t aqcpu_params_t;
+
+int get_aqcpu_params(fres_vres_t *vres, aqcpu_params_t *params);
+
+#endif /* AQCPU_CONTRACT_H */
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of AQCPU (Aquosa CPU) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including AQCPU header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file aqcpu_fra.c
+ * @author Martin Molnar <molnam1@fel.cvut.cz>
+ * @date Wed Feb 18 16:21:01 2009
+ *
+ * @brief
+ *
+ *
+ */
+
+
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <fra_generic.h>
+
+#include "aquosa/qres_lib.h"
+#include "aquosa/qsup_lib.h"
+
+#include "aqcpu_contract.h"
+
+UL_LOG_CUST(ulogd_fra_aqcpu);
+ul_log_domain_t ulogd_fra_aqcpu = {UL_LOGL_MSG, "fra_aqcpu"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(fra_aqcpu_logreg_domains, ulogd_fra_aqcpu);
+
+static int aqcpu_initialized = 0; /* initialization flag */
+
+/*
+ * Test whether Aquosa Cpu modue is initialized
+ */
+static inline int aqcpu_is_initialized()
+{
+ return (aqcpu_initialized == 1);
+}
+
+
+
+static int aqcpu_create_vres(fres_vres_t *vres, void *priv)
+{
+ aqcpu_params_t cpu_params;
+ qres_sid_t sid;
+ qos_rv rv;
+
+ if (vres->priv) {
+ errno = -EINVAL;
+ return -1;
+ }
+
+ /* get aqcpu params from contract */
+ get_aqcpu_params(vres, &cpu_params);
+ /* create cpu vres */
+ rv = qres_create_server(&cpu_params, &sid);
+ if (rv != QOS_OK) {
+ return qos_rv_int(rv);
+ }
+
+ ul_logdeb("Created AQCPU VRES(sid=%d period=%lld us, budget=%lld us)\n",
+ sid, cpu_params.P, cpu_params.Q);
+ if ((vres->priv = malloc(sizeof(qres_sid_t)))) {
+ memcpy(vres->priv, &sid, sizeof(qres_sid_t));
+ }
+
+ return 0;
+}
+
+/*
+ * aqcpu_cancel_vres(), cancels vres
+ *
+ * The threads bound to the vres are unbound, and so, detached from their
+ * AQuoSA resource reservation server and continue their execution according
+ * to the standard Linux scheduler policies.
+ *
+ */
+static int aqcpu_cancel_vres(fres_vres_t *vres, void *priv)
+{
+ qres_sid_t sid;
+ qos_rv qrv;
+
+ if (!vres->priv) {
+ errno = -EINVAL;
+ return -1;
+ }
+ memcpy(&sid, vres->priv, sizeof(qres_sid_t));
+
+ qrv = qres_destroy_server(sid);
+ if (qrv != QOS_OK) {
+ return qos_rv_int(qrv);
+ }
+ ul_logdeb("Canceled AQCPU VRES(sid=%d)\n",sid);
+ free(vres->priv);
+
+ return 0;
+}
+
+/* aqcpu_vres_change(), change some parameters of a vres
+ *
+ * In fact, since that AQuoSA call doesn't deal with _its_ Q_min (budget_min
+ * for in FRSH semantic) parameter all the renegotiation will be accepted but
+ * the new temporal behaviour is not guaranteed!
+ * Obviously this is a bug and should/will be corrected in AQuoSA as soon as
+ * possible.
+ *
+ */
+static
+int aqcpu_change_vres(fres_vres_t *vres, void *priv)
+{
+ aqcpu_params_t cpu_params;
+ qres_sid_t sid;
+ qos_rv qrv;
+
+ if (!vres->priv) {
+ errno = -EINVAL;
+ return -1;
+ }
+ memcpy(&sid, vres->priv, sizeof(qres_sid_t));
+
+ /* get aqcpu params from contract */
+ get_aqcpu_params(vres, &cpu_params);
+
+ /* set cpu params */
+ qrv = qres_set_params(sid, &cpu_params);
+
+ vres->perceived = vres->new;
+
+ ul_logmsg("AQCPU VRES(sid=%d) params changed(period=%lld us,"
+ "budget=%lld us)\n",sid, cpu_params.P,cpu_params.Q);
+
+ return 0;
+}
+
+/*
+ * installed as an exit handler (with 'atexit()') by the initialization
+ * code... For now it only calls the cleanup function of the AQuoSA
+ * Framework
+ */
+static inline void aqcpu_cleanup_wrapper() {
+ qres_cleanup();
+}
+
+#if 0
+static
+int aqcpu_fra_exit()
+{
+ qos_rv rv;
+
+ rv = qres_cleanup();
+ return qos_rv_int(rv);
+}
+#endif
+
+static
+int fra_CPU_bind_thread
+ (fres_vres_t *vres,
+ const fosa_thread_id_t thread)
+{
+ qos_rv qrv;
+ qres_sid_t sid = *((qres_sid_t*)vres->priv);
+
+ if ((qrv = qres_attach_thread(sid, thread.linux_pid,
+ thread.linux_tid)) != QOS_OK)
+ goto err;
+
+ return 0;
+err:
+ return -1;
+}
+
+static
+int fra_CPU_unbind_thread(const fosa_thread_id_t thread)
+{
+ qos_rv qrv;
+ qres_sid_t sid;
+
+ if (qres_get_sid(thread.linux_pid, thread.linux_tid, &sid) != QOS_OK)
+ goto err;
+
+ if ((qrv = qres_detach_thread(sid, thread.linux_pid,
+ thread.linux_tid)) != QOS_OK)
+ goto err;
+
+ return 0;
+err:
+ return -1;
+}
+
+static
+int fra_CPU_get_usage
+ (const fres_vres_t *vres,
+ fosa_rel_time_t *spent)
+{
+ qres_sid_t sid = *((qres_sid_t*)vres->priv);
+ qres_time_t exec_budget;
+ qos_rv rv;
+
+ if (!spent)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ rv = qres_get_exec_time(sid, &exec_budget, NULL);
+ if (rv != QOS_OK) return EINVAL;
+
+ *spent = fosa_usec_to_rel_time(exec_budget);
+
+ return 0;
+}
+
+static
+int fra_CPU_get_job_usage
+ (const fres_vres_t *vres,
+ fosa_rel_time_t *spent)
+{
+ qres_sid_t sid = *((qres_sid_t*)vres->priv);
+ qres_params_t q_params;
+ qres_time_t curr_budget;
+ qos_rv rv;
+
+ if (!spent)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ rv = qres_get_params(sid, &q_params);
+ if (rv != QOS_OK) return EINVAL;
+ rv = qres_get_curr_budget(sid, &curr_budget);
+ if (rv != QOS_OK) return EINVAL;
+
+ *spent = fosa_usec_to_rel_time(q_params.Q - curr_budget);
+
+ return 0;
+}
+
+static
+int fra_CPU_get_remaining_budget
+ (const fres_vres_t *vres,
+ fosa_rel_time_t *budget)
+{
+ qres_sid_t sid = *((qres_sid_t*)vres->priv);
+ qres_time_t curr_budget;
+ qos_rv rv;
+
+ if (!budget)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ rv = qres_get_curr_budget(sid, &curr_budget);
+ if (rv != QOS_OK) return EINVAL;
+
+ *budget = fosa_usec_to_rel_time(curr_budget);
+
+ return 0;
+}
+
+static
+int fra_CPU_set_spare_bandwidth(fres_vres_t *vres)
+{
+ qres_sid_t fake_sid = (qres_sid_t) -1;
+ aqcpu_params_t cpu_params;
+ qos_rv rv;
+
+ /* get aqcpu params from contract */
+ get_aqcpu_params(vres, &cpu_params);
+
+
+ /* reserve CPU bandwidth for feedback */
+ rv = qsup_reserve_spare(r2bw(cpu_params.Q, cpu_params.P));
+ if (rv != QOS_OK) return qos_rv_int(rv);
+
+ ul_logdeb("Created AQCPU spare (period=%lld us, budget=%lld us)\n",
+ cpu_params.P, cpu_params.Q);
+ if ((vres->priv = malloc(sizeof(qres_sid_t)))) {
+ memcpy(vres->priv, &fake_sid, sizeof(qres_sid_t));
+ }
+
+ return 0;
+}
+
+static
+int fra_CPU_get_desired_budget
+ (fres_vres_t *vres,
+ frsh_rel_time_t *p_budget_out)
+{
+ qres_sid_t sid = *((qres_sid_t*)vres->priv);
+ qres_params_t q_params;
+ qos_rv rv;
+
+ if (!p_budget_out)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ rv = qres_get_params(sid, &q_params);
+ if (rv != QOS_OK) return EINVAL;
+
+ *p_budget_out = fosa_usec_to_rel_time(q_params.Q);
+
+ return 0;
+}
+
+static
+int fra_CPU_set_desired_budget
+ (fres_vres_t *vres,
+ fosa_rel_time_t *p_budget_in)
+{
+ qres_sid_t sid = *((qres_sid_t*)vres->priv);
+ qres_params_t q_params;
+ qos_rv rv;
+
+ if (!p_budget_in)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ rv = qres_get_params(sid, &q_params);
+ if (rv != QOS_OK) return EINVAL;
+
+ q_params.Q = fosa_rel_time_to_usec(*p_budget_in);
+
+ rv = qres_set_params(sid, &q_params);
+ if (rv != QOS_OK) return EINVAL;
+
+ return 0;
+}
+
+static
+int fra_CPU_get_actual_budget
+ (fres_vres_t *vres,
+ fosa_rel_time_t *budget)
+{
+ qres_sid_t sid = *((qres_sid_t*)vres->priv);
+ qres_time_t appr_budget;
+ qos_rv rv;
+
+ if (!budget)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ rv = qres_get_appr_budget(sid, &appr_budget);
+ if (rv != QOS_OK) return EINVAL;
+
+ *budget = fosa_usec_to_rel_time(appr_budget);
+
+ return 0;
+}
+
+int aqcpu_fra_activate(forb_orb orb)
+{
+ qos_rv qrv;
+ if ((qrv = qres_init()) != QOS_OK) {
+ if (qrv == QOS_E_MISSING_COMPONENT) {
+ return FRES_ERR_KERNEL_SUPPORT_MISSING;
+ } else
+ return FRSH_ERR_INTERNAL_ERROR;
+ }
+
+ /* install the cleanup function of th AQuoSA framework as an exit
+ * handler function (quite futile but, for now, it's sufficent) */
+ if (atexit(aqcpu_cleanup_wrapper)) {
+ qres_cleanup();
+ return(FRSH_ERR_INTERNAL_ERROR);
+ }
+
+ aqcpu_initialized = 1;
+
+ return 0;
+}
+
+static struct fres_allocator aqcpu_allocator = {
+ .res_type = FRSH_RT_PROCESSOR,
+ .res_id = FRSH_CPU_ID_DEFAULT, /* CPU ID 0 */
+ .create_vres = aqcpu_create_vres,
+ .cancel_vres = aqcpu_cancel_vres,
+ .change_vres = aqcpu_change_vres,
+
+ .bind_thread = fra_CPU_bind_thread,
+ .unbind_thread = fra_CPU_unbind_thread,
+
+ .vres_get_usage = fra_CPU_get_usage,
+ .vres_get_job_usage = fra_CPU_get_job_usage,
+ .vres_get_remaining_budget = fra_CPU_get_remaining_budget,
+
+ .set_spare_bandwidth = fra_CPU_set_spare_bandwidth,
+ .get_desired_budget = fra_CPU_get_desired_budget,
+ .set_desired_budget = fra_CPU_set_desired_budget,
+ .get_actual_budget = fra_CPU_get_actual_budget,
+
+ .activate_callback = aqcpu_fra_activate,
+
+ .priv = NULL
+};
+
+/*
+ * aqcpu_fra_init(), initialize FRSH for the calling process
+ *
+ * Must be called before starting using the framework.
+ * No FRSH call will be successful if this routine is not invoked
+ *
+ * Note that no BACKGROUND is created and negotiated and the caller thread
+ * is bound to no BACKGROUND vres, since no way is provided in order of
+ * specifying the contract label and get back the vres id!
+ *
+ * Note also that, since in this implementation the threads/processes with
+ * backgound contracts are left into the default Linux scheduler hands' and
+ * not attached to any AQuoSA server, while we're violating what D-AC2v1
+ * (pag. 14) says, we achieve exactly the same behaviour!!
+ */
+int aqcpu_fra_init(void)
+{
+ int rv;
+
+ aqcpu_allocator.res_id = frsh_get_local_cpu_id();
+
+ if ((rv = fra_register(&aqcpu_allocator))) {
+ return rv;
+ }
+
+ return 0;
+}
--- /dev/null
+module fres {
+ module block {
+ struct aqcpu_reqs {
+ fosa_rel_time_t budget_min;
+ unsigned short flags;
+ /* add more contract specific params */
+ };
+
+ struct aqcpu_sched {
+ /* params added by resource manager for
+ * scheduling purposes
+ */
+ }
+ };
+};
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of AQCPU (Aquosa CPU) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including AQCPU header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+#ifndef AQCPU_RES_H
+#define AQCPU_RES_H
+
+#include <fres_vres.h>
+
+#include <forb.h>
+#include <fcb.h>
+
+int aqcpu_fra_init(void);
+
+#endif /* AQCPU_RES_H */
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+bin_PROGRAMS = frm_aqcpu
+frm_aqcpu_SOURCES = frm_aqcpu.c
+LOADLIBES += -L $(AQUOSA_ROOT)/lib -lqreslib -lqsuplib
+LOADLIBES += -Xlinker -rpath -Xlinker $(AQUOSA_ROOT)/lib
+frm_aqcpu_LIBS = frm forb contract fosa rt ulut fcb_client qreslib qsuplib
+lib_LOADLIBES+= frsh
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of AQCPU (Aquosa CPU) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file aqcpu_mngr.c
+ * @author Martin Molnar <molnam1@fel.cvut.cz>
+ * @date Wed Feb 18 16:22:56 2009
+ *
+ * @brief
+ *
+ *
+ */
+
+
+#include <frm_generic.h>
+#include <forb.h>
+#include <error.h>
+#include <errno.h>
+#include <getopt.h>
+#include <fres_sa_scenario.h>
+#include <stdbool.h>
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <stdio.h>
+
+UL_LOG_CUST(ulogd_frm_aqcpu);
+ul_log_domain_t ulogd_frm_aqcpu = {UL_LOGL_DEB, "frm_aqcpu"};
+
+static int aqcpu_admtest(struct fres_sa_scenario *scenario, void *priv,
+ bool *schedulable)
+{
+ struct fres_sa_contract *c;
+ long int period, budget;
+ long int sum_utilization = 0;
+
+ fres_sa_scenario_for_each_no_cancel_contract(scenario, c) {
+ fres_block_basic *basic;
+ char id[40];
+ fres_contract_id_to_string(id, &c->contract->id, sizeof(id));
+ basic = fres_contract_get_basic(c->contract);
+
+ period = fosa_rel_time_to_msec(basic->period);
+ budget = fosa_rel_time_to_msec(basic->budget);
+
+ ul_logdeb("processing : id=%s, period=%ld ms, budget=%ld ms\n",
+ id, period, budget);
+
+ sum_utilization+= budget*100/period;
+ }
+ *schedulable = sum_utilization <= 88; // 100;
+ if (*schedulable) {
+ scenario->utilization = sum_utilization;
+ }
+ ul_logmsg("=> %s\n", *schedulable?"schedulable":"not schedulable");
+
+ return 0;
+}
+
+static struct fres_res_manager frm = {
+ .res_type = FRSH_RT_PROCESSOR,
+ .res_id = FRSH_CPU_ID_DEFAULT,
+ .admission_test = aqcpu_admtest,
+ .name = "AQuoSA",
+ .priv = NULL
+};
+
+static struct option long_opts[] = {
+ { "loglevel", 1, 0, 'l' },
+ { 0, 0, 0, 0}
+};
+
+static void
+usage(void)
+{
+ printf("usage: frm_aqcpu [ options ]\n");
+ printf(" -d, --daemon [pid-file] go to background after FORB initialization\n");
+ printf(" -l, --loglevel <number>|<domain>=<number>,...\n");
+}
+
+int main(int argc, char *argv[])
+{
+ forb_orb orb;
+ int ret;
+ forb_init_attr_t attr = { .orb_id = "org.frescor.frm.aqcpu" };
+ int opt;
+ bool opt_daemon = false;
+ char *opt_pidfile = NULL;
+
+ ul_logreg_domain(&ulogd_frm_aqcpu);
+
+ while ((opt = getopt_long(argc, argv, "d::hl:", &long_opts[0], NULL)) != EOF) {
+ switch (opt) {
+ case 'd':
+ opt_daemon = true;
+ opt_pidfile = optarg;
+ break;
+ case 'l':
+ ul_log_domain_arg2levels(optarg);
+ break;
+ case 'h':
+ /*default:*/
+ usage();
+ exit(opt == 'h' ? 0 : 1);
+ }
+ }
+
+ if (opt_daemon)
+ forb_daemon_prepare(opt_pidfile);
+
+ orb = forb_init(&argc, &argv, &attr);
+ if (!orb) error(1, errno, "forb_init");
+
+ frm.res_id = frsh_get_local_cpu_id();
+ ret = frm_register_and_run(orb, &frm);
+
+ if (ret != 0) {
+ error(1, errno, "frm_generic_run");
+ }
+
+ return 0;
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+test_PROGRAMS = aqcputest
+aqcputest_SOURCES = aqcputest.c
+LOADLIBES += -L $(AQUOSA_ROOT)/lib -lqreslib -lqsuplib
+#aqcpumngr_LIBS = frm forb contract fosa rt ulut fcb_client
+lib_LOADLIBES += pthread rt frsh qreslib
--- /dev/null
+#include <frsh.h>
+#include <aqcpu_res.h>
+#include <error.h>
+
+void* work_thread()
+{
+ int ret;
+ unsigned long i = 0;
+ frsh_vres_id_t vres_id;
+
+ printf("I am alive! \n");
+ while(i != 1E9) {
+ i++;
+
+ printf("I am alive, run %lu!\n", i);
+
+ ret = frsh_thread_get_vres_id(fosa_thread_self(), &vres_id);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_get_vres_id");
+
+ printf("\tvres retrieved from thread-ID: %p\n", vres_id);
+
+ ret = frsh_resource_get_vres_from_label("TEST_VRES",
+ FRSH_RT_PROCESSOR,
+ FRSH_CPU_ID_DEFAULT,
+ &vres_id);
+
+ if (ret) PERROR_AND_EXIT(ret, "frsh_get_vres_from_label");
+
+ printf("\ton retrived from label: %p\n", vres_id);
+ }
+
+ return EXIT_SUCCESS;
+}
+
+int main()
+{
+ frsh_vres_id_t vres;
+ frsh_thread_attr_t attr;
+ frsh_thread_id_t thread;
+ frsh_contract_t contract;
+ frsh_rel_time_t budget, period;
+ frsh_rel_time_t zero = fosa_msec_to_rel_time(0);
+ int ret;
+
+ if (frsh_init())
+ error(1, errno, "FRSH initialization failed\n");
+
+ /* Contract negotiation for CPU */
+ ret = frsh_contract_init(&contract);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ budget = fosa_msec_to_rel_time(10);
+ period = fosa_msec_to_rel_time(100);
+ ret = frsh_contract_set_basic_params(&contract,
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+
+ ret = frsh_contract_set_resource_and_label(&contract, FRSH_RT_PROCESSOR,
+ FRSH_CPU_ID_DEFAULT, "TEST_VRES");
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ ret = frsh_contract_set_reclamation_params(&contract,
+ &zero,
+ &budget,
+ &period,
+ FRSH_GR_CONTINUOUS,
+ NULL,
+ 0,
+ 0);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_reclamation_params");
+
+ ret = frsh_contract_negotiate(&contract, &vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+
+ printf("Aqcpu vres negotiated, vres-ID: %p\n", vres);
+ pthread_attr_init(&attr);
+ ret = frsh_thread_create_and_bind(vres, &thread, &attr,
+ work_thread, (void*) NULL);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_thread_create_and_bind");
+
+ pthread_join(thread.pthread_id, (void**) NULL);
+
+ ret = frsh_contract_cancel(vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_cancel");
+
+ printf("Test PASSED!\n");
+
+ return 0;
+}
+
--- /dev/null
+CONFIG_AQUOSA=y
+CFLAGS+=-save-temps
+CONFIG_FWP=n
+CONFIG_RESOURCE_DUMMY=n
+CONFIG_RESOURCE_ITEM=n
+CONFIG_RESOURCE_CLUSTER_TREE=n
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+default_CONFIG = CONFIG_CPUCG=x
+
+ifeq ($(CONFIG_CPUCG),y)
+SUBDIRS = lib mngr tests
+CFLAGS+= -Wall -Wextra -D_REENTRANT
+endif
+#include_HEADERS +=$(wildcard aquosa/qresmod/*.h)
+#include_HEADERS +=$(wildcard aquosa/rresmod/*.h)
--- /dev/null
+Prerequisites
+
+1. Download libcg library
+svn co https://libcg.svn.sourceforge.net/svnroot/libcg/trunk libcg
+
+2. Install libcg
+3. Mount cgroup filesystem
+ mkdir /dev/cgroup
+ mount -t cgroup -o cpu cgroup /dev/cgroup
+
+
+Usefull links:
+
+1. https://kerneltrap.org/mailarchive/linux-kernel/2008/6/18/2160914
+2. http://workouts.foss.in/2008/index.php/Low_level_plumbing_for_cgroups
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+shared_LIBRARIES = frshcpucg
+frshcpucg_SOURCES += cpucg_contract.c cpucg_fra.c
+include_HEADERS += cpucg_contract.h cpucg_res.h timespec_usec_ops.h
+frshcpucg_LIBS += cgroup
+#include_HEADERS +=$(wildcard aquosa/qresmod/*.h)
+#include_HEADERS +=$(wildcard aquosa/rresmod/*.h)
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRESCOR CPUCG (cpu control group) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including AQCPU header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+#include "cpucg_contract.h"
+
+int get_cpucg_params(fres_vres_t *vres, cpucg_params_t *params)
+{
+ fres_block_basic *basic;
+
+ /* get params from contract */
+ basic = fres_contract_get_basic(vres->new);
+
+ /* core contract parameters */
+ params->P = timespec_to_usec(basic->period);
+ /* non-core contract parameters */
+ /* right now, the same as minimum budget */
+ params->Q = timespec_to_usec(basic->budget);
+
+ return 0;
+}
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRESCOR CPUCG (cpu control group) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including AQCPU header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+#ifndef CPUCG_CONTRACT_H
+#include "timespec_usec_ops.h"
+#include <fra_generic.h>
+
+typedef
+struct cpucg_params_t {
+ long long P;
+ long long Q;
+} cpucg_params_t;
+
+int get_cpucg_params(fres_vres_t *vres, cpucg_params_t *params);
+
+#endif /* CPUCG_CONTRACT_H */
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRESCOR CPUCG (cpu control group) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including AQCPU header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <fra_generic.h>
+#include <cpucg_res.h>
+
+#include "cpucg_contract.h"
+#include <stdio.h>
+#include <libcgroup.h>
+
+UL_LOG_CUST(ulogd_fra_cpucg);
+ul_log_domain_t ulogd_fra_cpucg = {UL_LOGL_MSG, "fra_cpucg"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(fra_cpucg_logreg_domains, ulogd_fra_cpucg);
+
+static int cpucg_initialized = 0; /* initialization flag */
+
+#define CGNAME 20
+/*
+ * Permissions
+ */
+static uid_t tuid = 0;
+static gid_t tgid = 0;
+static uid_t cuid = 0;
+static gid_t cgid = 0;
+
+static int vres_inc = 0;
+
+/*
+ * Test whether Aquosa Cpu modue is initialized
+ */
+static inline int cpucg_is_initialized()
+{
+ return (cpucg_initialized == 1);
+}
+
+static inline char* cpucg_get_name(void)
+{
+ char* cgname = malloc(CGNAME);
+ snprintf(cgname, CGNAME, "%d", getpid() + vres_inc++);
+
+ return cgname;
+}
+
+static int cpucg_create_vres(fres_vres_t *vres, void *priv)
+{
+ cpucg_params_t cpu_params;
+ struct cgroup_controller *cpucntl;
+ struct cgroup* ccg;
+ long int period;
+ long int budget;
+ char* cgroup_name;
+ int ret;
+
+ /* get aqcpu params from contract */
+ get_cpucg_params(vres, &cpu_params);
+ period = cpu_params.P;
+ budget = cpu_params.Q;
+
+ /* create cpu vres */
+ cgroup_name = cpucg_get_name();
+ ccg = cgroup_new_cgroup(cgroup_name);
+ cgroup_set_uid_gid(ccg, tuid, tgid, cuid, cgid);
+ cpucntl = cgroup_add_controller(ccg, "cpu");
+ printf("To be Created CGCPU VRES(period=%ld us, budget=%ld us)\n",
+ period, budget);
+ cgroup_add_value_uint64(cpucntl, "cpu.rt_period_us", period);
+ cgroup_add_value_uint64(cpucntl, "cpu.rt_runtime_us", budget);
+
+ if ((ret = cgroup_create_cgroup(ccg, 1))) {
+ return ret;
+ }
+
+ printf("Created CGCPU VRES(period=%lld us, budget=%lld us)\n",
+ period, budget);
+ vres->priv = ccg;
+
+ return 0;
+}
+
+/*
+ * aqcpu_cancel_vres(), cancels vres
+ *
+ * The thread bound to the vres are unbound, and so, detached from their
+ * AQuoSA resource reservation servers and continue their execution according
+ * to the standard Linux scheduler policies.
+ *
+ */
+static int cpucg_cancel_vres(fres_vres_t *vres, void *priv)
+{
+ struct cgroup *cgroup;
+
+ if (vres->priv) {
+ errno = -EINVAL;
+ return -1;
+ }
+
+ cgroup = (struct cgroup*) vres->priv;
+ /* TODO: Solve migration
+ cgroup_delete_cgroup(cgroup, 1);*/
+ printf("Canceled CGCPU VRES\n");
+ cgroup_free(&cgroup);
+
+ return 0;
+}
+
+/* aqcpu_vres_change(), change some parameters of a vres
+ *
+ * In fact, since that AQuoSA call doesn't deal with _its_ Q_min (budget_min
+ * for in FRSH semantic) parameter all the renegotiation will be accepted but
+ * the new temporal behaviour is not guaranteed!
+ * Obviously this is a bug and should/will be corrected in AQuoSA as soon as
+ * possible.
+ *
+ */
+int cpucg_change_vres(fres_vres_t *vres, void *priv)
+{
+ struct cgroup *cgroup;
+ cpucg_params_t cpu_params;
+
+ if (vres->priv) {
+ errno = -EINVAL;
+ return -1;
+ }
+
+ cgroup = (struct cgroup*) vres->priv;
+
+ /* get aqcpu params from contract */
+ get_cpucg_params(vres, &cpu_params);
+
+ /* TODO:
+ * cgroup->controller[0]->values[0]->value = cpu_params.P;
+ cgroup->controller[0]->values[1]->value = cpu_params.Q; */
+
+ ul_logmsg("AQCPU VRES params changed(period=%lld us,"
+ "budget=%lld us)\n", cpu_params.P, cpu_params.Q);
+
+ return 0;
+}
+
+static int fra_CPU_bind_thread
+ (fres_vres_t *vres,
+ const fosa_thread_id_t thread)
+{
+ struct cgroup* cgroup = (struct cgroup*)vres->priv;
+ struct sched_param param;
+ int p, policy, ret;
+
+ /* if (!aqcpu_is_initialized) {
+ * return(FRSH_ERR_NOT_INITIALIZED);
+ * }
+ */
+
+ pthread_getschedparam(pthread_self(), &policy, ¶m);
+ p = param.sched_priority;
+ printf("policy = %d, priority = %d\n", policy, p);
+ if (p == 0) {
+ param.sched_priority = 1;
+ pthread_setschedparam(pthread_self(), SCHED_RR, ¶m);
+ pthread_getschedparam(pthread_self(), &policy, ¶m);
+ printf("changed policy = %d, changed priority = %d\n",
+ policy, param.sched_priority);
+ }
+
+ if (cgroup_attach_task_pid(cgroup, thread.linux_tid))
+ goto err;
+
+ return 0;
+err:
+ return -1;
+}
+
+static int fra_CPU_unbind_thread(const fosa_thread_id_t thread)
+{
+ int ret;
+
+ /* TODO: solve thread -> vres mapping */
+#if 0
+ char path[FILENAME_MAX];
+ struct cgroup* cgroup = (struct cgroup*)vres->priv;
+ FILE* taskf;
+
+ /* if (!aqcpu_is_initialized) {
+ * return(FRSH_ERR_NOT_INITIALIZED);
+ * }
+ */
+
+ if (!cg_build_path(cgroup->name, path, cgroup->controller[i]->name)){
+ return FRSH_ERR_INTERNAL_ERROR;
+ }
+
+ strcat(path, "tasks");
+ taskf = fopen(path, "w");
+ if (!taskf) {
+ return FRSH_ERR_INTERNAL_ERROR;
+ }
+ fclose(taskf);
+#endif
+
+ return 0;
+err:
+ return -1;
+}
+
+static int fra_CPU_get_usage
+ (const fres_vres_t *vres,
+ fosa_rel_time_t *spent)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+static int fra_CPU_get_job_usage
+ (const fres_vres_t *vres,
+ fosa_rel_time_t *spent)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+static int fra_CPU_get_remaining_budget
+ (const fres_vres_t *vres,
+ fosa_rel_time_t *budget)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+static
+int fra_CPU_set_spare_bandwidth(fres_vres_t *vres)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+static int fra_CPU_get_desired_budget
+ (fres_vres_t *vres,
+ frsh_rel_time_t *p_budget_out)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+static int fra_CPU_set_desired_budget
+ (fres_vres_t *vres,
+ fosa_rel_time_t *p_budget_in)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+static int fra_CPU_get_actual_budget
+ (fres_vres_t *vres,
+ fosa_rel_time_t *budget)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int cpucg_fra_activate(forb_orb orb)
+{
+ if (cpucg_is_initialized()) {
+ return FRSH_ERR_SYSTEM_ALREADY_INITIALIZED;
+ }
+
+ /* TODO: tets whether cpu controller is mounted */
+ //if (cgroup_init() || !cgroup_test_subsys_mounted("cpu")) {
+ if (cgroup_init()) {
+ return FRES_ERR_KERNEL_SUPPORT_MISSING;
+ }
+
+ cpucg_initialized = 1;
+ return 0;
+
+}
+
+static struct fres_allocator cpucg_allocator = {
+ .res_type = FRSH_RT_PROCESSOR,
+ .res_id = 0, /* CPU ID 0 */
+ .create_vres = cpucg_create_vres,
+ .cancel_vres = cpucg_cancel_vres,
+ .change_vres = cpucg_change_vres,
+
+ .bind_thread = fra_CPU_bind_thread,
+ .unbind_thread = fra_CPU_unbind_thread,
+
+ .vres_get_usage = fra_CPU_get_usage,
+ .vres_get_job_usage = fra_CPU_get_job_usage,
+ .vres_get_remaining_budget = fra_CPU_get_remaining_budget,
+
+ .set_spare_bandwidth = fra_CPU_set_spare_bandwidth,
+ .get_desired_budget = fra_CPU_get_desired_budget,
+ .set_desired_budget = fra_CPU_set_desired_budget,
+ .get_actual_budget = fra_CPU_get_actual_budget,
+
+ .activate_callback = cpucg_fra_activate,
+
+ .priv = NULL,
+};
+
+/*
+ * cpucg_fra_init()
+ *
+ * initialize FRSH for the calling process
+ *
+ * Must be called before starting using the framework.
+ * No FRSH call will be successful if this routine is not invoked
+ *
+ * Note that no BACKGROUND is created and negotiated and the caller thread
+ * is bound to no BACKGROUND vres, since no way is provided in order of
+ * specifying the contract label and get back the vres id!
+ *
+ * Note also that, since in this implementation the threads/processes with
+ * backgound contracts are left into the default Linux scheduler hands' and
+ * not attached to any AQuoSA server, while we're violating what D-AC2v1
+ * (pag. 14) says, we achieve exactly the same behaviour!!
+ *
+ * possible return values:
+ * FRSH_NO_ERROR
+ * FRSH_ERR_ALREADY_INITIALIZED
+ * FRSH_ERR_INTERNAL_ERROR (something, different from the previous case, gone wrong)
+ */
+int cpucg_fra_init(void)
+{
+ int rv;
+
+ cpucg_allocator.res_id = frsh_get_local_cpu_id();
+
+ if ((rv = fra_register(&cpucg_allocator))) {
+ return rv;
+ }
+
+ return 0;
+}
+
+int cpucg_fra_exit()
+{
+ return 0;
+}
--- /dev/null
+#ifndef CPUCG_RES_H
+#define CPUCG_RES_H
+
+#include <fres_vres.h>
+
+#include <forb.h>
+#include <fcb.h>
+
+int cpucg_fra_init(void);
+
+#endif /* CPUCG_RES_H */
+
--- /dev/null
+#ifndef __TIMESPEC_USEC_OPS_H__
+#define __TIMESPEC_USEC_OPS_H__
+
+/*
+ * timespec_usec_ops.h
+ *
+ * ...
+ */
+
+#include <time.h>
+
+#define equal_timespec(t1, t2) \
+ ( ( (t1)->tv_sec == (t2)->tv_sec ) && ( (t1)->tv_nsec == (t2)->tv_nsec ) )
+
+#define increment_timespec(t) \
+do { \
+ (t)->tv_nsec ++; \
+ if ((t)->tv_nsec >= 1000000000UL) { \
+ (t)->tv_sec ++; \
+ (t)->tv_nsec -= 1000000000UL; \
+ } \
+} while(0)
+
+#define decrement_timespec(t) \
+do { \
+ if ( (t)->tv_nsec == 0) { \
+ (t)->tv_nsec = 1000000000UL; \
+ (t)->tv_sec --; \
+ } \
+ else \
+ (t)->tv_nsec --; \
+} while(0)
+
+#define sum_timespec(t1, t2, ts) \
+do { \
+ (ts)->tv_sec = (t1)->tv_sec + (t2)->tv_sec; \
+ (ts)->tv_nsec = (t1)->tv_nsec + (t2)->tv_nsec; \
+ while ( (ts)->tv_nsec >= 1000000000UL) { \
+ (ts)->tv_sec ++; \
+ (ts)->tv_nsec -= 1000000000UL; \
+ } \
+} while(0)
+
+#define sub_timespec(t1, t2, ts) \
+do { \
+ if ( (t2)->tv_sec < (t1)->tv_sec || \
+ ((t2)->tv_sec == (t1)->tv_nsec && (t2)->tv_nsec < (t1)->tv_nsec) ) { \
+ (ts)->tv_sec = (t1)->tv_sec - (t2)->tv_sec; \
+ (ts)->tv_nsec = (t1)->tv_nsec - (t2)->tv_sec; \
+ while ( (ts)->tv_nsec < 0) { \
+ (ts)->tv_sec --; \
+ (ts)->tv_nsec = (ts)->tv_nsec + 1000000000UL; \
+ } \
+ } else { \
+ (ts)->tv_sec = 0UL; \
+ (ts)->tv_nsec = 0UL; \
+ } \
+} while(0)
+
+#define zero_timespec(t) \
+do { \
+ (t)->tv_sec = 0; \
+ (t)->tv_nsec = 0; \
+} while(0)
+
+#define is_zero_timespec(t) \
+( (t)->tv_sec == 0 && (t)->tv_nsec == 0 )
+
+#endif /* __TIMESPEC_USEC_OPS_H__ */
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+bin_PROGRAMS = frm_cgcpu
+frm_cgcpu_SOURCES = frm_cgcpu.c
+frm_cgcpu_LIBS = frm forb contract fosa rt ulut fcb_client
+lib_LOADLIBES+= frsh
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRESCOR CPUCG (cpu control group) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file cpucg_mngr.c
+ * @author Martin Molnar <molnam1@fel.cvut.cz>
+ * @date Wed Feb 18 16:24:43 2009
+ *
+ * @brief
+ *
+ *
+ */
+
+#include <frm_generic.h>
+#include <forb.h>
+#include <error.h>
+#include <errno.h>
+#include <getopt.h>
+#include <fres_sa_scenario.h>
+#include <stdbool.h>
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <stdio.h>
+#include <frsh_core.h>
+
+UL_LOG_CUST(ulogd_frm_cpucg);
+ul_log_domain_t ulogd_frm_cpucg = {UL_LOGL_DEB, "frm_cpucg"};
+
+/**
+ * root cgroup`s period
+ */
+static unsigned int global_period_us;
+/**
+ * root cgroup`s runtime
+ */
+static unsigned int global_runtime_us;
+
+static int cpucg_admtest(struct fres_sa_scenario *scenario, void *priv,
+ bool *schedulable)
+{
+ struct fres_sa_contract *c;
+ long int period, budget;
+ long int sum_utilization = 0;
+
+ fres_sa_scenario_for_each_no_cancel_contract(scenario, c) {
+ fres_block_basic *basic;
+ char id[40];
+ fres_contract_id_to_string(id, &c->contract->id, sizeof(id));
+ basic = fres_contract_get_basic(c->contract);
+
+ period = fosa_rel_time_to_msec(basic->period);
+ budget = fosa_rel_time_to_msec(basic->budget);
+ printf("processing : id=%s, period=%ld ms, budget=%ld ms\n",
+ id,period, budget);
+ //ul_logdeb("processing : id=%s, period=%ld ms, budget=%ld ms\n",
+ // id,period, budget);
+
+ sum_utilization+= budget*100/period;
+ }
+ printf("sum_ut= %ld global_ut=%ld \n", sum_utilization, ((long)global_runtime_us*100/global_period_us));
+ *schedulable = (sum_utilization < (global_runtime_us*100/global_period_us));
+ printf("=> %s\n", (*schedulable)?"schedulable":"not schedulable");
+
+ return 0;
+}
+
+static struct fres_res_manager frm = {
+ .res_type = FRSH_RT_PROCESSOR,
+ .res_id = 0,
+ .name = "cgroup",
+ .admission_test = cpucg_admtest,
+ .priv = NULL
+};
+
+static struct option long_opts[] = {
+ { "loglevel", 1, 0, 'l' },
+ { 0, 0, 0, 0}
+};
+
+static void
+usage(void)
+{
+ printf("usage: frm_aqcpu [ options ]\n");
+ printf(" -l, --loglevel <number>|<domain>=<number>,...\n");
+}
+
+int main(int argc, char *argv[])
+{
+ forb_orb orb;
+ FILE* fd;
+ int ret;
+ int opt;
+ forb_init_attr_t attr = { .orb_id = "org.frescor.frm.cgcpu" };
+ bool opt_daemon = false;
+ char *opt_pidfile = NULL;
+
+ ul_logreg_domain(&ulogd_frm_cpucg);
+
+ while ((opt = getopt_long(argc, argv, "d::hl:", &long_opts[0], NULL)) != EOF) {
+ switch (opt) {
+ case 'd':
+ opt_daemon = true;
+ opt_pidfile = optarg;
+ break;
+ case 'l':
+ ul_log_domain_arg2levels(optarg);
+ break;
+ case 'h':
+ /*default:*/
+ usage();
+ exit(opt == 'h' ? 0 : 1);
+ }
+ }
+
+ if (opt_daemon)
+ forb_daemon_prepare(opt_pidfile);
+
+ orb = forb_init(&argc, &argv, &attr);
+ if (!orb) error(1, errno, "forb_init");
+
+ if (!(fd = fopen("/proc/sys/kernel/sched_rt_period_us", "r"))) {
+ error(1, errno, "frm_generic_run");
+ }
+ ret = fscanf(fd,"%d", &global_period_us);
+ printf("sched_rt_period_us= %d\n", global_period_us);
+ if (ret == 0 || ret == EOF) {
+ error(1, errno, "frm_generic_run");
+ }
+ fclose(fd);
+
+ if (!(fd = fopen("/proc/sys/kernel/sched_rt_runtime_us", "r"))) {
+ error(1, errno, "frm_generic_run");
+ }
+ ret = fscanf(fd,"%d", &global_runtime_us);
+ printf("sched_rt_runtime_us= %d\n", global_runtime_us);
+ if (ret == 0 || ret == EOF) {
+ error(1, errno, "frm_generic_run");
+ }
+ fclose(fd);
+
+ frm.res_id = frsh_get_local_cpu_id();
+ ret = frm_register_and_run(orb, &frm);
+ if (ret != 0) {
+ error(1, errno, "frm_generic_run");
+ }
+
+ return 0;
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+test_PROGRAMS = cpucgtest
+cpucgtest_SOURCES = cpucgtest.c
+#aqcpumngr_LIBS = frm forb contract fosa rt ulut fcb_client
+lib_LOADLIBES += pthread rt frshcpucg frsh
--- /dev/null
+CONFIG_AQUOSA=y
+CFLAGS+=-save-temps
+CONFIG_FWP=n
+CONFIG_RESOURCE_DUMMY=n
+CONFIG_RESOURCE_ITEM=n
+CONFIG_RESOURCE_CLUSTER_TREE=n
+
--- /dev/null
+#include <frsh.h>
+#include <cpucg_res.h>
+#include <error.h>
+
+void* work_thread()
+{
+ int i;
+
+ printf("I am alive! \n");
+ while(1) {
+ printf("I am alive! \n");
+ i++;
+
+ }
+
+}
+
+int main()
+{
+ frsh_vres_id_t vres;
+ frsh_thread_attr_t attr;
+ frsh_thread_id_t thread;
+ frsh_contract_t contract;
+ frsh_rel_time_t budget, period;
+ int ret;
+
+ if (frsh_init()) {
+ error(1, 0, "FRSH initialization failed\n");
+
+ }
+
+ /* Contract negotiation for CPU */
+ ret = frsh_contract_init(&contract);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ budget = fosa_msec_to_rel_time(50);
+ period = fosa_msec_to_rel_time(100);
+ ret = frsh_contract_set_basic_params(&contract,
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+ ret = frsh_contract_set_resource_and_label(&contract, FRSH_RT_PROCESSOR,
+ 0,"aqcpu_cont1");
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ ret = frsh_contract_negotiate(&contract, &vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+
+ printf("Aqcpu vres negotiated\n");
+ pthread_attr_init(&attr);
+ ret = frsh_thread_create_and_bind(vres, &thread, &attr,
+ work_thread, (void*) NULL);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_thread_create_and_bind");
+
+ pthread_join(thread.pthread_id, (void**) NULL);
+ printf("Test PASSED!\n");
+
+ return 0;
+}
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+default_CONFIG += CONFIG_DISKBFQ=y
+default_CONFIG += CONFIG_DISKBFQ_SCHED_NAME="bfq"
+default_CONFIG += CONFIG_DISKBFQ_QUEUE_PATH="/sys/class/block/%s/queue/"
+default_CONFIG += CONFIG_DISKBFQ_SCHED_PATH="scheduler"
+default_CONFIG += CONFIG_DISKBFQ_BUDGET_PATH="iosched/budget"
+
+ifeq ($(CONFIG_DISKBFQ),y)
+SUBDIRS = lib mngr #tests
+CFLAGS+= -Wall -Wextra -D_REENTRANT
+endif
--- /dev/null
+Prerequisites
+
+TODO: write down something about BFQ.
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+shared_LIBRARIES = frshdiskbfq
+frshdiskbfq_SOURCES += diskbfq_contract.c diskbfq_fra.c disk_block.c
+include_HEADERS += diskbfq_contract.h diskbfq_res.h res_disk.h
+include_GEN_HEADERS = res_disk_idl.h
+frshdiskbfq_LIBS += fra
+frshdiskbfq_CLIENT_IDL = res_disk_idl.idl
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file disk_block.c
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ *
+ * @brief Description contract blocks specific to dummy resource
+ *
+ *
+ */
+#include <res_disk.h>
+#include <fres_container.h>
+
+static const struct fres_block_desc disk_block_desc = {
+ .name = "disk_sched",
+ .size = sizeof(fres_block_disk_sched),
+ .serialize = (fres_block_serialize_fnc_t*)fres_block_disk_sched_serialize,
+ .deserialize = (fres_block_deserialize_fnc_t*)fres_block_disk_sched_deserialize,
+ .duplicate = fres_block_duplicate_default
+};
+
+int fres_block_register_disk_sched()
+{
+ return fres_block_register(FRES_BLOCK_DISK_SCHED,
+ &disk_block_desc);
+}
+
--- /dev/null
+#include "diskbfq_contract.h"
+
+int get_diskbfq_params(fres_vres_t *vres, diskbfq_params_t *params)
+{
+ fres_block_basic *basic;
+
+ /* get params from contract */
+ basic = fres_contract_get_basic(vres->new);
+
+ params->P = timespec_to_usec(basic->period);
+ params->Q = timespec_to_usec(basic->budget);
+
+ return 0;
+}
+
--- /dev/null
+#ifndef DISKBFQ_CONTRACT_H
+#include <fra_generic.h>
+
+typedef
+struct diskbfq_params_t {
+ long long P;
+ long long Q;
+} diskbfq_params_t;
+
+int get_diskbfq_params(fres_vres_t *vres, diskbfq_params_t *params);
+
+#endif /* DISKBFQ_CONTRACT_H */
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRESCOR CPUCG (cpu control group) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including AQCPU header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file diskbfq_fra.c
+ * @author Dario Faggiolir <faggioli@gandalf.sssup.it>
+ *
+ * @brief
+ *
+ *
+ */
+
+#include <stdio.h>
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <fra_generic.h>
+#include "diskbfq_contract.h"
+#include "res_disk.h"
+
+UL_LOG_CUST(ulogd_fra_diskbfq);
+ul_log_domain_t ulogd_fra_diskbfq = {UL_LOGL_MSG, "fra_diskbfq"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(fra_diskbfq_logreg_domains, ulogd_fra_diskbfq);
+
+static int diskbfq_initialized = 0; /* initialization flag */
+
+/*
+ * Test whether BFQ disk scheduler modue is initialized
+ */
+static inline int diskbfq_is_initialized()
+{
+ return (diskbfq_initialized == 1);
+}
+
+static int diskbfq_create_vres(fres_vres_t *vres, void *priv)
+{
+ fres_block_basic *basic;
+ fres_block_disk_sched *disk_sched;
+ char id[40];
+
+ /*
+ * for disk, reserving the bandwidth does not
+ * make any sense.
+ *
+ * All that we must do is prepare the
+ * vres storing the I/O priority the thread that
+ * will be bound to it will acquire.
+ */
+ fres_contract_id_to_string(id, &vres->id, sizeof(id));
+ basic = fres_contract_get_basic(vres->new);
+ disk_sched = fres_contract_get_disk_sched(vres->new);
+ if (!(vres->priv = malloc(sizeof(int))))
+ return -1;
+
+ memcpy(vres->priv, &disk_sched->ioprio, sizeof(int));
+ ul_logmsg("Created BFQ VRES (ioprio=%d budget=%ld ms, period=%ld ms)\n",
+ disk_sched->ioprio,
+ fosa_rel_time_to_msec(basic->budget),
+ fosa_rel_time_to_msec(basic->period));
+
+ return 0;
+}
+
+static int diskbfq_cancel_vres(fres_vres_t *vres, void *priv)
+{
+ if (!vres->priv) {
+ errno = -EINVAL;
+ return -1;
+ }
+
+ /*
+ * As before, it is not possible to "free" disk
+ * bandwidth.
+ *
+ * All that we do is free vres memory, the bandwidth
+ * is automatically released when the thread is unbound
+ * from the vres itself.
+ */
+ ul_logmsg("Canceled DISK VRES (ioprio=%d)\n", *((int*)vres->priv));
+ free(vres->priv);
+
+ return 0;
+}
+
+static
+int diskbfq_change_vres(fres_vres_t *vres, void *priv)
+{
+ fres_block_disk_sched *disk_sched;
+
+ if (!vres->priv) {
+ errno = -EINVAL;
+ return -1;
+ }
+
+ disk_sched = fres_contract_get_disk_sched(vres->new);
+ ul_logmsg("Changed BFQ VRES from ioprio=%d to ioprio=%d\n",
+ *((int*)vres->priv), (int) disk_sched->ioprio);
+ memcpy(vres->priv, &disk_sched->ioprio, sizeof(int));
+
+ return 0;
+}
+
+int diskbfq_fra_exit()
+{
+ return 0;
+}
+
+static
+int fra_DISK_bind_thread
+ (fres_vres_t *vres,
+ const fosa_thread_id_t thread)
+{
+ fres_block_basic *b;
+ int ret, ioprio = *((int*)vres->priv);
+ struct fres_contract *contract = vres->allocated;
+
+ b = fres_contract_get_basic(contract);
+ if (b->contract_type == FRSH_CT_REGULAR)
+ /* Hack: frm_diskbfq calculates wrong ioprio (-1) - override it here */
+ ioprio = IOPRIO_CLASS_BE << IOPRIO_CLASS_SHIFT | 0;
+ else if (b->contract_type == FRSH_CT_BACKGROUND)
+ ioprio |= IOPRIO_CLASS_IDLE << IOPRIO_CLASS_SHIFT;
+ else
+ goto err;
+
+ /* ret = ioprio_set(IOPRIO_WHO_PROCESS, gettid(), ioprio); */
+ ret = syscall(__NR_ioprio_set, IOPRIO_WHO_PROCESS,
+ syscall(__NR_gettid), ioprio);
+ if (ret) goto err;
+
+ return 0;
+err:
+ ul_logerr("ioprio(): %s\n", strerror(errno));
+ return -1;
+}
+
+static
+int fra_DISK_unbind_thread(const fosa_thread_id_t thread)
+{
+ int ret;
+
+ /* ret = ioprio_set(IOPRIO_WHO_PROCESS, gettid(), IOPRIO_DEFAULT); */
+ ret = syscall(__NR_ioprio_set, IOPRIO_WHO_PROCESS,
+ syscall(__NR_gettid), IOPRIO_PRIO_DEFAULT);
+ if (ret)
+ return -1;
+
+ return 0;
+}
+
+static
+int fra_DISK_get_usage
+ (const fres_vres_t *vres,
+ fosa_rel_time_t *spent)
+{
+ return -1;
+}
+
+static
+int fra_DISK_get_job_usage
+ (const fres_vres_t *vres,
+ fosa_rel_time_t *spent)
+{
+ return -1;
+}
+
+static
+int fra_DISK_get_remaining_budget
+ (const fres_vres_t *vres,
+ fosa_rel_time_t *budget)
+{
+ return -1;
+}
+
+static
+int fra_DISK_set_spare_bandwidth
+ (fres_vres_t *vres)
+{
+ return -1;
+}
+
+static
+int fra_DISK_get_desired_budget
+ (fres_vres_t *vres,
+ frsh_rel_time_t *p_budget_out)
+{
+ return -1;
+}
+
+static
+int fra_DISK_set_desired_budget
+ (fres_vres_t *vres,
+ fosa_rel_time_t *p_budget_in)
+{
+ return -1;
+}
+
+static
+int fra_DISK_get_actual_budget
+ (fres_vres_t *vres,
+ fosa_rel_time_t *budget)
+{
+ return -1;
+}
+
+static struct fres_allocator diskbfq_allocator = {
+ .res_type = FRSH_RT_DISK,
+ .res_id = 0, /* DISK ID 0 */
+ .create_vres = diskbfq_create_vres,
+ .cancel_vres = diskbfq_cancel_vres,
+ .change_vres = diskbfq_change_vres,
+
+ .bind_thread = fra_DISK_bind_thread,
+ .unbind_thread = fra_DISK_unbind_thread,
+
+ .vres_get_usage = fra_DISK_get_usage,
+ .vres_get_job_usage = fra_DISK_get_job_usage,
+ .vres_get_remaining_budget = fra_DISK_get_remaining_budget,
+
+ .set_spare_bandwidth = fra_DISK_set_spare_bandwidth,
+ .get_desired_budget = fra_DISK_get_desired_budget,
+ .set_desired_budget = fra_DISK_set_desired_budget,
+ .get_actual_budget = fra_DISK_get_actual_budget,
+
+ .priv = NULL
+};
+
+/*
+ * diskbfq_fra_init()
+ *
+ * initialize FRSH for the calling process
+ *
+ * Must be called before starting using the framework.
+ * No FRSH call will be successful if this routine is not invoked
+ *
+ * Note that no BACKGROUND is created and negotiated and the caller thread
+ * is bound to no BACKGROUND vres, since no way is provided in order of
+ * specifying the contract label and get back the vres id!
+ *
+ * Note also that, since in this implementation the threads/processes with
+ * backgound contracts are left into the default Linux scheduler hands' and
+ * not attached to any AQuoSA server, while we're violating what D-AC2v1
+ * (pag. 14) says, we achieve exactly the same behaviour!!
+ *
+ * possible return values:
+ * FRSH_NO_ERROR
+ * FRSH_ERR_ALREADY_INITIALIZED
+ * FRSH_ERR_INTERNAL_ERROR (something, different from the previous case, gone wrong)
+ */
+int diskbfq_fra_init(void)
+{
+ if (diskbfq_is_initialized()) {
+ return -1;
+ }
+
+ fres_block_register_disk_sched();
+ if (fra_register(&diskbfq_allocator)) {
+ return -1;
+ }
+
+ diskbfq_initialized = 1;
+ return 0;
+}
+
--- /dev/null
+#ifndef DISKBFQ_RES_H
+#define DISKBFQ_RES_H
+
+#include <forb.h>
+#include <fcb.h>
+#include <frsh_core.h>
+
+int diskbfq_fra_init(void);
+
+int fra_DISK_bind_thread(fres_vres_t *vres, fosa_thread_id_t thread);
+int fra_DISK_unbind_thread(fosa_thread_id_t thread);
+
+int fra_DISK_get_usage(const fres_vres_t *vres,
+ fosa_rel_time_t *spent);
+int fra_DISK_get_job_usage(const fres_vres_t *vres,
+ fosa_rel_time_t *spent);
+int fra_DISK_get_remaining_budget(const fres_vres_t *vres,
+ fosa_rel_time_t *budget);
+
+int fra_DISK_set_spare_bandwidth(fres_vres_t *vres);
+
+int fra_DISK_get_desired_budget(fres_vres_t *vres,
+ frsh_rel_time_t *p_budget_out);
+int fra_DISK_set_desired_budget(fres_vres_t *vres,
+ fosa_rel_time_t *p_budget_in);
+int fra_DISK_get_actual_budget(fres_vres_t *vres,
+ fosa_rel_time_t *budget);
+
+#endif /* DISKBFQ_RES_H */
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file res_disk.h
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ *
+ * @brief Disk resource declarations
+ *
+ *
+ */
+
+#ifndef RES_DISK_H
+#define RES_DISK_H
+
+#include <unistd.h>
+#include <linux/unistd.h>
+#include <sys/syscall.h>
+#include <asm/unistd.h>
+
+#include <forb.h>
+#include <fcb.h>
+#include <res_disk_idl.h>
+#include <fres_contract.h>
+#include <fres_container.h>
+
+enum {
+ IOPRIO_CLASS_NONE,
+ IOPRIO_CLASS_RT,
+ IOPRIO_CLASS_BE,
+ IOPRIO_CLASS_IDLE,
+};
+
+enum {
+ IOPRIO_WHO_PROCESS = 1,
+ IOPRIO_WHO_PGRP,
+ IOPRIO_WHO_USER,
+};
+
+#define IOPRIO_CLASS_SHIFT 13
+/**
+ * @FIXME:
+ * Why all these can't be config parameters?
+ **/
+//#define SYSFS_BFQ_NAME CONFIG_DISKBFQ_SCHED_NAME /* default = "bfq" */
+//#define SYSFS_BFQ_BASIC_PATH CONFIG_DISKBFQ_QUEUE_PATH /* default = "/sys/class/block/%s/queue" */
+//#define SYSFS_BFQ_SCHED_PATH CONFIG_DISKBFQ_QUEUE_PATH CONFIG_DISKBFQ_SCHED_PATH
+//#define SYSFS_BFQ_BUDGET_PATH CONFIG_DISKBFQ_QUEUE_PATH CONFIG_DISKBFQ_BUDGET_PATH /* default = CONFIG_DISKBFQ_QUEUE_PATH "iosched/budget" */
+#define SYSFS_BFQ_NAME "bfq"
+#define SYSFS_BFQ_BASIC_PATH "/sys/block/%s/queue/"
+#define SYSFS_BFQ_SCHED_PATH SYSFS_BFQ_BASIC_PATH "scheduler"
+#define SYSFS_BFQ_BUDGET_PATH SYSFS_BFQ_BASIC_PATH "iosched/max_budget"
+
+#define DISKBFQ_WEIGHT_MAX 100
+
+#define IOPRIO_PRIO_DEFAULT 4
+#define IOPRIO_CLASS_DEFAULT IOPRIO_CLASS_BE
+#define DISKBFQ_IOPRIO_DEFAULT \
+ (IOPRIO_PRIO_DEFAULT || (IOPRIO_CLASS_DEFAULT << IOPRIO_CLASS_SHIFT))
+
+int fra_disk_init(void);
+int fres_block_register_disk_sched(void);
+
+/* Define fres_container_(add|get|del)_disk_sched. */
+FRES_CONTAINER_ACCESSOR(DISK_SCHED, disk_sched);
+
+/* Define fres_contract_(add|get|del)_disk_sched. */
+FRES_CONTRACT_ACCESSOR(disk_sched);
+
+#endif
+
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------------------- //
+// Copyright (C) 2006 - 2008 FRESCOR consortium partners: //
+// //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// Scuola Superiore Sant'Anna, ITALY //
+// Kaiserslautern University, GERMANY //
+// Univ. Politécnica Valencia, SPAIN //
+// Czech Technical University in Prague, CZECH REPUBLIC //
+// ENEA SWEDEN //
+// Thales Communication S.A. FRANCE //
+// Visual Tools S.A. SPAIN //
+// Rapita Systems Ltd UK //
+// Evidence ITALY //
+// //
+// See http://www.frescor.org for a link to partners' websites //
+// //
+// FRESCOR project (FP6/2005/IST/5-034026) is funded //
+// in part by the European Union Sixth Framework Programme //
+// The European Union is not liable of any use that may be //
+// made of this code. //
+// //
+// //
+// based on previous work (FSF) done in the FIRST project //
+// //
+// Copyright (C) 2005 Mälardalen University, SWEDEN //
+// Scuola Superiore S.Anna, ITALY //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// //
+// FSF API web pages: http:marte.unican.es/fsf/docs //
+// http:shark.sssup.it/contrib/first/docs/ //
+// //
+// This file is part of FORB (Frescor Object Request Broker) //
+// //
+// FORB is free software; you can redistribute it and/or modify it //
+// under terms of the GNU General Public License as published by the //
+// Free Software Foundation; either version 2, or (at your option) any //
+// later version. FORB is distributed in the hope that it will be //
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty //
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
+// General Public License for more details. You should have received a //
+// copy of the GNU General Public License along with FORB; see file //
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, //
+// Cambridge, MA 02139, USA. //
+// //
+// As a special exception, including FORB header files in a file, //
+// instantiating FORB generics or templates, or linking other files //
+// with FORB objects to produce an executable application, does not //
+// by itself cause the resulting executable application to be covered //
+// by the GNU General Public License. This exception does not //
+// however invalidate any other reasons why the executable file might be //
+// covered by the GNU Public License. //
+////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @file res_disk_idl.idl
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ *
+ * @brief Contract data block for disk resource
+ *
+ *
+ */
+module fres {
+ module block {
+ struct disk_sched {
+ long weight;
+ long ioprio;
+ };
+ };
+};
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+LFS:=$(shell getconf LFS_CFLAGS)
+CFLAGS += $(LFS)
+
+bin_PROGRAMS = frm_diskbfq
+frm_diskbfq_SOURCES = diskbfq_mngr.c diskbfq_th.c
+frm_diskbfq_LIBS = frm forb contract fosa m rt ulut fcb_client frshdiskbfq
+
+include_HEADERS = diskbfq_th.h
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRESCOR BFQ disk bandwidth reservation */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#include <frm_generic.h>
+#include <forb.h>
+#include <error.h>
+#include <errno.h>
+#include <fres_sa_scenario.h>
+#include <stdbool.h>
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "res_disk.h"
+#include "diskbfq_th.h"
+
+UL_LOG_CUST(ulogd_frm_diskbfq);
+ul_log_domain_t ulogd_frm_diskbfq = {UL_LOGL_DEB, "frm_diskbfq"};
+
+struct disk_data {
+ double throughput;
+ int budget;
+};
+
+static int bandwidth_to_weight(struct disk_data *data,
+ unsigned long budget,
+ unsigned long period)
+{
+ float th, weight;
+ //unsigned long q_i, p_i;
+ int b, w_i;
+
+ th = data->throughput / 10E9;
+ b = data->budget;
+
+ /* Convert to nanoseconds! */
+ //q_i *= 1000;
+ //p_i *= 1000;
+
+ if (period < b / th)
+ return -1;
+
+ weight = (DISKBFQ_WEIGHT_MAX * budget) / (period - (b / th));
+ w_i = floor(weight);
+ if (weight != w_i)
+ w_i++;
+
+ return w_i;
+}
+
+static int weight_to_ioprio(int weight)
+{
+ if (weight >= 100)
+ return 0;
+ if (weight > 14)
+ return 1;
+ if (weight == -1)
+ return -1;
+
+ return 8 - 1 - (weight / 2);
+}
+
+static int diskbfq_admtest(struct fres_sa_scenario *scenario,
+ void *priv,
+ bool *schedulable)
+{
+ struct fres_sa_contract *c;
+ long int period, budget;
+ long int sum_weight = 0;
+ struct disk_data *data = priv;
+
+ fres_sa_scenario_for_each_no_cancel_contract(scenario, c) {
+ fres_block_basic *basic;
+ fres_block_resource *resource;
+ fres_block_disk_sched *disk_sched;
+ char id[40];
+
+ fres_contract_id_to_string(id, &c->contract->id, sizeof(id));
+ basic = fres_contract_get_basic(c->contract);
+ resource = fres_contract_get_resource(c->contract);
+
+ period = fosa_rel_time_to_nsec(basic->period);
+ budget = fosa_rel_time_to_nsec(basic->budget);
+ ul_logmsg("processing: id=%s, period=%ld us, budget=%ld us\n",
+ id, period/1000, budget/1000);
+
+ if (c->contract == c->new) {
+ int ret;
+
+ /* Calc weight and IO prio for the new contracts */
+ disk_sched = malloc(sizeof(*disk_sched));
+ if (!disk_sched) return -1;
+
+ disk_sched->weight = bandwidth_to_weight(data,
+ budget,
+ period);
+ disk_sched->ioprio =
+ weight_to_ioprio(disk_sched->weight);
+ ret = fres_contract_add_disk_sched(c->contract,
+ disk_sched);
+ if (ret) {
+ ul_logerr("Cannot add disk_sched block\n");
+ free(disk_sched);
+ return -1;
+ }
+ } else {
+ disk_sched = fres_contract_get_disk_sched(c->contract);
+ if (!disk_sched) {
+ ul_logerr("disk_sched is not present\n");
+ return -1;
+ }
+ }
+ sum_weight += disk_sched->weight;
+ }
+
+ ul_logmsg("sum_weight=%ld, max_weight=%d\n",
+ sum_weight,
+ DISKBFQ_WEIGHT_MAX);
+ *schedulable = sum_weight < DISKBFQ_WEIGHT_MAX;
+ ul_logmsg("=> %s\n", (*schedulable) ? "schedulable" : "not schedulable");
+
+ return 0;
+}
+
+struct disk_data disk;
+
+static struct fres_res_manager frm = {
+ .res_type = FRSH_RT_DISK,
+ .res_id = 0,
+ .name = "Disk BFQ",
+ .admission_test = diskbfq_admtest,
+ .priv = &disk
+};
+
+int main(int argc, char *argv[])
+{
+ forb_init_attr_t attr = { .orb_id = "org.frescor.frm.diskbfq" };
+ forb_orb orb;
+ FILE* fd;
+ int readers = 4;
+ char disk_dev[40] = {0}, *disk_name = disk_dev;
+ char path[128], scheduler[128];
+ int i, opt, ret;
+
+ ul_logreg_domain(&ulogd_frm_diskbfq);
+
+ if (argc < 3) {
+err_usage:
+ fprintf(stderr, "Usage:\n %s "
+ "-i disk_id -d disk_device [-n readers]\n",
+ argv[0]);
+ error(1, EINVAL, "frm_diskbfq");
+ }
+
+ while ((opt = getopt(argc, argv, "i:d:n:")) != -1) {
+ switch (opt) {
+ case 'i':
+ frm.res_id = atoi(optarg);
+ break;
+ case 'd':
+ strncpy(disk_dev,
+ optarg, sizeof(disk_dev));
+
+ for (i = strlen(disk_dev) - 1; i >= 0; i--) {
+ if (disk_dev[i] == '/') {
+ disk_name = disk_dev + i + 1;
+ break;
+ }
+ }
+ break;
+ case 'n':
+ readers = atoi(optarg);
+ break;
+ default:
+ goto err_usage;
+ }
+ }
+
+ if (!*disk_name)
+ error(1, 0, "Disk device not specified");
+
+ orb = forb_init(&argc, &argv, &attr);
+ if (!orb) error(1, errno, "forb_init");
+
+ /*
+ * Check if BFQ I/O scheduler is available
+ * in the system.
+ */
+ snprintf(path, 128,
+ SYSFS_BFQ_SCHED_PATH,
+ disk_name);
+ if (!(fd = fopen(path, "r+")))
+ error(1, errno, "fopen(%s)", path);
+
+ ret = fscanf(fd, "%128[^\n]", scheduler);
+ if (ret == 0 || ret == EOF)
+ error(1, errno, "fscanf: %s", path);
+ if (!strstr(scheduler, SYSFS_BFQ_NAME))
+ error(1, errno, "bfq not available in kernel");
+
+ /**
+ * Now check if BFQ is the default I/O scheduler
+ * for the specific disk and set it to so if not.
+ **/
+ else if (!strstr(scheduler, "[" SYSFS_BFQ_NAME "]")) {
+ rewind(fd);
+ ret = fprintf(fd, SYSFS_BFQ_NAME);
+ if (ret && ret != EOF)
+ ret = fflush(fd);
+ if (ret == 0 || ret == EOF)
+ error(1, errno, "cannot activate bfq scheduler");
+ }
+ fclose(fd);
+
+ snprintf(path, sizeof(path),
+ SYSFS_BFQ_BUDGET_PATH,
+ disk_name);
+ if (!(fd = fopen(path, "r+")))
+ error(1, errno, "fopen(%s)", path);
+
+ ret = fprintf(fd, "256");
+ if (ret == 0)
+ error(1, errno, "fprintf: %s", path);
+
+ rewind(fd);
+ ret = fscanf(fd, "%d", &disk.budget);
+ if (ret == 0 || ret == EOF)
+ error(1, errno, "fscanf: %s", path);
+ fclose(fd);
+
+ /**
+ * Estimate the disk throughput in order to achieve
+ * effective weight assignement during runtime.
+ **/
+ printf("Throughput estimation...\n");
+ disk.throughput = estimate_throughput(disk_dev, readers);
+ if (disk.throughput < 0.0)
+ error(1, errno, "throughput estimation error");
+
+ fprintf(stdout, "disk name: %s\n"
+ "scheduler: %s\n"
+ "disk aggregate throughput: %f KiB/s\n"
+ "scheduling budget: %d\n",
+ disk_name, SYSFS_BFQ_NAME, disk.throughput, disk.budget);
+
+ /* Register fres_block_disk_sched to contract handling
+ * functions */
+ fres_block_register_disk_sched();
+
+ ret = frm_register_and_run(orb, &frm);
+ if (ret) error(1, errno, "frm_register_and_run");
+
+ return 0;
+}
+
--- /dev/null
+/*
+ * The only function of interest is:
+ * double estimate_throughput(char *device, int streamers);
+ * @device: the device we want to test.
+ * @streamers: the number of sequential readers we're interested in.
+ */
+
+#include <diskbfq_th.h>
+
+/* given a device name, return its size in sectors */
+static int64_t read_size(char *device)
+{
+ int count, size, i;
+ int64_t rval;
+ char *path, *devname = device;
+ FILE *fp;
+
+ for (i = strlen(device) - 1; i >= 0; i--) {
+ if (device[i] == '/') {
+ devname = device + i + 1;
+ break;
+ }
+ }
+
+ size = sizeof(SYSFS_BASE) + strlen(devname) + sizeof("/size");
+ path = calloc(1, size);
+ if (!path)
+ return -ENOMEM;
+
+ snprintf(path, size, SYSFS_BASE "%s/size", devname);
+ fp = fopen(path, "r");
+ if (!fp) {
+ rval = -ENODEV;
+ goto err;
+ }
+
+ count = fscanf(fp, "%llu", (unsigned long long*) &rval);
+ if (count != 1)
+ rval = -EIO;
+
+ fclose(fp);
+err:
+ free(path);
+ return rval;
+}
+
+/* reader: reads from the device until stop_all becomes true */
+static void *reader_body(void *arg)
+{
+ struct reader_data *rdata = arg;
+ off_t offset = rdata->offset * 512;
+ char buffer[2 * READ_BLKSIZE], *bufptr;
+ ssize_t count;
+ int page_size;
+
+ /* O_DIRECT needs page-aligned buffer/offset/blksize */
+ page_size = sysconf(_SC_PAGESIZE);
+ bufptr = (char *)(((uintptr_t)buffer + page_size) & ~(page_size - 1));
+
+ while (!*rdata->stop) {
+ /* offset may lose alignment if a read ends prematurely */
+ offset = (offset + page_size) & ~(page_size - 1);
+
+ /* should not happen, wrap if we're too fast */
+ if (offset > READ_ROOM * 512 - READ_BLKSIZE)
+ offset = rdata->offset * 512;
+
+ /* use pread() to share devfd among all the threads */
+ count = pread(rdata->devfd, bufptr, READ_BLKSIZE, offset);
+ if (count < 0) {
+ rdata->error = errno;
+ break;
+ }
+ rdata->completed += count / 512;
+ offset += count;
+ }
+
+ dprintf("reader: completed = %lld, error = %d\n",
+ rdata->completed, rdata->error);
+ return NULL;
+}
+
+/* wait for the termination of all the readers (collecting errors, if any) */
+static void wait_all(struct dprof_data *ddata, int *error)
+{
+ struct reader_data *rdata;
+ int i;
+
+ ddata->stop_all = 1;
+ for (i = 0; i < ddata->streamers; i++) {
+ rdata = ddata->reader_data + i;
+ if (!rdata->started)
+ continue;
+ pthread_join(rdata->id, NULL);
+ if (rdata->error && error)
+ *error = rdata->error;
+ }
+}
+
+/* create and start all the readers */
+static struct dprof_data *create_readers(int streamers, int devfd,
+ int64_t devsize)
+{
+ struct dprof_data *ddata;
+ struct reader_data *rdata;
+ int i, error = 0;
+ off_t step;
+
+ ddata = calloc(1, sizeof(struct reader_data) * streamers +
+ sizeof(struct dprof_data));
+ if (!ddata)
+ return NULL;
+
+ ddata->streamers = streamers;
+
+ /* space the readers evenly over the disk surface */
+ step = (devsize - streamers * READ_ROOM) / streamers;
+
+ for (i = 0; i < streamers; i++) {
+ rdata = ddata->reader_data + i;
+ rdata->offset = step * i;
+ rdata->stop = &ddata->stop_all;
+ rdata->devfd = devfd;
+
+ error = pthread_create(&rdata->id, NULL, reader_body, rdata);
+ if (error) {
+ wait_all(ddata, NULL);
+ free(ddata);
+ return NULL;
+ }
+ rdata->started = 1;
+ }
+
+ return ddata;
+}
+
+/* return the throughput, in KiB/s */
+static double calc_throughput(struct dprof_data *ddata,
+ struct timeval *begin,
+ struct timeval *end)
+{
+ struct reader_data *rdata;
+ double total = 0, delta;
+ int i;
+
+ for (i = 0; i < ddata->streamers; i++) {
+ rdata = ddata->reader_data + i;
+ total += rdata->completed;
+ }
+
+ delta = end->tv_usec - begin->tv_usec;
+ delta += (end->tv_sec - begin->tv_sec) * 1000000.0;
+
+ /* total is in sectors, delta in usecs, convert to KiB/s */
+ return total / delta * (512 * 1000000 / 1024);
+}
+
+double estimate_throughput(char *device, int streamers)
+{
+ struct timeval begin, end;
+ struct dprof_data *ddata;
+ double throughput = -1;
+ int64_t devsize;
+ int devfd, error = 0;
+
+ /* get device size */
+ devsize = read_size(device);
+ if (devsize < 0)
+ return -1;
+
+ /* open the device */
+ devfd = open(device, O_RDONLY | O_DIRECT);
+ if (devfd < 0)
+ return -1;
+
+ /* let the good times roll... */
+ gettimeofday(&begin, NULL);
+
+ /* start all the threads */
+ ddata = create_readers(streamers, devfd, devsize);
+ if (!ddata)
+ goto err;
+
+ /* let them read */
+ sleep(MEAS_INTERVAL);
+
+ /* wait for their completion */
+ wait_all(ddata, &error);
+
+ /* this is the end... */
+ gettimeofday(&end, NULL);
+
+ if (!error)
+ throughput = calc_throughput(ddata, &begin, &end);
+ else
+ errno = error;
+ free(ddata);
+
+err:
+ close(devfd);
+
+ return throughput;
+}
+
--- /dev/null
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#if defined _XOPEN_SOURCE && (_XOPEN_SOURCE < 500)
+#define _XOPEN_SOURCE 500
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+#ifdef CONFIG_DISKBFQ_DEBUG
+#define dprintf(fmt...) printf(fmt)
+#else
+#define dprintf(fmt...)
+#endif
+
+/* reserve 1GiB per client */
+#define READ_ROOM (2048ULL * 1024)
+
+/* read 512KiB per transaction */
+#define READ_BLKSIZE (1024ULL * 512)
+
+/* (max) 5 seconds */
+#define MEAS_INTERVAL 5
+
+#define SYSFS_BASE "/sys/block/"
+#define DROP_CACHES "/proc/sys/vm/drop_caches"
+
+/* per-reader descriptor */
+struct reader_data {
+ pthread_t id;
+ size_t completed;
+ off_t offset;
+ int devfd;
+ int started;
+ int error;
+ volatile int *stop;
+};
+
+/* global state, malloc'd to allow estimate_througput() to be reentrant */
+struct dprof_data {
+ int streamers;
+ volatile int stop_all;
+ struct reader_data reader_data[];
+};
+
+double estimate_throughput(char *device, int streamers);
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+test_PROGRAMS = cpucgtest
+cpucgtest_SOURCES = cpucgtest.c
+#aqcpumngr_LIBS = frm forb contract fosa rt ulut fcb_client
+lib_LOADLIBES += pthread rt frshcpucg frsh
--- /dev/null
+CONFIG_DISKBFQ=y
+CFLAGS+=-save-temps
+CONFIG_FWP=n
+CONFIG_RESOURCE_DUMMY=n
+CONFIG_RESOURCE_ITEM=n
+CONFIG_RESOURCE_CLUSTER_TREE=n
+
--- /dev/null
+#include <frsh.h>
+#include <diskbfq_res.h>
+#include <error.h>
+
+void* work_thread()
+{
+ int i;
+
+ printf("I am alive! \n");
+ while(1) {
+ printf("I am alive! \n");
+ i++;
+
+ }
+
+}
+
+int main()
+{
+ frsh_vres_id_t vres;
+ frsh_thread_attr_t attr;
+ frsh_thread_id_t thread;
+ frsh_contract_t contract;
+ frsh_rel_time_t budget, period;
+ int ret;
+
+ if (frsh_init()) {
+ error(1, 0, "FRSH initialization failed\n");
+
+ }
+
+ /* Contract negotiation for CPU */
+ ret = frsh_contract_init(&contract);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ budget = fosa_msec_to_rel_time(50);
+ period = fosa_msec_to_rel_time(100);
+ ret = frsh_contract_set_basic_params(&contract,
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+ ret = frsh_contract_set_resource_and_label(&contract, FRSH_RT_DISK,
+ 0,"aqcpu_cont1");
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ ret = frsh_contract_negotiate(&contract, &vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+
+ printf("Disk (BFQ) vres negotiated\n");
+ pthread_attr_init(&attr);
+ ret = frsh_thread_create_and_bind(vres, &thread, &attr,
+ work_thread, (void*) NULL);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_thread_create_and_bind");
+
+ pthread_join(thread.pthread_id, (void**) NULL);
+ printf("Test PASSED!\n");
+
+ return 0;
+}
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+default_CONFIG += CONFIG_RESOURCE_DUMMY=y
+default_CONFIG += CONFIG_RESOURCE_DUMMY_VERBOSE=y
+LOCAL_CONFIG_H = dummy_config.h
+
+bin_PROGRAMS = frm_dummy
+frm_dummy_SOURCES = frm_dummy.c dummy_block.c
+frm_dummy_CLIENT_IDL = res_dummy_idl.idl
+frm_dummy_LIBS = frm forb contract fosa rt ulut fcb_client
+
+shared_LIBRARIES = fra_dummy
+fra_dummy_SOURCES = fra_dummy.c dummy_block.c
+fra_dummy_LIBS = fra
+fra_dummy_CLIENT_IDL = res_dummy_idl.idl
+
+include_HEADERS = res_dummy.h
+include_GEN_HEADERS = res_dummy_idl.h
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file dummy_block.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Thu Oct 30 14:35:05 2008
+ *
+ * @brief Description contract blocks specific to dummy resource
+ *
+ *
+ */
+#include <res_dummy.h>
+#include <fres_container.h>
+
+static const struct fres_block_desc dummy_block_desc = {
+ .name = "dummy_sched",
+ .size = sizeof(fres_block_dummy_sched),
+ .serialize = (fres_block_serialize_fnc_t*)fres_block_dummy_sched_serialize,
+ .deserialize = (fres_block_deserialize_fnc_t*)fres_block_dummy_sched_deserialize,
+ .duplicate = fres_block_duplicate_default
+};
+
+int fres_block_register_dummy()
+{
+ return fres_block_register(FRES_BLOCK_DUMMY_SCHED,
+ &dummy_block_desc);
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file fra_dummy.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Wed Feb 18 16:06:34 2009
+ *
+ * @brief Dummy resource allocator implementation
+ *
+ *
+ */
+
+
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <fra_generic.h>
+#include "res_dummy.h"
+#include <stdio.h>
+#include "dummy_config.h"
+
+
+UL_LOG_CUST(ulogd_frs_dummy);
+ul_log_domain_t ulogd_fra_dummy = {UL_LOGL_MSG, "fra_dummy"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(fra_dummy_logreg_domains, ulogd_fra_dummy);
+
+struct dummy_vres_priv {
+ int num;
+};
+
+static int create_vres(fres_vres_t *vres, void *priv)
+{
+ int *my_data = priv;
+ struct dummy_vres_priv *vres_priv;
+ fres_block_basic *basic;
+ fres_block_dummy_sched *dummy_sched;
+ char id[40];
+
+ (*my_data)++;
+
+ fres_contract_id_to_string(id, &vres->id, sizeof(id));
+ basic = fres_contract_get_basic(vres->new);
+ dummy_sched = fres_contract_get_dummy_sched(vres->new);
+ vres_priv = malloc(sizeof(vres_priv));
+ vres_priv->num = *my_data;
+ vres->priv = vres_priv;
+#ifdef CONFIG_RESOURCE_DUMMY_VERBOSE
+ printf("Creating VRes #%d (id=%s, period=%ld ms, budget=%ld ms, priority=%d)\n",
+ vres_priv->num, id,
+ fosa_rel_time_to_msec(basic->period),
+ fosa_rel_time_to_msec(basic->budget),
+ dummy_sched ? dummy_sched->priority : -1);
+#endif
+ return 0;
+}
+
+static int cancel_vres(fres_vres_t *vres, void *priv)
+{
+ int *my_data = priv;
+ fres_block_basic *basic;
+ fres_block_dummy_sched *dummy_sched;
+ char id[40];
+
+ fres_contract_id_to_string(id, &vres->id, sizeof(id));
+ basic = fres_contract_get_basic(vres->allocated);
+ dummy_sched = fres_contract_get_dummy_sched(vres->allocated);
+#ifdef CONFIG_RESOURCE_DUMMY_VERBOSE
+ struct dummy_vres_priv *vres_priv = vres->priv;
+ printf("Canceling VRes #%d (id=%s, period=%ld ms, budget=%ld ms, priority=%d)\n",
+ vres_priv->num, id,
+ fosa_rel_time_to_msec(basic->period),
+ fosa_rel_time_to_msec(basic->budget),
+ dummy_sched ? dummy_sched->priority : 999);
+#endif
+ (*my_data)--;
+ return 0;
+}
+
+static int change_vres(fres_vres_t *vres, void *priv)
+{
+ fres_block_basic *basic[2];
+ fres_block_dummy_sched *dummy_sched[2];
+ char id[40];
+
+ fres_contract_id_to_string(id, &vres->id, sizeof(id));
+ basic[0] = fres_contract_get_basic(vres->allocated);
+ basic[1] = fres_contract_get_basic(vres->new);
+ dummy_sched[0] = fres_contract_get_dummy_sched(vres->allocated);
+ dummy_sched[1] = fres_contract_get_dummy_sched(vres->new);
+
+#ifdef CONFIG_RESOURCE_DUMMY_VERBOSE
+ struct dummy_vres_priv *vres_priv = vres->priv;
+ printf("Changing VRes #%d (id=%s, period: %ld -> %ld ms, budget: %ld -> %ld ms, priority: %d -> %d)\n",
+ vres_priv->num, id,
+ fosa_rel_time_to_msec(basic[0]->period),
+ fosa_rel_time_to_msec(basic[1]->period),
+ fosa_rel_time_to_msec(basic[0]->budget),
+ fosa_rel_time_to_msec(basic[1]->budget),
+ dummy_sched[0] ? dummy_sched[0]->priority : 999,
+ dummy_sched[1] ? dummy_sched[1]->priority : 999);
+#endif
+
+ vres->perceived = vres->new;
+
+ return 0;
+}
+
+
+
+static int my_data;
+
+static struct fres_allocator dummy_allocator = {
+ .res_type = DUMMY_RESOURCE_TYPE,
+ .res_id = DUMMY_RESOURCE_ID,
+ /* Here we are using the "simple interface" */
+ .create_vres = create_vres,
+ .cancel_vres = cancel_vres,
+ .change_vres = change_vres,
+ .priv = &my_data
+};
+
+int fra_dummy_init(void)
+{
+ fres_block_register_dummy();
+ return fra_register(&dummy_allocator);
+}
+
+/**
+ * Initializes addition dummy resource allocator.
+ *
+ * This is intended for the use in automatic tests which need to work
+ * with multiple resources. The test can initialize several dummy
+ * resources, not just the default one with id 255.
+ *
+ * @param id
+ *
+ * @return Zero on success, non-zero error code on error.
+ */
+int fra_dummy_init_and_activate_id(frsh_resource_id_t res_id)
+{
+ struct fres_allocator *fra;
+ int ret;
+ fres_block_register_dummy();
+ fra = malloc(sizeof(*fra));
+ if (!fra)
+ goto err;
+ *fra = dummy_allocator;
+ fra->res_id = res_id;
+ fra->priv = malloc(sizeof(int));
+ ret = fra_register(fra);
+ if (ret)
+ goto err;
+ ret = fra_activate(fra->res_type, fra->res_id);
+ return ret;
+err:
+ return -1;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file frm_dummy.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Wed Feb 18 16:06:04 2009
+ *
+ * @brief Dummy resource manager implementation
+ *
+ *
+ */
+
+
+#include <frm_generic.h>
+#include <forb.h>
+#include <error.h>
+#include <errno.h>
+#include <getopt.h>
+#include <fres_sa_scenario.h>
+#include <stdbool.h>
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include "res_dummy.h"
+#include <stdio.h>
+#include "dummy_config.h"
+
+bool opt_accept_all = false;
+bool opt_daemon = false;
+char *opt_pidfile = NULL;
+int opt_res_id = DUMMY_RESOURCE_ID;
+
+struct dummy_data {
+ int some_data;
+};
+
+int admission_test(struct fres_sa_scenario *scenario, void *priv, bool *schedulable)
+{
+ struct dummy_data *data = priv;
+ struct fres_sa_contract *c;
+ int ret;
+ long int utilization = 0;
+
+#ifdef CONFIG_RESOURCE_DUMMY_VERBOSE
+ printf("Admission test:\n");
+#endif
+
+ if (opt_accept_all) {
+ *schedulable = true;
+ return 0;
+ }
+
+ data->some_data++;
+
+ fres_sa_scenario_for_each_no_cancel_contract(scenario, c) {
+ fres_block_basic *basic;
+ fres_block_dummy_sched *dummy_sched;
+ char id[40];
+ fres_contract_id_to_string(id, &c->id, sizeof(id));
+#ifdef CONFIG_RESOURCE_DUMMY_VERBOSE
+ printf(" %s contract: id=%s num_blocks=%d\n",
+ c->contract == c->new ? "new" : "old", id,
+ fres_contract_get_num_blocks(c->contract));
+#endif
+
+ basic = fres_contract_get_basic(c->contract);
+ if (!basic) {
+ fprintf(stderr, "No basic block present\n");
+ return -1;
+ }
+
+ if (c->contract == c->new) {
+ /* Add data for scheduler to the new contracts */
+ dummy_sched = malloc(sizeof(*dummy_sched));
+ if (!dummy_sched) return -1;
+ dummy_sched->priority = 100 - fosa_rel_time_to_msec(basic->budget);
+ ret = fres_contract_add_dummy_sched(c->contract, dummy_sched);
+ if (ret) {
+ fprintf(stderr, "Cannot add dummy_sched block\n");
+ return -1;
+ }
+ } else {
+ dummy_sched = fres_contract_get_dummy_sched(c->contract);
+ if (!dummy_sched) {
+ fprintf(stderr, "Dummy_sched is not present\n");
+ return -1;
+ }
+ }
+#ifdef CONFIG_RESOURCE_DUMMY_VERBOSE
+ printf(" period=%ld ms, budget=%ld ms, priority=%d\n",
+ fosa_rel_time_to_msec(basic->period),
+ fosa_rel_time_to_msec(basic->budget), dummy_sched->priority);
+#endif
+ utilization +=
+ 1000*fosa_rel_time_to_msec(basic->budget) /
+ fosa_rel_time_to_msec(basic->period);
+ }
+ *schedulable = utilization < 1000;
+ if (*schedulable) {
+ scenario->utilization = utilization/10;
+ }
+
+#ifdef CONFIG_RESOURCE_DUMMY_VERBOSE
+ printf("utilization=%ld.%03ld => %s\n", utilization/1000, utilization%1000,
+ *schedulable?"schedulable":"not schedulable");
+#endif
+
+ return 0;
+}
+
+struct dummy_data dummy_data;
+
+static struct fres_res_manager frm = {
+ .res_type = DUMMY_RESOURCE_TYPE,
+ .res_id = DUMMY_RESOURCE_ID,
+ .admission_test = admission_test,
+ .priv = &dummy_data,
+ .name = "Dummy resource",
+};
+
+static struct option long_opts[] = {
+ { "daemon", optional_argument, NULL, 'd' },
+ { "loglevel", 1, 0, 'l' },
+ { "id", required_argument, 0, 'i' },
+ { "accept-all", 0, 0, 'a' },
+ { "help", 0, 0, 'h' },
+ { 0, 0, 0, 0}
+};
+
+static void
+usage(void)
+{
+ printf("usage: frm_dummy [ options ]\n");
+ printf(" -a, --accept-all Accepts all contracts\n");
+ printf(" -d, --daemon [pid-file] go to background after FORB initialization\n");
+ printf(" -i, --id <resource id> Use a different id that the default (%d)\n", DUMMY_RESOURCE_ID);
+ printf(" -h, --help Display this help\n");
+ printf(" -l, --loglevel <number>|<domain>=<number>,...\n");
+}
+
+int main(int argc, char *argv[])
+{
+ forb_orb orb;
+ int ret;
+ forb_init_attr_t attr = { .orb_id = "org.frescor.frm.dummy" };
+ int opt;
+
+ while ((opt = getopt_long(argc, argv, "ad::i:l:h", &long_opts[0], NULL)) != EOF) {
+ switch (opt) {
+ case 'a':
+ opt_accept_all = true;
+ case 'd':
+ opt_daemon = true;
+ opt_pidfile = optarg;
+ break;
+ case 'i':
+ opt_res_id = atoi(optarg);
+ break;
+ case 'l':
+ ul_log_domain_arg2levels(optarg);
+ break;
+ case 'h':
+ /*default:*/
+ usage();
+ exit(opt == 'h' ? 0 : 1);
+ }
+ }
+
+ if (opt_daemon)
+ forb_daemon_prepare(opt_pidfile);
+
+ orb = forb_init(&argc, &argv, &attr);
+ if (!orb) error(1, errno, "forb_init");
+
+ /* Register fres_block_dummy_sched to contract handling
+ * functions */
+ fres_block_register_dummy();
+
+#ifndef CONFIG_RESOURCE_DUMMY_VERBOSE
+ ulogd_frm_generic.level = UL_LOGL_ERR;
+#endif
+
+ frm.res_id = opt_res_id;
+ ret = frm_register_and_run(orb, &frm);
+
+ if (ret != 0) {
+ error(1, errno, "frm_generic_run failed");
+ }
+
+ return 0;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file res_dummy.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Wed Feb 18 16:06:49 2009
+ *
+ * @brief Dummy resource declarations
+ *
+ *
+ */
+
+#ifndef RES_DUMMY_H
+#define RES_DUMMY_H
+
+#include <forb.h>
+#include <fcb.h>
+#include <res_dummy_idl.h>
+#include <fres_contract.h>
+#include <fres_container.h>
+
+#define DUMMY_RESOURCE_TYPE (frsh_resource_type_t)255
+#define DUMMY_RESOURCE_ID (frsh_resource_id_t)255
+
+int fra_dummy_init(void);
+int fra_dummy_init_and_activate_id(frsh_resource_id_t res_id);
+int fres_block_register_dummy(void);
+
+/* Define fres_container_(add|get|del)_dummy_sched. */
+FRES_CONTAINER_ACCESSOR(DUMMY_SCHED, dummy_sched);
+
+/* Define fres_contract_(add|get|del)_dummy_sched. */
+FRES_CONTRACT_ACCESSOR(dummy_sched);
+
+
+#endif
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------------------- //
+// Copyright (C) 2006 - 2008 FRESCOR consortium partners: //
+// //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// Scuola Superiore Sant'Anna, ITALY //
+// Kaiserslautern University, GERMANY //
+// Univ. Politécnica Valencia, SPAIN //
+// Czech Technical University in Prague, CZECH REPUBLIC //
+// ENEA SWEDEN //
+// Thales Communication S.A. FRANCE //
+// Visual Tools S.A. SPAIN //
+// Rapita Systems Ltd UK //
+// Evidence ITALY //
+// //
+// See http://www.frescor.org for a link to partners' websites //
+// //
+// FRESCOR project (FP6/2005/IST/5-034026) is funded //
+// in part by the European Union Sixth Framework Programme //
+// The European Union is not liable of any use that may be //
+// made of this code. //
+// //
+// //
+// based on previous work (FSF) done in the FIRST project //
+// //
+// Copyright (C) 2005 Mälardalen University, SWEDEN //
+// Scuola Superiore S.Anna, ITALY //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// //
+// FSF API web pages: http:marte.unican.es/fsf/docs //
+// http:shark.sssup.it/contrib/first/docs/ //
+// //
+// This file is part of FORB (Frescor Object Request Broker) //
+// //
+// FORB is free software; you can redistribute it and/or modify it //
+// under terms of the GNU General Public License as published by the //
+// Free Software Foundation; either version 2, or (at your option) any //
+// later version. FORB is distributed in the hope that it will be //
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty //
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
+// General Public License for more details. You should have received a //
+// copy of the GNU General Public License along with FORB; see file //
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, //
+// Cambridge, MA 02139, USA. //
+// //
+// As a special exception, including FORB header files in a file, //
+// instantiating FORB generics or templates, or linking other files //
+// with FORB objects to produce an executable application, does not //
+// by itself cause the resulting executable application to be covered //
+// by the GNU General Public License. This exception does not //
+// however invalidate any other reasons why the executable file might be //
+// covered by the GNU Public License. //
+////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @file res_dummy_idl.idl
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Thu Oct 30 14:27:12 2008
+ *
+ * @brief Contract data block for dummy resource
+ *
+ *
+ */
+module fres {
+ module block {
+ /// Dummy data to demonstrate information transfer from
+ // manager to allocator
+ struct dummy_sched {
+ long priority;
+ };
+ };
+};
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+default_CONFIG += CONFIG_RESOURCE_FPGA=y
+default_CONFIG += CONFIG_FPGA_CORES=FRES_FPGA_CORRELATOR508_m
+
+ifeq ($(CONFIG_RESOURCE_FPGA),y)
+LOCAL_CONFIG_H = fpga_config.h
+
+bin_PROGRAMS = frm_fpga
+frm_fpga_SOURCES = frm_fpga.c fpga_block.c
+frm_fpga_CLIENT_IDL = res_fpga_idl.idl
+frm_fpga_LIBS = frm forb contract fosa rt ulut fcb_client
+
+shared_LIBRARIES = fra_fpga
+fra_fpga_SOURCES = fra_fpga.c fpga_block.c
+fra_fpga_LIBS = fra
+fra_fpga_CLIENT_IDL = res_fpga_idl.idl
+
+include_HEADERS = res_fpga.h
+include_GEN_HEADERS = res_fpga_idl.h
+endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file fpga_block.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Thu Oct 30 14:35:05 2008
+ *
+ * @brief Description contract blocks specific to FPGA resource
+ *
+ *
+ */
+#include <res_fpga.h>
+#include <fres_container.h>
+
+static const struct fres_block_desc fpga_block_desc = {
+ .name = "fpga",
+ .size = sizeof(fres_block_fpga),
+ .serialize = (fres_block_serialize_fnc_t*)fres_block_fpga_serialize,
+ .deserialize = (fres_block_deserialize_fnc_t*)fres_block_fpga_deserialize,
+ .duplicate = fres_block_duplicate_default
+};
+
+int fres_block_register_fpga()
+{
+ return fres_block_register(FRES_BLOCK_FPGA,
+ &fpga_block_desc);
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file fra_fpga.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Wed Feb 18 16:07:49 2009
+ *
+ * @brief FPGA resource allocator
+ *
+ *
+ */
+
+
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <fra_generic.h>
+#include "res_fpga.h"
+#include <stdio.h>
+
+
+UL_LOG_CUST(ulogd_frs_fpga);
+ul_log_domain_t ulogd_fra_fpga = {UL_LOGL_MSG, "fra_fpga"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(fra_fpga_logreg_domains, ulogd_fra_fpga);
+
+static int create_vres(fres_vres_t *vres, void *priv)
+{
+ return 0;
+}
+
+static int cancel_vres(fres_vres_t *vres, void *priv)
+{
+ return 0;
+}
+
+static int change_vres(fres_vres_t *vres, void *priv)
+{
+ return 0;
+}
+
+
+
+static struct fres_allocator fpga_allocator = {
+ .res_type = FRSH_RT_FPGA,
+ .res_id = 0,
+ /* Here we are using the "simple interface" */
+ .create_vres = create_vres,
+ .cancel_vres = cancel_vres,
+ .change_vres = change_vres,
+};
+
+int fra_fpga_init(void)
+{
+ fres_block_register_fpga();
+ return fra_register(&fpga_allocator);
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file frm_fpga.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Wed Feb 18 16:08:22 2009
+ *
+ * @brief FPGA resource manager
+ *
+ *
+ */
+
+
+#include <frm_generic.h>
+#include <forb.h>
+#include <error.h>
+#include <errno.h>
+#include <fres_sa_scenario.h>
+#include <stdbool.h>
+#include <ul_log.h>
+#include "res_fpga.h"
+#include <stdio.h>
+#include "fpga_config.h"
+
+/**
+ * State of the FPGA
+ */
+struct fpga_state {
+ fres_cores_t cores; /**< Currently loaded cores */
+};
+
+int admission_test(struct fres_sa_scenario *scenario, void *priv, bool *schedulable)
+{
+ struct fpga_state *data = priv;
+ struct fres_sa_contract *c;
+
+ fres_sa_scenario_for_each_no_cancel_contract(scenario, c) {
+ fres_block_fpga *fpga;
+
+ fpga = fres_contract_get_fpga(c->contract);
+ if (fpga) {
+ fres_cores_t req = fpga->cores;
+ fres_cores_t cur = data->cores;
+ if ((req & ~cur) != 0) *schedulable = false;
+ else *schedulable = true;
+ } else {
+ fprintf(stderr, "FPGA block is not present\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+struct fpga_state fpga_state = {
+ /* Currently only static FPGA configuration specified at
+ * compile type is supported. */
+ .cores = CONFIG_FPGA_CORES,
+};
+
+static const struct fres_res_manager frm = {
+ .res_type = FRSH_RT_FPGA,
+ .res_id = 0,
+ .name = "FPGA",
+ .admission_test = admission_test,
+ .priv = &fpga_state
+};
+
+
+int main(int argc, char *argv[])
+{
+ forb_orb orb;
+ int ret;
+ forb_init_attr_t attr = { .orb_id = "org.frescor.frm.fpga" };
+ orb = forb_init(&argc, &argv, &attr);
+ if (!orb) error(1, errno, "forb_init");
+
+ /* Register fres_block_fpga to contract handling
+ * functions */
+ fres_block_register_fpga();
+
+ ret = frm_register_and_run(orb, &frm);
+
+ if (ret != 0) {
+ error(1, errno, "frm_generic_run failed");
+ }
+
+ return 0;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file res_fpga.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Wed Feb 18 16:08:42 2009
+ *
+ * @brief FPGA resource declarations
+ *
+ *
+ */
+
+#ifndef RES_FPGA_H
+#define RES_FPGA_H
+
+#include <forb.h>
+#include <fcb.h>
+#include <res_fpga_idl.h>
+#include <fres_contract.h>
+#include <fres_container.h>
+
+int fra_fpga_init(void);
+int fres_block_register_fpga(void);
+
+/* Define fres_container_(add|get|del)_fpga. */
+FRES_CONTAINER_ACCESSOR(FPGA, fpga);
+
+/* Define fres_contract_(add|get|del)_fpga. */
+FRES_CONTRACT_ACCESSOR(fpga);
+
+/* Available FPGA cores */
+#define FRES_FPGA_TIMESTAMP_b 0
+#define FRES_FPGA_CORRELATOR508_b 1
+
+#define FRES_FPGA_TIMESTAMP_m (1<<FRES_FPGA_TIMESTAMP_b)
+#define FRES_FPGA_CORRELATOR508_m (1<<FRES_FPGA_CORRELATOR508_b)
+
+
+#endif
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------------------- //
+// Copyright (C) 2006 - 2008 FRESCOR consortium partners: //
+// //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// Scuola Superiore Sant'Anna, ITALY //
+// Kaiserslautern University, GERMANY //
+// Univ. Politécnica Valencia, SPAIN //
+// Czech Technical University in Prague, CZECH REPUBLIC //
+// ENEA SWEDEN //
+// Thales Communication S.A. FRANCE //
+// Visual Tools S.A. SPAIN //
+// Rapita Systems Ltd UK //
+// Evidence ITALY //
+// //
+// See http://www.frescor.org for a link to partners' websites //
+// //
+// FRESCOR project (FP6/2005/IST/5-034026) is funded //
+// in part by the European Union Sixth Framework Programme //
+// The European Union is not liable of any use that may be //
+// made of this code. //
+// //
+// //
+// based on previous work (FSF) done in the FIRST project //
+// //
+// Copyright (C) 2005 Mälardalen University, SWEDEN //
+// Scuola Superiore S.Anna, ITALY //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// //
+// FSF API web pages: http:marte.unican.es/fsf/docs //
+// http:shark.sssup.it/contrib/first/docs/ //
+// //
+// This file is part of FORB (Frescor Object Request Broker) //
+// //
+// FORB is free software; you can redistribute it and/or modify it //
+// under terms of the GNU General Public License as published by the //
+// Free Software Foundation; either version 2, or (at your option) any //
+// later version. FORB is distributed in the hope that it will be //
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty //
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
+// General Public License for more details. You should have received a //
+// copy of the GNU General Public License along with FORB; see file //
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, //
+// Cambridge, MA 02139, USA. //
+// //
+// As a special exception, including FORB header files in a file, //
+// instantiating FORB generics or templates, or linking other files //
+// with FORB objects to produce an executable application, does not //
+// by itself cause the resulting executable application to be covered //
+// by the GNU General Public License. This exception does not //
+// however invalidate any other reasons why the executable file might be //
+// covered by the GNU Public License. //
+////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @file res_fpga_idl.idl
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Thu Oct 30 14:27:12 2008
+ *
+ * @brief Contract data block for FPGA resource
+ */
+module fres {
+ typedef unsigned long long cores_t;
+ module block {
+ struct fpga {
+ cores_t cores;
+ };
+ };
+};
--- /dev/null
+/**
+ * This file contains the default baud rate for current TinyOS
+ * platforms. Don't add anything but platform entries, as this file is also
+ * #included in C code to get the table, with appropriate #define's to
+ * avoid problems...
+*/
+/*package net.tinyos.packet;*/
+
+class BaudRate {
+ static void init() throws Exception {
+ /* The Platform.x argument is there for when this code is #include'd
+ into C */
+ Platform.add(Platform.x, "mica", 19200);
+ Platform.add(Platform.x, "mica2", 57600);
+ Platform.add(Platform.x, "mica2dot", 19200);
+ Platform.add(Platform.x, "telos", 115200);
+ Platform.add(Platform.x, "telosb", 115200);
+ Platform.add(Platform.x, "tinynode", 115200);
+ Platform.add(Platform.x, "tmote", 115200);
+ Platform.add(Platform.x, "micaz", 57600);
+ Platform.add(Platform.x, "eyesIFX", 57600);
+ Platform.add(Platform.x, "intelmote2", 115200);
+ }
+}
--- /dev/null
+#include "FWSN.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <string.h>
+#include <semaphore.h>
+
+#include "serialsource.h"
+
+
+
+static char *msgs[] = {
+ "unknown_packet_type",
+ "ack_timeout" ,
+ "sync" ,
+ "too_long" ,
+ "too_short" ,
+ "bad_sync" ,
+ "bad_crc" ,
+ "closed" ,
+ "no_memory" ,
+ "unix_error"
+};
+
+
+int frameLength; //WSN frame length, readed form the network
+int numberOfSlots; //number of assigned slots in WSN, readed form the network
+int slotTime; // time of the TDMA slot in WSN (from DEFINE)
+unsigned char data[MAX_DATA_LENGTH]; //las read data
+int dataLength;
+int dataValid;
+// counters for maximum number of add/remove attemps.
+int RepeatCounter_overPeriod; // counts number of used period to add/remove a device. (lost of the communication chanel)
+int communication_error; // information, that maximum counter has been achieved without adding/removing the node
+
+
+sem_t actionLock; //there is a demand to add or remove a node
+sem_t waitAdd; //wait until the action is finished
+sem_t waitRemove; //wait until the action is finished
+// there is a demand to add/remove a node
+int applayAdd;
+int applayRemove;
+//unsigned char applayRemove; //there is a demand to remove a ne node
+unsigned char addDeviceID; //node ID
+unsigned char remDeviceID; //node ID
+
+
+
+void *readData ( void *ptr );
+
+
+void stderr_msg(serial_source_msg problem)
+{
+ fprintf(stderr, "Note: %s\n", msgs[problem]);
+}
+
+//*************************************************************************************************************************
+/*
+initialize the thread to red data from the network
+*/
+pthread_t init(void *argv)
+{
+ pthread_t threadRead;
+ //initialize semaphors for add/remove node control
+
+ sem_init(&waitAdd, 0, 0);
+ sem_init(&waitRemove, 0, 0);
+ sem_init(&actionLock, 0, 1);
+ // start the reading thread
+ pthread_create( &threadRead, NULL, readData, argv);
+ return threadRead;
+}
+
+//*************************************************************************************************************************
+/*
+send comand to the WSN to add a new device with "id"
+*/
+int sendAddDevice(serial_source src, unsigned char id)
+{
+ unsigned char packet[] = {DEFAULT_PACKET_ADD_DEVICE};
+ int sendResult;
+ int repeatCount =0;
+ // write node ID in to the packet
+ packet[11] = id;
+ // send packet
+ sendResult = write_serial_packet(src, packet, PACKET_LENGTH);
+ // repeat if not sent
+ while ((sendResult != 0) && (repeatCount < MAXIMUM_REPEAT_COUNTER))
+ {
+ usleep(DELAY_BETWEEN_SENDS);
+ sendResult = write_serial_packet(src, packet, PACKET_LENGTH);
+ repeatCount++;
+ }
+ if (sendResult ==0)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+//*************************************************************************************************************************
+/*
+send comand to the WSN to remove a device with "id"
+*/
+int sendRemoveDevice(serial_source src, unsigned char id)
+{
+ unsigned char packet[] = {DEFAULT_PACKET_REMOVE_DEVICE};
+ int sendResult;
+ int repeatCount =0;
+ // write node ID in to the packet
+ packet[11] = id;
+ // send packet
+ sendResult = write_serial_packet(src, packet, PACKET_LENGTH);
+
+ // repeat if not sent
+ while ((sendResult != 0) && (repeatCount < MAXIMUM_REPEAT_COUNTER))
+ {
+ usleep(DELAY_BETWEEN_SENDS);
+ sendResult = write_serial_packet(src, packet, PACKET_LENGTH);
+ repeatCount++;
+ }
+ if (sendResult ==0)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+//*************************************************************************************************************************
+/*
+the thread to read the data from the WSN
+*/
+void *readData ( void *ptr )
+{
+ serial_source src;
+ char **argv;
+ argv = (char **) ptr;
+
+ src = open_serial_source(argv[1], platform_baud_rate(argv[2]), 0, stderr_msg);
+ if (!src)
+ {
+ fprintf(stderr, "Couldn't open serial port at %s:%s\n", argv[1],argv[2]);
+ exit(1);
+ }
+
+
+ for(;;)
+ {
+ int len, dataLengthOld;
+ const unsigned char *packet = read_serial_packet(src, &len); //read the data form the network
+ if (!packet)
+ exit(0);
+
+
+
+ dataLengthOld = dataLength;
+ dataLength = 0;
+ if ((len > 15) && ((len-15)%4 == 1) && (packet[2] == 0x7E)) //parse the received data
+ {
+ memcpy(data,&packet[15],len - 15);
+ dataLength = len - 15; //minus the head of the message and -1 byte for number of slots information, at the end of package.
+ frameLength = packet[12];
+ slotTime = SLOT_TIME * 2;
+ numberOfSlots = packet[len-1];
+ dataValid = 1;
+ }
+ else
+ {
+ dataLength = dataLengthOld;
+ dataValid = 0;
+ }
+
+ //check if the device has been added
+ if (applayAdd == 1) // if there is a demand to add a new device, check if it has been allready added.
+ {
+ int i;
+ for (i=0;i<dataLength;i=i+4) //has been added?
+ {
+ if (data[i+1] == addDeviceID)
+ applayAdd = 0;
+ }
+ if (RepeatCounter_overPeriod > MAXIMUM_REPEAT_COUNTER_OVER_PERIOD && applayAdd == 1) // check the repeat counter
+ {
+ communication_error = 1;
+ applayAdd = 0;
+ }
+ if (applayAdd == 0) // free the demand
+ sem_post(&waitAdd);
+ else
+ RepeatCounter_overPeriod++;
+
+
+ }
+
+ //check if the device has been removed
+ if (applayRemove == 1) // if there is a demand to remove a device, check if it has been allready removed.
+ {
+ int i;
+ int applayRemoveLocal = 0;
+ for (i=0;i<dataLength;i=i+4) // has been removed?
+ {
+ if (data[i+1] == remDeviceID)
+ applayRemoveLocal = 1;
+ }
+ if (RepeatCounter_overPeriod > MAXIMUM_REPEAT_COUNTER_OVER_PERIOD && applayRemoveLocal == 1) // check the counter
+ {
+ communication_error = 1;
+ applayRemoveLocal = 0;
+ }
+ if (applayRemoveLocal == 0) //free the demand
+ {
+ applayRemove = 0;
+ sem_post(&waitRemove);
+ }
+ else
+ RepeatCounter_overPeriod++;
+ }
+
+ free((void *)packet);
+ usleep(DELAY_BETWEEN_SENDS);
+
+ // if there is a demand to add a device, send the control package
+ if (applayAdd == 1)
+ {
+ sendAddDevice(src, addDeviceID);
+ usleep(DELAY_BETWEEN_SENDS);
+ }
+
+ // if there is a demand to remove a device, send the control package
+ if (applayRemove == 1)
+ {
+ sendRemoveDevice(src, remDeviceID);
+ usleep(DELAY_BETWEEN_SENDS);
+ }
+ }
+ return NULL;
+}
+
+//*************************************************************************************************************************
+/*
+returns 1, if there is a free slot in the TDMA of sensor network, which satisfay that all responses will be in "maxResponseTime" time (ms)
+returns 0 if new device will by possible to add after the networ automatic reconfiguration.
+returns -1 if not.
+*/
+
+int isFreeSlot(int maxResponseTime)
+{
+ int maxFrameLength;
+ int queuedDev;
+ // compute the demanded framelength of the ITEM according the demanded maximum commuication delay.
+
+ maxFrameLength = floor((float)maxResponseTime/(float)slotTime);
+ if (maxFrameLength < 4) return -1;
+ if (maxFrameLength >= 8) maxFrameLength = 8;
+ else
+ maxFrameLength = 4;
+
+ // check if there is no adding demand in process
+ if (applayAdd == 1)
+ queuedDev = 1; // one node is waiting in the queue to bee added.
+
+
+
+ if (numberOfSlots + 1 + queuedDev < maxFrameLength)
+ { // number of devices is smaller than the number of slots in the demanded period
+ if (frameLength <= maxFrameLength) return 1; //and the distribution of assigned slots is the way, that the actual period is smaller then the demanded one
+ else return 0; //wrong distribution of slots, try it after a while, (after an automatic system reconfiguration)
+ }
+ return -1; // not posible to add a new device.
+}
+
+
+//*************************************************************************************************************************
+/*
+returns -1, the demanded period is higher than the actual one
+returns -2, node adding in process, not posiyble to determine the number of free slots
+returns 0, no free slot remains
+returns X, there is X free slots
+*/
+
+int noOfFreeSlots(int maxResponseTime)
+{
+ int maxFrameLength;
+ int freeSlots;
+ // check if there is no adding demand in the process
+ if (applayAdd == 1)
+ return -2; // node adding in process, not posiyble to determine the number of free slots
+
+
+
+ // compute the demanded framelength of the ITEM according the demanded maximum commuication delay.
+ maxFrameLength = floor((float)maxResponseTime/(float)slotTime);
+ if (maxFrameLength < 4) return -1;
+ if (maxFrameLength >= 8) maxFrameLength = 8;
+ else
+ maxFrameLength = 4;
+
+
+ if (frameLength > maxFrameLength) return -1; // actual period is higher than the demanded one.
+ freeSlots = maxFrameLength-1;// - numberOfSlots -1; //nubmer of free slots
+
+ return freeSlots; // !!!!!!!!!! number of free slots in the frame length. Does not depend on number of ocupied slots.
+}
+
+
+
+//*************************************************************************************************************************
+/*
+Try to add the device "id".
+returns 1 if the device has been added.
+returns -1 if not.
+*/
+int addDevice ( unsigned char id)
+{
+ sem_wait(&actionLock); // lock the control section, or wait for free access.
+ // reset the counter and the error flag
+ RepeatCounter_overPeriod = 0;
+ communication_error = 0;
+ //strat the task
+ addDeviceID = id;
+ applayAdd = 1;
+ //wait until the node is added
+ sem_wait(&waitAdd);
+ sem_post(&actionLock);
+
+
+ if (communication_error == 1)
+ return -1;
+ return 1;
+}
+
+//*************************************************************************************************************************
+/*
+Try to remove the device "id".
+returns 1 if the device has been removed
+returns -1 if not.
+returns -2 if "id" is basestation (it is not possible to remove the basestation)
+*/
+int removeDevice (unsigned char id)
+{
+ if (id == BASESTATION_ID) return -2;
+
+ sem_wait(&actionLock); //lock the control section or wait
+ //reset the counter and the communication error flag
+ RepeatCounter_overPeriod = 0;
+ communication_error = 0;
+ //strat the action
+ remDeviceID = id;
+ applayRemove = 1;
+ //wait untkil the node is removed
+ sem_wait(&waitRemove);
+ sem_post(&actionLock);
+
+ if (communication_error == 1)
+ return -1;
+ return 1;
+}
+
+//*************************************************************************************************************************
+/*
+returns the data length.
+and the data arrauy in dat.
+returns 0 if there are no available data.
+*/
+unsigned getData(unsigned char *dat, unsigned length)
+{
+ if ((dataLength > 0) && (dataValid == 1))
+ {
+ unsigned l = dataLength < length ? dataLength : length;
+ memcpy(dat,data,l);
+ return l;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+//*************************************************************************************************************************
+//*************************************************************************************************************************
--- /dev/null
+#ifndef FWSN_H
+#define FWSN_H
+
+
+#include <pthread.h>
+
+#define SLOT_TIME 128
+#define MAX_DATA_LENGTH 64
+#define DEFAULT_PACKET_ADD_DEVICE 0x00, 0xff, 0xff, 0x00, 0x00, 0x02, 0x00, 0x07, 0xc2, 0x02, 0xc5, 0x00
+#define DEFAULT_PACKET_REMOVE_DEVICE 0x00, 0xff, 0xff, 0x00, 0x00, 0x02, 0x00, 0x07, 0xc2, 0x02, 0x5C, 0x00
+#define PACKET_LENGTH 12
+#define DELAY_BETWEEN_SENDS 3000
+#define MAXIMUM_REPEAT_COUNTER 5
+#define MAXIMUM_REPEAT_COUNTER_OVER_PERIOD 7
+#define BASESTATION_ID 01
+
+
+pthread_t init(void *argv);
+/*
+Initialize the proces of reading data from the sensor network.
+Returns a pointer to the thread of the proces. NULL - no thread has been created.
+argv - <device> <rate> . example: "/dev/ttyUSB0 telosb"
+*/
+
+//*************************************************************************************************************************
+int isFreeSlot(int maxResponseTime);
+/*
+returns 1, if there is a free slot in the TDMA of sensor network, which satisfay that all responses will be in "maxResponseTime" time (ms)
+returns 0 if new device will by possible to add after the networ automatic reconfiguration.
+returns -1 if not.
+*/
+
+//*************************************************************************************************************************
+int noOfFreeSlots(int maxResponseTime);
+/*
+returns -1, the demanded period is higher than the actual one
+returns -2, node adding in process, not posiyble to determine the number of free slots
+returns 0, no free slot remains
+returns X, there is X free slots in the available frame length
+*/
+
+//*************************************************************************************************************************
+int addDevice ( unsigned char id);
+/*
+Try to add the device "id".
+returns 1 if the device has been added.
+returns -1 if not.
+*/
+
+
+//*************************************************************************************************************************
+int removeDevice (unsigned char id);
+/*
+Try to remove the device "id".
+returns 1 if the device has been removed
+returns -1 if not.
+returns -2 if "id" is basestation (it is not possible to remove the basestation)
+*/
+//*************************************************************************************************************************
+
+unsigned getData(unsigned char *dat, unsigned length);
+/*
+returns the data length.
+and the data arrauy in dat.
+returns 0 if there are no available data.
+*/
+
+
+#endif
--- /dev/null
+CC=gcc\r
+CFLAGS=-g -std=c99 -pedantic -Wall\r
+\r
+%.o:%.c\r
+ $(CC) $(CFLAGS) -c $<\r
+\r
+FWSN: example_FWSN.o FWSN.o serialsource.o\r
+ gcc -lm -lc -lpthread example_FWSN.o FWSN.o serialsource.o -o example_FWSN\r
+\r
+\r
+clean:\r
+ rm -f *.o send listen FWSN example_FWSN\r
+\r
--- /dev/null
+default_CONFIG = CONFIG_RESOURCE_ITEM=y
+
+ifeq ($(CONFIG_RESOURCE_ITEM),y)
+CFLAGS += -std=gnu99
+
+bin_PROGRAMS = frm_item
+frm_item_SOURCES = frm_item.c item_blocks.c FWSN.c serialsource.c
+frm_item_SERVER_IDL = item_idl.idl
+frm_item_LIBS = frm forb contract fosa rt ulut fcb_client m
+
+shared_LIBRARIES = fra_item
+fra_item_SOURCES = item_blocks.c fra_item.c
+fra_item_LIBS = fra
+fra_item_CLIENT_IDL = item_idl.idl
+
+include_HEADERS = item.h
+include_GEN_HEADERS = item_idl.h
+
+SUBDIRS=tests
+endif
--- /dev/null
+#include "FWSN.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+
+void printdata()
+{
+ unsigned char *d;
+ int len,i;
+
+ len = getData(&d);
+
+ for (i = 0; i < len-1; i++)
+ {
+ printf("%02x ", d[i]);
+ if (i%4 == 3)
+ printf(" | ");
+ }
+ free(d);
+ putchar('\n');
+}
+//*************************************************************************************************************************
+void mysleep(int time)
+{
+ int i;
+ for(i=0;i<time;i++)
+ {
+ sleep(1);
+ printdata();
+ }
+
+}
+
+//*************************************************************************************************************************
+
+int main(int argc, char **argv)
+{
+ pthread_t threadRead;
+
+ if (argc != 3)
+ {
+ fprintf(stderr, "Usage: %s <device> <rate> - dump packets from a serial port\n", argv[0]);
+ exit(2);
+ }
+
+ threadRead = init(argv);
+
+ for (;;)
+ {
+
+//ADDing of the nodes.
+
+ printdata();
+ mysleep(2);
+ printf("addDevice(0x02) \n");
+ if (addDevice(0x02) == 1 ) printf("ADD \n");
+
+
+ printdata();
+ //mysleep(10);
+ printf("addDevice(0x03) \n");
+ if (addDevice(0x03) == 1 ) printf("ADD \n");
+
+
+ printdata();
+ //mysleep(10);
+ printf("addDevice(0x03) \n");
+ if (addDevice(0x03) == 1 ) printf("ADD \n");
+
+
+ printdata();
+ // mysleep(10);
+ printf("addDevice(0x04) \n");
+ if (addDevice(0x04) == 1 ) printf("ADD \n");
+
+
+
+ printdata();
+ //mysleep(10);
+ printf("addDevice(0x06) \n");
+ if (addDevice(0x06) == 1 ) printf("ADD \n");
+
+
+
+// REMOVE ALL nodes
+ printdata();
+ mysleep(10);
+ printf("removeDevice(0x04) \n");
+ if (removeDevice(0x04) == 1 ) printf("REM \n");
+
+
+ printdata();
+ //mysleep(10);
+ printf("removeDevice(0x06) \n");
+ if (removeDevice(0x06) == 1 ) printf("REM \n");
+
+
+ printdata();
+ //mysleep(10);
+ printf("removeDevice(0x03) \n");
+ if (removeDevice(0x03) == 1 ) printf("REM \n");
+ //else printf("NOT - REM \n");
+ //putchar('\n');
+
+ printdata();
+ //mysleep(10);
+ printf("removeDevice(0x02) \n");
+ if (removeDevice(0x02) == 1 ) printf("REM \n");
+ else printf("NOT - REM \n");
+ putchar('\n');
+
+
+
+ mysleep(5);
+ }
+
+
+}
+
--- /dev/null
+#include <item.h>
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <fra_generic.h>
+#include <stdio.h>
+#include <frsh_distributed.h>
+#include <frsh_forb.h>
+
+UL_LOG_CUST(ulogd_fra_item);
+ul_log_domain_t ulogd_fra_item = {UL_LOGL_MSG, "fra_item"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(fra_item_logreg_domains, ulogd_fra_item);
+
+struct item {
+ fres_item_scheduler scheduler;
+};
+
+static int create_vres(fres_vres_t *vres, void *priv)
+{
+ struct item *item = priv;
+ fres_block_item_nodes *nodes;
+ CORBA_Environment env;
+ int ret;
+
+ nodes = fres_contract_get_item_nodes(vres->new);
+ if (!nodes) return FRES_ERR_NEEDS_MORE_DATA_IN_CONTRACT;
+
+ ret = fres_item_scheduler_add_nodes(item->scheduler, nodes->mask, &env);
+ if (forb_exception_occurred(&env)) return fres_forbex2err(&env);
+ if (ret) return ret;
+ return 0;
+}
+
+static int cancel_vres(fres_vres_t *vres, void *priv)
+{
+ struct item *item = priv;
+ fres_block_item_nodes *nodes;
+ CORBA_Environment env;
+ int ret;
+
+ nodes = fres_contract_get_item_nodes(vres->allocated);
+ if (!nodes) return FRES_ERR_NEEDS_MORE_DATA_IN_CONTRACT;
+
+ ret = fres_item_scheduler_del_nodes(item->scheduler, nodes->mask, &env);
+ if (forb_exception_occurred(&env)) return fres_forbex2err(&env);
+ if (ret) return ret;
+ return 0;
+}
+
+static int change_vres(fres_vres_t *vres, void *priv)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+static struct item item;
+
+int initialize_item_scheduler(forb_orb orb)
+{
+ item.scheduler = forb_resolve_reference(frsh_forb_global.orb, "item_scheduler");
+ if (!item.scheduler) {
+ ul_logerr("forb_resolve_reference(item_scheduler) failed\n");
+ return errno;
+ }
+ return 0;
+}
+
+static struct fres_allocator item_allocator = {
+ .res_type = FRSH_RT_NETWORK,
+ .res_id = FRSH_NETPF_ITEM,
+ /* Here we are using the "simple interface" */
+ .create_vres = create_vres,
+ .cancel_vres = cancel_vres,
+ .change_vres = change_vres,
+ .priv = &item,
+ .activate_callback = initialize_item_scheduler,
+};
+
+int fra_item_init(void)
+{
+ fres_block_register_item();
+ return fra_register(&item_allocator);
+}
+
+/**
+ * Receives data from sensor network.
+ *
+ * @param[in] vres
+ *
+ * @param[out] data Where to store pointer to the array with received
+ * data. The programmer should free the returned array via
+ * forb_free(), when the data are not needed anymore.
+ *
+ * @return Number of elements returned in @a data array, -1 on error.
+ */
+int fra_item_receive(frsh_vres_id_t vres, unsigned char *data[])
+{
+ fres_item_data_seq *seq;
+ fres_block_item_nodes *nodes;
+ int ret;
+ CORBA_Environment env;
+
+ nodes = fres_contract_get_item_nodes(vres->allocated);
+ if (!nodes) return FRES_ERR_NEEDS_MORE_DATA_IN_CONTRACT;
+
+ fres_item_scheduler_get_data(item.scheduler, nodes->mask, &seq, &env);
+ CORBA_sequence_set_release(seq, CORBA_FALSE);
+ ret = seq->_length;
+ *data = seq->_buffer;
+
+
+
+ forb_free(seq);
+ return ret;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file frm_item.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @author Jiri Trdlicka <trdlij1@fel.cvut.cz>
+ * @date Thu Nov 6 17:21:48 2008
+ *
+ * @brief Resource manager for ITEM protocol
+ *
+ *
+ */
+#include <frm_generic.h>
+#include <forb.h>
+#include <error.h>
+#include <errno.h>
+#include <fres_sa_scenario.h>
+#include <stdbool.h>
+#include <ul_log.h>
+#include <stdio.h>
+#include <frsh_distributed.h>
+#include <item.h>
+#include "FWSN.h"
+
+static inline bool node_present(fres_item_node_mask nodes, int node)
+{
+ return (nodes & (1LL<<node)) != 0;
+}
+
+static inline void node_add(fres_item_node_mask *nodes, int node)
+{
+ *nodes |= (1LL<<node);
+}
+
+static inline void node_del(fres_item_node_mask *nodes, int node)
+{
+ *nodes &= (~(1LL<<node));
+}
+
+static int
+admission_test(struct fres_sa_scenario *scenario, void *priv, bool *schedulable)
+{
+ struct fres_sa_contract *c;
+ fres_item_node_mask all_nodes;
+ frsh_rel_time_t min_deadline = fosa_msec_to_rel_time(0);
+
+
+ /* Find communicating nodes and the most restricting deadline */
+ all_nodes = 0;
+ fres_sa_scenario_for_each_no_cancel_contract(scenario, c) {
+ fres_block_item_nodes *nodes;
+ fosa_rel_time_t deadline;
+
+ nodes = fres_contract_get_item_nodes(c->contract);
+ if (!nodes) return FRES_ERR_NEEDS_MORE_DATA_IN_CONTRACT;
+ all_nodes |= nodes->mask;
+
+
+ if (fres_contract_get_deadline(&c->contract, &deadline)) {
+ if (fosa_rel_time_is_null(min_deadline) ||
+ fosa_rel_time_smaller(deadline, min_deadline)) {
+ min_deadline = deadline;
+ }
+ }
+ }
+
+
+ if (!fosa_rel_time_is_null(min_deadline)) {
+ /* Compare number of nodes and min_deadline */
+ //ITEM ADD
+ int i;
+ int count_nodes;
+ int free_slots;
+ fres_item_node_mask counting_var;
+
+ counting_var =1;
+ count_nodes = 0;
+ *schedulable = true;
+
+ for (i = 0; i <= sizeof(all_nodes)-1; i++) //FIXME Number of bits
+ {
+ //printf("JOP 5 - %i\n",aa);
+ if ((all_nodes & counting_var) > 0)
+ count_nodes = count_nodes + 1;
+ counting_var = counting_var<<1;
+ }
+
+ free_slots = noOfFreeSlots(fosa_rel_time_to_msec(min_deadline));
+
+ if (free_slots < 0)
+ {
+ *schedulable = false; // adding of new nodes in action or the actual period is higher then the minimum demanded one.
+ }
+ else
+ {
+ if (free_slots < count_nodes)
+ *schedulable = false; // too much nodes are demanded
+ }
+
+ }
+ else {
+ *schedulable = true;
+ }
+
+ return 0;
+}
+
+struct item_status {
+ /** Specifies how many applications want to read from a which
+ * node */
+ int node_requested[64];
+};
+
+CORBA_long
+add_nodes(fres_item_scheduler obj, const fres_item_node_mask mask, CORBA_Environment *ev)
+{
+ int node;
+ struct item_status *item_status = (struct item_status*)forb_instance_data(obj);
+
+ for (node=1; node<64; node++) {
+ if (node_present(mask, node)) {
+ if (item_status->node_requested[node] == 0)
+ {
+ /* Add node */
+ addDevice(node); //ITEM ADD
+ }
+ item_status->node_requested[node]++;
+ }
+ }
+ return 0;
+}
+
+CORBA_long
+del_nodes(fres_item_scheduler obj, const fres_item_node_mask mask, CORBA_Environment *ev)
+{
+ struct item_status *item_status = (struct item_status*)forb_instance_data(obj);
+ int node;
+
+ for (node=1; node<64; node++) {
+ if (node_present(mask, node)) {
+ item_status->node_requested[node]--;
+ if (item_status->node_requested[node] == 0)
+ {
+ /* Remove node */
+ removeDevice(node); //ITEM ADD
+ }
+ }
+ }
+ return 0;
+}
+
+CORBA_long
+get_data(fres_item_scheduler obj, const fres_item_node_mask mask, fres_item_data_seq** data, CORBA_Environment *ev)
+{
+ unsigned max = 256;
+ //struct item_status *item_status = (struct item_status*)forb_instance_data(obj);
+ fres_item_data_seq *d = forb_malloc(sizeof(*d));
+
+ d->_buffer = CORBA_sequence_octet_allocbuf(max); //FIXME: CORBA_sequence_fres_item_data_seq_allocbuf(max);
+ d->_maximum = max;
+ d->_length = getData(d->_buffer, d->_maximum);
+
+ *data = d;
+
+ return 0;
+}
+
+static const struct fres_res_manager frm_item_desc = {
+ .res_type = FRSH_RT_NETWORK,
+ .res_id = FRSH_NETPF_ITEM,
+ .admission_test = admission_test,
+ .priv = NULL,
+};
+
+static const struct forb_fres_item_scheduler_impl item_scheduler_impl = {
+ .add_nodes = add_nodes,
+ .del_nodes = del_nodes,
+ .get_data = get_data,
+};
+
+struct item_status item_status;
+
+int main(int argc, char *argv[])
+{
+ forb_orb orb;
+ int ret;
+ forb_executor_t executor;
+ fres_resource_manager frm;
+ fres_item_scheduler fis;
+ struct frm_data frm_data;
+
+ //ITEM ADD
+ pthread_t threadRead;
+ char device[] ="/dev/ttyUSB0";
+ char platform[]="telosb";
+ char *parametrsITEM[] ={NULL,device,platform};
+
+ forb_init_attr_t attr = { .orb_id = "org.frescor.frm.item" };
+ orb = forb_init(&argc, &argv, &attr);
+ if (!orb) error(1, errno, "forb_init");
+
+
+ fres_block_register_item();
+
+
+ ret = forb_executor_init(&executor);
+ if (ret) error(1, errno, "forb_executor_init failed");
+
+
+ frm = frm_register(orb, &frm_data, &executor, &frm_item_desc);
+ if (!frm) {
+ error(1, errno, "frm_register failed");
+ }
+
+
+ fis = forb_fres_item_scheduler_new(orb, &item_scheduler_impl, &item_status);
+ if (!fis) error(1, errno, "forb_fres_item_scheduler_new failed");
+
+
+ ret = forb_register_reference(fis, "item_scheduler");
+ if (ret) error (1, errno, "Cannot register ITEM scheduler");
+
+
+ forb_executor_register_object(&executor, fis);
+
+
+ // ITEM ADD
+ threadRead = init(parametrsITEM);
+ //if (threadRead == NULL) error (1, errno, "Cannot run the ITEM PC Manager"); //TODO fix the worning
+
+
+ forb_executor_run(&executor);
+
+
+
+ return 0;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file item.h
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @author Jiri Trdlicka <trdlij1@fel.cvut.cz>
+ * @date Wed Feb 18 16:10:06 2009
+ *
+ * @brief ITEM resource declarations
+ *
+ *
+ */
+#ifndef ITEM_H
+#define ITEM_H
+
+#include <item_idl.h>
+#include <forb.h>
+#include <fcb.h>
+#include <fres_contract.h>
+#include <fres_container.h>
+
+int fres_block_register_item();
+int fra_item_init(void);
+int fra_item_receive(frsh_vres_id_t vres, unsigned char *data[]);
+
+/* Define fres_container_(add|get|del)_item_nodes. */
+FRES_CONTAINER_ACCESSOR(ITEM_NODES, item_nodes);
+
+/* Define fres_contract_(add|get|del)_item_nodes. */
+FRES_CONTRACT_ACCESSOR(item_nodes);
+
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file item_blocks.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Fri Oct 31 17:23:25 2008
+ *
+ * @brief Description of contract blocks specific to the ITEM resource.
+ */
+#include <item.h>
+#include <fres_container.h>
+
+static const struct fres_block_desc item_nodes_desc = {
+ .name = "item nodes",
+ .size = sizeof(fres_block_item_nodes),
+ .serialize = (fres_block_serialize_fnc_t*)fres_block_item_nodes_serialize,
+ .deserialize = (fres_block_deserialize_fnc_t*)fres_block_item_nodes_deserialize,
+ .duplicate = fres_block_duplicate_default
+};
+
+int fres_block_register_item()
+{
+ return fres_block_register(FRES_BLOCK_ITEM_NODES,
+ &item_nodes_desc);
+}
--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------------------- //
+// Copyright (C) 2006 - 2008 FRESCOR consortium partners: //
+// //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// Scuola Superiore Sant'Anna, ITALY //
+// Kaiserslautern University, GERMANY //
+// Univ. Politécnica Valencia, SPAIN //
+// Czech Technical University in Prague, CZECH REPUBLIC //
+// ENEA SWEDEN //
+// Thales Communication S.A. FRANCE //
+// Visual Tools S.A. SPAIN //
+// Rapita Systems Ltd UK //
+// Evidence ITALY //
+// //
+// See http://www.frescor.org for a link to partners' websites //
+// //
+// FRESCOR project (FP6/2005/IST/5-034026) is funded //
+// in part by the European Union Sixth Framework Programme //
+// The European Union is not liable of any use that may be //
+// made of this code. //
+// //
+// //
+// based on previous work (FSF) done in the FIRST project //
+// //
+// Copyright (C) 2005 Mälardalen University, SWEDEN //
+// Scuola Superiore S.Anna, ITALY //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// //
+// FSF API web pages: http:marte.unican.es/fsf/docs //
+// http:shark.sssup.it/contrib/first/docs/ //
+// //
+// This file is part of FORB (Frescor Object Request Broker) //
+// //
+// FORB is free software; you can redistribute it and/or modify it //
+// under terms of the GNU General Public License as published by the //
+// Free Software Foundation; either version 2, or (at your option) any //
+// later version. FORB is distributed in the hope that it will be //
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty //
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
+// General Public License for more details. You should have received a //
+// copy of the GNU General Public License along with FORB; see file //
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, //
+// Cambridge, MA 02139, USA. //
+// //
+// As a special exception, including FORB header files in a file, //
+// instantiating FORB generics or templates, or linking other files //
+// with FORB objects to produce an executable application, does not //
+// by itself cause the resulting executable application to be covered //
+// by the GNU General Public License. This exception does not //
+// however invalidate any other reasons why the executable file might be //
+// covered by the GNU Public License. //
+////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @file item_idl.idl
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Fri Oct 31 17:17:49 2008
+ *
+ * @brief
+ *
+ *
+ */
+module fres {
+ module item {
+ typedef unsigned long long node_mask;
+ typedef sequence<octet> data_seq;
+ interface scheduler {
+ /** Adds given nodes to network and stats receiving data from them */
+ long add_nodes(in node_mask mask);
+ /** Diconnectes given nodes from network and stops receiving data from them */
+ long del_nodes(in node_mask mask);
+ /** Returns last data received form the given nodes */
+ long get_data(in node_mask mask, out data_seq data);
+ };
+ };
+ module block {
+ module item {
+ struct nodes {
+ /** A bit set to 1 means we want to
+ * receive data from that node. */
+ fres::item::node_mask mask;
+ };
+ };
+ };
+};
--- /dev/null
+#include <item.h>
+#include <ul_log.h>
+#include <fra_generic.h>
+#include <stdio.h>
+#include <frsh_distributed.h>
+
+UL_LOG_CUST(ulogd_frs_item);
+ul_log_domain_t ulogd_frs_item = {UL_LOGL_MSG, "frs_item"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(frs_item_logreg_domains, ulogd_frs_item);
+
+struct item {
+ fres_item_scheduler scheduler;
+};
+
+static int create_vres(fres_vres_t *vres, void *priv)
+{
+ struct item *item = priv;
+ fres_block_item_nodes *nodes;
+ CORBA_Environment env;
+ int ret;
+
+ nodes = fres_contract_get_item_nodes(vres->new);
+ if (!nodes) return FRES_ERR_NEEDS_MORE_DATA_IN_CONTRACT;
+
+ ret = fres_item_scheduler_add_nodes(item->scheduler, nodes->mask, &env);
+ if (forb_exception_occurred(&env)) return FRES_ERR_FORB_EXCEPTION;
+ if (ret) return ret;
+ return 0;
+}
+
+static int cancel_vres(fres_vres_t *vres, void *priv)
+{
+ struct item *item = priv;
+ fres_block_item_nodes *nodes;
+ CORBA_Environment env;
+ int ret;
+
+ nodes = fres_contract_get_item_nodes(vres->allocated);
+ if (!nodes) return FRES_ERR_NEEDS_MORE_DATA_IN_CONTRACT;
+
+ ret = fres_item_scheduler_del_nodes(item->scheduler, nodes->mask, &env);
+ if (forb_exception_occurred(&env)) return FRES_ERR_FORB_EXCEPTION;
+ if (ret) return ret;
+ return 0;
+}
+
+static int change_vres(fres_vres_t *vres, void *priv)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+
+
+static struct item item;
+
+static struct fres_allocator item_allocator = {
+ .res_type = FRSH_RT_NETWORK,
+ .res_id = FRSH_NETPF_ITEM,
+ /* Here we are using the "simple interface" */
+ .create_vres = create_vres,
+ .cancel_vres = cancel_vres,
+ .change_vres = change_vres,
+ .priv = &item
+};
+
+int fra_item_init(forb_orb orb, fres_contract_broker fcb, forb_executor_t *executor)
+{
+ fres_block_register_item();
+
+ item.scheduler = forb_resolve_reference(orb, "item_scheduler");
+ if (!item.scheduler) {
+ ul_logerr("forb_resolve_reference(item_scheduler) failed\n");
+ return errno;
+ }
+ return fra_register(orb, fcb, executor, &item_allocator);
+}
+
+/**
+ * Receives data from sensor network.
+ *
+ * @param[in] vres
+ *
+ * @param[out] data Where to store pointer to the array with received
+ * data. The programmer should free the returned array via
+ * forb_free(), when the data are not needed anymore.
+ *
+ * @return Number of elements returned in @a data array, -1 on error.
+ */
+int fra_item_receive(frsh_vres_id_t vres, unsigned *data[])
+{
+ fres_item_data_seq *seq;
+ fres_block_item_nodes *nodes;
+ int ret;
+ CORBA_Environment env;
+
+ nodes = fres_contract_get_item_nodes(vres->allocated);
+ if (!nodes) return FRES_ERR_NEEDS_MORE_DATA_IN_CONTRACT;
+
+ fres_item_scheduler_get_data(item.scheduler, nodes->mask, &seq, &env);
+ CORBA_sequence_set_release(seq, CORBA_FALSE);
+ ret = seq->_length;
+ *data = seq->_buffer;
+ forb_free(seq);
+ return ret;
+}
--- /dev/null
+/**
+ * @file frm_item.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Thu Nov 6 17:21:48 2008
+ *
+ * @brief Resource manager for ITEM protocol
+ *
+ *
+ */
+#include <frm_generic.h>
+#include <forb.h>
+#include <error.h>
+#include <errno.h>
+#include <fres_sa_scenario.h>
+#include <stdbool.h>
+#include <ul_log.h>
+#include <stdio.h>
+#include <frsh_distributed.h>
+#include <item.h>
+
+//ITEM ADD
+#include "FWSN.h"
+
+
+
+static inline bool node_present(fres_item_node_mask nodes, int node)
+{
+ return (nodes & (1LL<<node)) != 0;
+}
+
+static inline void node_add(fres_item_node_mask *nodes, int node)
+{
+ *nodes |= (1LL<<node);
+}
+
+static inline void node_del(fres_item_node_mask *nodes, int node)
+{
+ *nodes &= (~(1LL<<node));
+}
+
+static int
+admission_test(struct fres_sa_scenario *scenario, void *priv, bool *schedulable)
+{
+ struct fres_sa_contract *c;
+ fres_item_node_mask all_nodes;
+ frsh_rel_time_t min_deadline = fosa_msec_to_rel_time(0);
+
+ /* Find communicating nodes and the most restricting deadline */
+ all_nodes = 0;
+ fres_sa_scenario_for_each_contract(scenario, c) {
+ fres_block_item_nodes *nodes;
+ fosa_rel_time_t deadline;
+
+ nodes = fres_contract_get_item_nodes(c->contract);
+ if (!nodes) return FRES_ERR_NEEDS_MORE_DATA_IN_CONTRACT;
+ all_nodes |= nodes->mask;
+
+ if (fres_contract_get_deadline(&c->contract, &deadline)) {
+ if (fosa_rel_time_is_null(min_deadline) ||
+ fosa_rel_time_smaller(deadline, min_deadline)) {
+ min_deadline = deadline;
+ }
+ }
+ }
+
+ if (!fosa_rel_time_is_null(min_deadline)) {
+ /* TODO: Compare number of nodes and min_deadline */
+ *schedulable = false;
+ } else {
+ //ITEM ADD
+ int i;
+ int count_nodes;
+ int free_slots;
+ count_nodes = 0;
+ for (i = 0; i <= sizeof(all_nodes)-1; i++)
+ {
+ count_nodes = count_nodes + all_nodes(i);
+ }
+ free_slots = noOfFreeSlots(min_deadline);
+ if (free_slots < 0)
+ *schedulable = false; // adding of new nodes in action or the actual period is higher then the minimum demanded one.
+ else
+ {
+ if (free_slots < count_nodes)
+ *schedulable = false; // too much nodes are demanded
+ }
+
+ *schedulable = true;
+ }
+
+ return 0;
+}
+
+struct item_status {
+ /** Specifies how many applications want to read from a which
+ * node */
+ int node_requested[64];
+};
+
+CORBA_long
+add_nodes(fres_item_scheduler obj, const fres_item_node_mask mask, CORBA_Environment *ev)
+{
+ int node;
+ struct item_status *item_status = (struct item_status*)forb_instance_data(obj);
+
+ for (node=2; node<64; node++) {
+ if (node_present(mask, node)) {
+ if (item_status->node_requested[node] == 0)
+ {
+ /* TODO: Add node */
+ addDevice(node); //ITEM ADD
+
+ }
+ item_status->node_requested[node]++;
+ }
+ }
+ return /* TODO */ 0;
+}
+
+CORBA_long
+del_nodes(fres_item_scheduler obj, const fres_item_node_mask mask, CORBA_Environment *ev)
+{
+ struct item_status *item_status = (struct item_status*)forb_instance_data(obj);
+ int node;
+
+ for (node=2; node<64; node++) {
+ if (node_present(mask, node)) {
+ item_status->node_requested[node]--;
+ if (item_status->node_requested[node] == 0)
+ {
+ /* TODO: Remove node */
+ removeDevice(node); //ITEM ADD
+ }
+ }
+ }
+ return 0;
+}
+
+CORBA_long
+get_data(fres_item_scheduler obj, const fres_item_node_mask mask, fres_item_data_seq** data, CORBA_Environment *ev)
+{
+ //struct item_status *item_status = (struct item_status*)forb_instance_data(obj);
+ /* TODO: */
+ return 0;
+}
+
+static const struct fres_res_manager frm_item_desc = {
+ .res_type = FRSH_RT_NETWORK,
+ .res_id = FRSH_NETPF_ITEM,
+ .admission_test = admission_test,
+ .priv = NULL,
+};
+
+static const struct forb_fres_item_scheduler_impl item_scheduler_impl = {
+ .add_nodes = add_nodes,
+ .del_nodes = del_nodes,
+ .get_data = get_data,
+};
+
+struct item_status item_status;
+
+int main(int argc, char *argv[])
+{
+ forb_orb orb;
+ int ret;
+ forb_executor_t executor;
+ fres_resource_manager frm;
+ fres_item_scheduler fis;
+ struct frm_data frm_data;
+//ITEM ADD
+ pthread_t threadRead;
+ char device[] ="/dev/ttyUSB0";
+ char platform[]="telosb";
+ char *parametrsITEM[] ={NULL,device,platform};
+
+
+ orb = forb_init(&argc, &argv, "frm_item");
+ if (!orb) error(1, errno, "forb_init");
+
+ fres_block_register_item();
+
+ ret = forb_executor_init(&executor);
+ if (ret) error(1, errno, "forb_executor_init failed");
+
+ frm = frm_register(orb, &frm_data, &executor, &frm_item_desc);
+ if (!frm) {
+ error(1, errno, "frm_register failed");
+ }
+
+ fis = forb_fres_item_scheduler_new(orb, &item_scheduler_impl, &item_status);
+ if (!fis) error(1, errno, "forb_fres_item_scheduler_new failed");
+
+ ret = forb_register_reference(fis, "item_scheduler");
+ if (ret) error (1, errno, "Cannot register ITEM scheduler");
+
+ forb_executor_register_object(&executor, fis);
+
+ forb_executor_run(&executor);
+
+
+// ITEM ADD
+ threadRead = init(parametrsITEM);
+ if (threadRead == NULL) error (1, errno, "Cannot run the ITEM PC Manager");
+
+
+
+ return 0;
+}
--- /dev/null
+/**
+ * This file is automatically generated by ncg. DO NOT EDIT THIS FILE.
+ * It includes values of some nesC constants from
+ * /opt/tinyos-2.x/tos/lib/serial/Serial.h.
+ */
+
+enum {
+ SERIAL_HDLC_CTLESC_BYTE = 125,
+ SERIAL_TOS_SERIAL_802_15_4_ID = 2,
+ SERIAL_SERIAL_PROTO_ACK = 67,
+ SERIAL_TOS_SERIAL_CC1000_ID = 1,
+ SERIAL_SERIAL_PROTO_PACKET_NOACK = 69,
+ SERIAL_SERIAL_PROTO_PACKET_UNKNOWN = 255,
+ SERIAL_HDLC_FLAG_BYTE = 126,
+ SERIAL_TOS_SERIAL_ACTIVE_MESSAGE_ID = 0,
+ SERIAL_TOS_SERIAL_UNKNOWN_ID = 255,
+ SERIAL_SERIAL_PROTO_PACKET_ACK = 68
+};
--- /dev/null
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <termios.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/time.h>
+#include <stdio.h>
+#ifdef __CYGWIN__
+#include <windows.h>
+#include <io.h>
+#else
+#include <stdint.h>
+#endif
+
+/* C implementation of the mote serial protocol. See
+ net.tinyos.packet.Packetizer for more details */
+
+#undef DEBUG
+
+#include "serialsource.h"
+#include "serialprotocol.h"
+
+typedef int bool;
+
+enum {
+#ifndef __CYGWIN__
+ FALSE = 0,
+ TRUE = 1,
+#endif
+ BUFSIZE = 256,
+ MTU = 256,
+ ACK_TIMEOUT = 1000000, /* in us */
+ SYNC_BYTE = SERIAL_HDLC_FLAG_BYTE,
+ ESCAPE_BYTE = SERIAL_HDLC_CTLESC_BYTE,
+
+ P_ACK = SERIAL_SERIAL_PROTO_ACK,
+ P_PACKET_ACK = SERIAL_SERIAL_PROTO_PACKET_ACK,
+ P_PACKET_NO_ACK = SERIAL_SERIAL_PROTO_PACKET_NOACK,
+ P_UNKNOWN = SERIAL_SERIAL_PROTO_PACKET_UNKNOWN
+};
+
+struct packet_list
+{
+ uint8_t *packet;
+ int len;
+ struct packet_list *next;
+};
+
+struct serial_source {
+ int fd;
+ bool non_blocking;
+ void (*message)(serial_source_msg problem);
+
+ /* Receive state */
+ struct {
+ uint8_t buffer[BUFSIZE];
+ int bufpos, bufused;
+ uint8_t packet[MTU];
+ bool in_sync, escaped;
+ int count;
+ struct packet_list *queue[256]; // indexed by protocol
+ } recv;
+ struct {
+ uint8_t seqno;
+ uint8_t *escaped;
+ int escapeptr;
+ uint16_t crc;
+ } send;
+};
+
+static tcflag_t parse_baudrate(int requested)
+{
+ int baudrate;
+
+ switch (requested)
+ {
+#ifdef B50
+ case 50: baudrate = B50; break;
+#endif
+#ifdef B75
+ case 75: baudrate = B75; break;
+#endif
+#ifdef B110
+ case 110: baudrate = B110; break;
+#endif
+#ifdef B134
+ case 134: baudrate = B134; break;
+#endif
+#ifdef B150
+ case 150: baudrate = B150; break;
+#endif
+#ifdef B200
+ case 200: baudrate = B200; break;
+#endif
+#ifdef B300
+ case 300: baudrate = B300; break;
+#endif
+#ifdef B600
+ case 600: baudrate = B600; break;
+#endif
+#ifdef B1200
+ case 1200: baudrate = B1200; break;
+#endif
+#ifdef B1800
+ case 1800: baudrate = B1800; break;
+#endif
+#ifdef B2400
+ case 2400: baudrate = B2400; break;
+#endif
+#ifdef B4800
+ case 4800: baudrate = B4800; break;
+#endif
+#ifdef B9600
+ case 9600: baudrate = B9600; break;
+#endif
+#ifdef B19200
+ case 19200: baudrate = B19200; break;
+#endif
+#ifdef B38400
+ case 38400: baudrate = B38400; break;
+#endif
+#ifdef B57600
+ case 57600: baudrate = B57600; break;
+#endif
+#ifdef B115200
+ case 115200: baudrate = B115200; break;
+#endif
+#ifdef B230400
+ case 230400: baudrate = B230400; break;
+#endif
+#ifdef B460800
+ case 460800: baudrate = B460800; break;
+#endif
+#ifdef B500000
+ case 500000: baudrate = B500000; break;
+#endif
+#ifdef B576000
+ case 576000: baudrate = B576000; break;
+#endif
+#ifdef B921600
+ case 921600: baudrate = B921600; break;
+#endif
+#ifdef B1000000
+ case 1000000: baudrate = B1000000; break;
+#endif
+#ifdef B1152000
+ case 1152000: baudrate = B1152000; break;
+#endif
+#ifdef B1500000
+ case 1500000: baudrate = B1500000; break;
+#endif
+#ifdef B2000000
+ case 2000000: baudrate = B2000000; break;
+#endif
+#ifdef B2500000
+ case 2500000: baudrate = B2500000; break;
+#endif
+#ifdef B3000000
+ case 3000000: baudrate = B3000000; break;
+#endif
+#ifdef B3500000
+ case 3500000: baudrate = B3500000; break;
+#endif
+#ifdef B4000000
+ case 4000000: baudrate = B4000000; break;
+#endif
+ default:
+ baudrate = 0;
+ }
+ return baudrate;
+}
+
+#ifdef DEBUG
+static void dump(const char *msg, unsigned char *packet, int len)
+{
+ int i;
+
+ printf("%s", msg);
+ for (i = 0; i < len; i++)
+ printf(" %02x", packet[i]);
+ putchar('\n');
+}
+#endif
+
+static void message(serial_source src, serial_source_msg msg)
+{
+ if (src->message)
+ src->message(msg);
+}
+
+static int serial_read(serial_source src, int non_blocking, void *buffer, int n)
+{
+ fd_set fds;
+ int cnt;
+
+ if (non_blocking)
+ {
+ cnt = read(src->fd, buffer, n);
+
+ /* Work around buggy usb serial driver (returns 0 when no data
+ is available). Mac OS X seems to like to do this too (at
+ least with a Keyspan 49WG).
+ */
+ if (cnt == 0)
+ {
+ cnt = -1;
+ errno = EAGAIN;
+ }
+ return cnt;
+ }
+ else
+ for (;;)
+ {
+ FD_ZERO(&fds);
+ FD_SET(src->fd, &fds);
+ cnt = select(src->fd + 1, &fds, NULL, NULL, NULL);
+ if (cnt < 0)
+ return -1;
+
+ cnt = read(src->fd, buffer, n);
+ if (cnt != 0)
+ return cnt;
+ }
+}
+
+serial_source open_serial_source(const char *device, int baud_rate,
+ int non_blocking,
+ void (*message)(serial_source_msg problem))
+/* Effects: opens serial port device at specified baud_rate. If non_blocking
+ is true, read_serial_packet calls will be non-blocking (writes are
+ always blocking, for now at least)
+ Returns: descriptor for serial forwarder at host:port, or
+ NULL for failure (bad device or bad baud rate)
+ */
+{
+ struct termios newtio;
+ int fd;
+ tcflag_t baudflag = parse_baudrate(baud_rate);
+
+ if (!baudflag)
+ return NULL;
+
+ fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK);
+ if (fd < 0)
+ return NULL;
+
+#ifdef __CYGWIN__
+ /* For some very mysterious reason, this incantation is necessary to make
+ the serial port work under some windows machines */
+ HANDLE handle = (HANDLE)get_osfhandle(fd);
+ DCB dcb;
+ if (!(GetCommState(handle, &dcb) && SetCommState(handle, &dcb)))
+ {
+ close(fd);
+ return NULL;
+ }
+#endif
+ /* Serial port setting */
+ memset(&newtio, 0, sizeof(newtio));
+ newtio.c_cflag = CS8 | CLOCAL | CREAD;
+ newtio.c_iflag = IGNPAR | IGNBRK;
+ cfsetispeed(&newtio, baudflag);
+ cfsetospeed(&newtio, baudflag);
+
+ /* Raw output_file */
+ newtio.c_oflag = 0;
+
+ if (tcflush(fd, TCIFLUSH) >= 0 &&
+ tcsetattr(fd, TCSANOW, &newtio) >= 0)
+ {
+ serial_source src = malloc(sizeof *src);
+
+ if (src)
+ {
+ memset(src, 0, sizeof *src);
+ src->fd = fd;
+ src->non_blocking = non_blocking;
+ src->message = message;
+ src->send.seqno = 37;
+
+ return src;
+ }
+ }
+ close(fd);
+
+ return NULL;
+}
+
+int serial_source_fd(serial_source src)
+/* Returns: the file descriptor used by serial source src (useful when
+ non-blocking reads were requested)
+*/
+{
+ return src->fd;
+}
+
+int close_serial_source(serial_source src)
+/* Effects: closes serial source src
+ Returns: 0 if successful, -1 if some problem occured (but source is
+ considered closed anyway)
+ */
+{
+ int ok = close(src->fd);
+
+ free(src);
+
+ return ok;
+}
+
+static int source_wait(serial_source src, struct timeval *deadline)
+/* Effects: waits until deadline for some data on source. deadline
+ can be NULL for indefinite waiting.
+ Returns: 0 if data is available, -1 if the deadline expires
+*/
+{
+ struct timeval tv;
+ fd_set fds;
+ int cnt;
+
+ if (src->recv.bufpos < src->recv.bufused)
+ return 0;
+
+ for (;;)
+ {
+ if (deadline)
+ {
+ gettimeofday(&tv, NULL);
+ tv.tv_sec = deadline->tv_sec - tv.tv_sec;
+ tv.tv_usec = deadline->tv_usec - tv.tv_usec;
+ if (tv.tv_usec < 0)
+ {
+ tv.tv_usec += 1000000;
+ tv.tv_sec--;
+ }
+ if (tv.tv_sec < 0)
+ return -1;
+ }
+
+ FD_ZERO(&fds);
+ FD_SET(src->fd, &fds);
+ cnt = select(src->fd + 1, &fds, NULL, NULL, deadline ? &tv : NULL);
+ if (cnt < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ message(src, msg_unix_error);
+ return -1;
+ }
+ if (cnt == 0)
+ return -1;
+ return 0;
+ }
+}
+
+static int source_write(serial_source src, const void *buffer, int count)
+{
+ int actual = 0;
+
+ if (fcntl(src->fd, F_SETFL, 0) < 0)
+ {
+ message(src, msg_unix_error);
+ return -1;
+ }
+ while (count > 0)
+ {
+ int n = write(src->fd, buffer, count);
+
+ if (n < 0 && errno == EINTR)
+ continue;
+ if (n < 0)
+ {
+ message(src, msg_unix_error);
+ actual = -1;
+ break;
+ }
+
+ count -= n;
+ actual += n;
+ buffer += n;
+ }
+ if (fcntl(src->fd, F_SETFL, O_NONBLOCK) < 0)
+ {
+ message(src, msg_unix_error);
+ /* We're in trouble, but there's no obvious fix. */
+ }
+ return actual;
+}
+
+static void push_protocol_packet(serial_source src,
+ uint8_t type, uint8_t *packet, uint8_t len)
+{
+ /* I'm assuming short queues */
+ struct packet_list *entry = malloc(sizeof *entry), **last;
+
+ if (!entry)
+ {
+ message(src, msg_no_memory);
+ free(packet);
+ return;
+ }
+
+ entry->packet = packet;
+ entry->len = len;
+ entry->next = NULL;
+
+ last = &src->recv.queue[type];
+ while (*last)
+ last = &(*last)->next;
+ *last = entry;
+}
+
+static struct packet_list *pop_protocol_packet(serial_source src, uint8_t type)
+{
+ struct packet_list *entry = src->recv.queue[type];
+
+ if (entry)
+ src->recv.queue[type] = entry->next;
+
+ return entry;
+}
+
+static bool packet_available(serial_source src, uint8_t type)
+{
+ return src->recv.queue[type] != NULL;
+}
+
+int serial_source_empty(serial_source src)
+/* Returns: true if serial source does not contain any pending data, i.e.,
+ if the result is true and there is no data available on the source's
+ file descriptor, then read_serial_packet will:
+ - return NULL if the source is non-blocking
+ - block if it is blocking
+
+ (Note: the presence of this calls allows the serial_source to do some
+ internal buffering)
+*/
+{
+ return src->recv.bufpos >= src->recv.bufused &&
+ !packet_available(src, P_PACKET_NO_ACK);
+}
+
+/* Slow implementation of crc function */
+static uint16_t crc_byte(uint16_t crc, uint8_t b)
+{
+ uint8_t i;
+
+ crc = crc ^ b << 8;
+ i = 8;
+ do
+ if (crc & 0x8000)
+ crc = crc << 1 ^ 0x1021;
+ else
+ crc = crc << 1;
+ while (--i);
+
+ return crc;
+}
+
+static uint16_t crc_packet(uint8_t *data, int len)
+{
+ uint16_t crc = 0;
+
+ while (len-- > 0)
+ crc = crc_byte(crc, *data++);
+
+ return crc;
+}
+
+static int read_byte(serial_source src, int non_blocking)
+/* Returns: next byte (>= 0), or -1 if no data available and non-blocking is true.
+*/
+{
+ if (src->recv.bufpos >= src->recv.bufused)
+ {
+ for (;;)
+ {
+ int n = serial_read(src, non_blocking, src->recv.buffer, sizeof src->recv.buffer);
+
+ if (n == 0) /* Can't occur because of serial_read bug workaround */
+ {
+ message(src, msg_closed);
+ return -1;
+ }
+ if (n > 0)
+ {
+#ifdef DEBUG
+ dump("raw", src->recv.buffer, n);
+#endif
+ src->recv.bufpos = 0;
+ src->recv.bufused = n;
+ break;
+ }
+ if (errno == EAGAIN)
+ return -1;
+ if (errno != EINTR)
+ message(src, msg_unix_error);
+ }
+ }
+ //printf("in %02x\n", src->recv.buffer[src->recv.bufpos]);
+ return src->recv.buffer[src->recv.bufpos++];
+}
+
+static void process_packet(serial_source src, uint8_t *packet, int len);
+static int write_framed_packet(serial_source src,
+ uint8_t packet_type, uint8_t first_byte,
+ const uint8_t *packet, int count);
+
+static void read_and_process(serial_source src, int non_blocking)
+/* Effects: reads and processes up to one packet.
+*/
+{
+ uint8_t *packet = src->recv.packet;
+
+ for (;;)
+ {
+ int byte = read_byte(src, non_blocking);
+
+ if (byte < 0)
+ return;
+
+ if (!src->recv.in_sync)
+ {
+ if (byte == SYNC_BYTE)
+ {
+ src->recv.in_sync = TRUE;
+ message(src, msg_sync);
+ src->recv.count = 0;
+ src->recv.escaped = FALSE;
+ }
+ continue;
+ }
+ if (src->recv.count >= MTU)
+ {
+ message(src, msg_too_long);
+ src->recv.in_sync = FALSE;
+ continue;
+ }
+ if (src->recv.escaped)
+ {
+ if (byte == SYNC_BYTE)
+ {
+ /* sync byte following escape is an error, resync */
+ message(src, msg_bad_sync);
+ src->recv.in_sync = FALSE;
+ continue;
+ }
+ byte ^= 0x20;
+ src->recv.escaped = FALSE;
+ }
+ else if (byte == ESCAPE_BYTE)
+ {
+ src->recv.escaped = TRUE;
+ continue;
+ }
+ else if (byte == SYNC_BYTE)
+ {
+ int count = src->recv.count;
+ uint8_t *received;
+ uint16_t read_crc, computed_crc;
+
+ src->recv.count = 0; /* ready for next packet */
+
+ if (count < 4)
+ /* frames that are too small are ignored */
+ continue;
+
+ received = malloc(count - 2);
+ if (!received)
+ {
+ message(src, msg_no_memory);
+ continue;
+ }
+ memcpy(received, packet, count - 2);
+
+ read_crc = packet[count - 2] | packet[count - 1] << 8;
+ computed_crc = crc_packet(received, count - 2);
+
+#ifdef DEBUG
+ dump("received", packet, count);
+ printf(" crc %x comp %x\n", read_crc, computed_crc);
+#endif
+ if (read_crc == computed_crc)
+ {
+ process_packet(src, received, count - 2);
+ return; /* give rest of world chance to do something */
+ }
+ else
+ {
+ message(src, msg_bad_crc);
+ free(received);
+ /* We don't lose sync here. If we did, garbage on the line
+ at startup will cause loss of the first packet. */
+ continue;
+ }
+ }
+ packet[src->recv.count++] = byte;
+ }
+}
+
+static void process_packet(serial_source src, uint8_t *packet, int len)
+{
+ int packet_type = packet[0], offset = 1;
+
+ if (packet_type == P_PACKET_ACK)
+ {
+ /* send ack */
+ write_framed_packet(src, P_ACK, packet[1], NULL, 0);
+ /* And merge with un-acked packets */
+ packet_type = P_PACKET_NO_ACK;
+ offset = 2;
+ }
+ /* packet must remain a valid pointer to pass to free. So we move the
+ data rather than pass an internal pointer */
+ memmove(packet, packet + offset, len - offset);
+ push_protocol_packet(src, packet_type, packet, len - offset);
+}
+
+void *read_serial_packet(serial_source src, int *len)
+/* Effects: Read the serial source src. If a packet is available, return it.
+ If in blocking mode and no packet is available, wait for one.
+ Returns: the packet read (in newly allocated memory), with *len is
+ set to the packet length, or NULL if no packet is yet available and
+ the serial source is in non-blocking mode
+*/
+{
+ read_and_process(src, TRUE);
+ for (;;)
+ {
+ struct packet_list *entry;
+
+ entry = pop_protocol_packet(src, P_PACKET_NO_ACK);
+ if (entry)
+ {
+ uint8_t *packet = entry->packet;
+
+ *len = entry->len;
+ free(entry);
+
+ return packet;
+ }
+ if (src->non_blocking && serial_source_empty(src))
+ return NULL;
+ source_wait(src, NULL);
+ read_and_process(src, src->non_blocking);
+ }
+}
+
+/* The escaper does the sync bytes+escape-like encoding+crc of packets */
+
+static void escape_add(serial_source src, uint8_t b)
+{
+ src->send.escaped[src->send.escapeptr++] = b;
+}
+
+static int init_escaper(serial_source src, int count)
+{
+ src->send.escaped = malloc(count * 2 + 2);
+ if (!src->send.escaped)
+ {
+ message(src, msg_no_memory);
+ return -1;
+ }
+ src->send.escapeptr = 0;
+ src->send.crc = 0;
+
+ escape_add(src, SYNC_BYTE);
+
+ return 0;
+}
+
+static void terminate_escaper(serial_source src)
+{
+ escape_add(src, SYNC_BYTE);
+}
+
+static void escape_byte(serial_source src, uint8_t b)
+{
+ src->send.crc = crc_byte(src->send.crc, b);
+ if (b == SYNC_BYTE || b == ESCAPE_BYTE)
+ {
+ escape_add(src, ESCAPE_BYTE);
+ escape_add(src, b ^ 0x20);
+ }
+ else
+ escape_add(src, b);
+}
+
+static void free_escaper(serial_source src)
+{
+ free(src->send.escaped);
+}
+
+// Write a packet of type 'packetType', first byte 'firstByte'
+// and bytes 2..'count'+1 in 'packet'
+static int write_framed_packet(serial_source src,
+ uint8_t packet_type, uint8_t first_byte,
+ const uint8_t *packet, int count)
+{
+ int i, crc;
+
+#ifdef DEBUG
+ printf("writing %02x %02x", packet_type, first_byte);
+ dump("", packet, count);
+#endif
+
+ if (init_escaper(src, count + 4) < 0)
+ return -1;
+
+ escape_byte(src, packet_type);
+ escape_byte(src, first_byte);
+ for (i = 0; i < count; i++)
+ escape_byte(src, packet[i]);
+
+ crc = src->send.crc;
+ escape_byte(src, crc & 0xff);
+ escape_byte(src, crc >> 8);
+
+ terminate_escaper(src);
+
+#ifdef DEBUG
+ dump("encoded", src->send.escaped, src->send.escapeptr);
+#endif
+
+ if (source_write(src, src->send.escaped, src->send.escapeptr) < 0)
+ {
+ free_escaper(src);
+ return -1;
+ }
+ free_escaper(src);
+ return 0;
+}
+
+static void add_timeval(struct timeval *tv, long us)
+/* Specialised for this app */
+{
+ tv->tv_sec += us / 1000000;
+ tv->tv_usec += us % 1000000;
+ if (tv->tv_usec > 1000000)
+ {
+ tv->tv_usec -= 1000000;
+ tv->tv_sec++;
+ }
+}
+
+int write_serial_packet(serial_source src, const void *packet, int len)
+/* Effects: writes len byte packet to serial source src
+ Returns: 0 if packet successfully written, 1 if successfully written
+ but not acknowledged, -1 otherwise
+*/
+{
+ struct timeval deadline;
+
+ src->send.seqno++;
+ if (write_framed_packet(src, P_PACKET_ACK, src->send.seqno, packet, len) < 0)
+ return -1;
+
+ gettimeofday(&deadline, NULL);
+ add_timeval(&deadline, ACK_TIMEOUT);
+ for (;;)
+ {
+ struct packet_list *entry;
+
+ read_and_process(src, TRUE);
+ entry = pop_protocol_packet(src, P_ACK);
+ if (entry)
+ {
+ uint8_t acked = entry->packet[0];
+
+ free(entry->packet);
+ free(entry);
+ if (acked == src->send.seqno)
+ return 0;
+ }
+ else if (source_wait(src, &deadline) < 0)
+ return 1;
+ }
+}
+
+/* This somewhat convoluted code allows us to use a common baudrate table
+ with the Java code. This could be improved if we generated the Java
+ code from a common table.
+*/
+
+struct pargs {
+ char *name;
+ int rate;
+};
+
+static void padd(struct pargs *args, const char *name, int baudrate)
+{
+ if (!strcmp(args->name, name))
+ args->rate = baudrate;
+}
+
+static void init(void) { }
+
+int platform_baud_rate(char *platform_name)
+/* Returns: The baud rate of the specified platform, or -1 for unknown
+ platforms
+*/
+{
+ /* The Java code looks like Platform.add(Platform.x, "name", baudrate);
+ Fake up some C stuff which will make that work right. */
+ struct pargs args;
+ struct {
+ void (*add)(struct pargs *args, const char *name, int baudrate);
+ struct pargs *x;
+ } Platform = { padd, &args };
+ static struct {
+ struct {
+ int packet;
+ } tinyos;
+ } net;
+
+ if (isdigit(platform_name[0]))
+ return atoi(platform_name);
+
+ args.name = platform_name;
+ args.rate = -1;
+
+#define class
+#define BaudRate
+#define static
+#define void
+#define throws ;
+#define Exception
+#define package
+#include "./BaudRate.java"
+
+ return args.rate;
+}
--- /dev/null
+#ifndef SERIALSOURCE_H
+#define SERIALSOURCE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct serial_source *serial_source;
+
+typedef enum {
+ msg_unknown_packet_type, /* packet of unknown type received */
+ msg_ack_timeout, /* ack not received within timeout */
+ msg_sync, /* sync achieved */
+ msg_too_long, /* greater than MTU (256 bytes) */
+ msg_too_short, /* less than 4 bytes */
+ msg_bad_sync, /* unexpected sync byte received */
+ msg_bad_crc, /* received packet has bad crc */
+ msg_closed, /* serial port closed itself */
+ msg_no_memory, /* malloc failed */
+ msg_unix_error /* check errno for details */
+} serial_source_msg;
+
+serial_source open_serial_source(const char *device, int baud_rate,
+ int non_blocking,
+ void (*message)(serial_source_msg problem));
+/* Effects: opens serial port device at specified baud_rate. If non_blocking
+ is true, read_serial_packet calls will be non-blocking (writes are
+ always blocking, for now at least)
+ If non-null, message will be called to signal various problems during
+ execution.
+ Returns: descriptor for serial forwarder at host:port, or
+ NULL for failure
+ */
+
+int serial_source_fd(serial_source src);
+/* Returns: the file descriptor used by serial source src (useful when
+ non-blocking reads were requested)
+*/
+
+int serial_source_empty(serial_source src);
+/* Returns: true if serial source does not contain any pending data, i.e.,
+ if the result is true and there is no data available on the source's
+ file descriptor, then read_serial_packet will:
+ - return NULL if the source is non-blocking
+ - block if it is blocking
+
+ (Note: the presence of this calls allows the serial_source to do some
+ internal buffering)
+*/
+
+int close_serial_source(serial_source src);
+/* Effects: closes serial source src
+ Returns: 0 if successful, -1 if some problem occured (but source is
+ considered closed anyway)
+ */
+
+void *read_serial_packet(serial_source src, int *len);
+/* Effects: Read the serial source src. If a packet is available, return it.
+ If in blocking mode and no packet is available, wait for one.
+ Returns: the packet read (in newly allocated memory), with *len is
+ set to the packet length, or NULL if no packet is yet available and
+ the serial source is in non-blocking mode
+*/
+
+int write_serial_packet(serial_source src, const void *packet, int len);
+/* Effects: writes len byte packet to serial source src
+ Returns: 0 if packet successfully written, 1 if successfully written
+ but not acknowledged, -1 otherwise
+*/
+
+int platform_baud_rate(char *platform_name);
+/* Returns: The baud rate of the specified platform, or -1 for unknown
+ platforms. If platform_name starts with a digit, just return
+ atoi(platform_name).
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+test_PROGRAMS += test_item
+test_item_SOURCES = test_item.c
+lib_LOADLIBES += pthread rt frsh
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file test_item.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Wed Feb 18 16:11:34 2009
+ *
+ * @brief Test for ITEM WSN resource
+ *
+ *
+ */
+
+
+#include <frsh.h>
+#include <error.h>
+#include <item.h>
+#include <fres_contract.h>
+
+//ITEM ADD
+//#include "FWSN.h"
+
+#if 1
+#define N 4
+int contract_deadline_sec[N] = { 4,4,4,4 };
+int contract_nodes[N] = { 0x04, 0x05, 0x02 ,0x03};
+#else
+#define N 3
+int contract_deadline_sec[N] = {2,2,2};
+int contract_nodes[N] = { 0x02,0x03,0x04};
+#endif
+int main(int argc, char *argv[])
+{
+ int ret;
+ frsh_contract_t contract[N];
+ frsh_vres_id_t vres[N];
+ int i;
+
+
+ ret = frsh_init();
+ if (ret) PERROR_AND_EXIT(ret, "frsh_init");
+
+ /* Negotiate N contracts */
+ for (i=0; i<N; i++) {
+ frsh_rel_time_t deadline;
+ fres_block_item_nodes *nodes;
+ ret = frsh_contract_init(&contract[i]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ /* Set resource */
+ ret = frsh_contract_set_resource_and_label(
+ &contract[i], FRSH_RT_NETWORK, FRSH_NETPF_ITEM, NULL);
+ if (ret) PERROR_AND_EXIT(ret, "Cannot set resource\n");
+
+ /* Set nodes we want to receive data from */
+ nodes = malloc(sizeof(*nodes));
+ if (!nodes) PERROR_AND_EXIT(errno, "malloc");
+ //nodes->mask = contract_nodes[i];
+
+ nodes->mask =1;
+ nodes->mask = nodes->mask << (contract_nodes[i]);
+
+
+ ret = fres_contract_add_item_nodes(contract[i], nodes);
+ if (ret) PERROR_AND_EXIT(ret, "Cannot add item_nodes block\n");
+
+ /* Set deadline */
+ deadline = fosa_msec_to_rel_time(contract_deadline_sec[i]*1000);
+ ret = frsh_contract_set_timing_reqs(&contract[i],
+ false, &deadline);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_timing_reqs");
+
+ /* Negotiate the contract */
+ ret = frsh_contract_negotiate(&contract[i], &vres[i]);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+ if (ret) printf(" \n frsh_contract_negotiate - NOT ACCEPTED \n");
+ }
+ printf("Contracts negotiated\n");
+
+ for (i=0; i<30; i++) {
+ //int j;
+ //printf("Reading data\n");
+ //for (j=0; j<N; j++) {
+ unsigned char *data;
+ int len;
+ // int k;
+ ret = fra_item_receive(vres[1], &data);
+ if (ret == -1) PERROR_AND_EXIT(errno, "frs_item_receive");
+ len = ret;
+
+ /* Do something with the received data */
+
+ /* printf("JOP 89 : %i - ",len);
+ for (k = 0; k < len-1; k++)
+ {
+ printf("%02x ", data[k]);
+ if (k%4 == 3)
+ printf(" | ");
+ }
+ putchar('\n');*/
+
+ int l;
+ int m;
+ for (l=1; l < len/4; l++)
+ {
+ for(m=1; m < 20; m++)
+ {
+ if (data[4*l-1] > 6*m) putchar('*');
+ else putchar(' ');
+ }
+ printf(" | ");
+ }
+ putchar('\n');
+
+ forb_free(data);
+ //}
+ sleep(1);
+ }
+
+ for (i=0; i<N; i++) {
+ frsh_contract_cancel(vres[i]);
+ }
+ return 0;
+}
--- /dev/null
+_build
+_compiled
+TAGS
+config.omk-default
+cscope.*
+*~
--- /dev/null
+_build
+_compiled
+TAGS
+config.omk-default
+cscope.*
+*~
--- /dev/null
+commit eb429599f8240a4a141aa02ba76066b96df5341c
+Merge: 8832dd6... 613a4c5...
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Mar 21 10:02:55 2008 +0100
+
+ Merge branch 'martin'
+
+commit 613a4c543c5a7c8cace599583f373bc66afbea80
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Mar 20 19:37:51 2008 +0100
+
+ Added agent and contract table locking
+
+commit c4c3ec3c573e07602681f3e2a192ea1343c10619
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Mar 20 19:01:43 2008 +0100
+
+ Added global agent_table variable and hence changed parameters of fwp_agent_atble functions
+
+commit 9c33faf6efe3b0c2de915ae2081a8d885726197c
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Mar 19 16:56:18 2008 +0100
+
+ Bug fixes
+
+commit 28c971e13430da37c08d8ea68982c798fde70e5a
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Mar 18 18:57:18 2008 +0100
+
+ Unulutizing fwp lib :-)
+
+commit 23cbe546255e63c5fc84e5d8a4c95c533c6112d8
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Mar 17 10:46:13 2008 +0100
+
+ Added fwp.h - library header file for user
+
+commit 3c0176151058c5869817972a5dd904a3c7d84bc2
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Mar 17 10:32:52 2008 +0100
+
+ fwp_proto moved to fwp_comm
+
+commit dff772bb588e0c7bf4d421f3436e7f3961eac9b9
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Mar 17 10:18:03 2008 +0100
+
+ Compilation fixes
+
+commit 3ce13aadcdd99d92c68237b0a45216e858234298
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Sun Mar 16 23:47:35 2008 +0100
+
+ the type changes of fwp vres and endpoint
+
+commit a90be451e06c736a243a38ee94ab9fa039b9b07d
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Mar 14 18:06:01 2008 +0100
+
+ Added fwp_types.h - defiens user types
+
+commit 6e644d1d9444cd9159c3c3babe797b950f18a4cd
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Mar 14 18:04:10 2008 +0100
+
+ WIP:Ulutizing fwp_vres and fwp_endpoint
+
+commit 6b6a258fc7e7a373992e54fa8da98cc70f20d811
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Mar 13 14:52:17 2008 +0100
+
+ Added appcall_id to msg header, fwp agent got simplified, removed forwarding table
+
+commit 3573e776ed210793d336de4f7922391957458a15
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Mar 11 17:47:06 2008 +0100
+
+ Compilation fixes
+
+commit 2c2b1a1764363bf7bd61ccc71ed69d3b9e9dc720
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Mar 10 12:42:30 2008 +0100
+
+ label changed to id
+
+commit 426fbdfc2dc2977025a399fcbd74ad201278cc39
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Mon Mar 10 01:52:38 2008 +0100
+
+ fwp_agent_table operations added
+
+commit 220aeda53a794fb6cce5f1d153b90c0634c022c3
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Mar 6 18:22:26 2008 +0100
+
+ Added aegnt table
+
+commit 6adbfaff1489729164ef224e14ce4f1dbd5e9d0c
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Wed Mar 5 01:05:53 2008 +0100
+
+ Stupid admctrl test integrated
+
+commit cf454896a3519da74f583b0aa40d7846ef9f8a84
+Merge: 34eb301... ed92819...
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Tue Mar 4 20:51:33 2008 +0100
+
+ Merge conflict resolved
+
+commit ed92819bae022eaa4a698051a017ca7076648996
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Mar 4 18:07:01 2008 +0100
+
+ ulutize fwp_contractbl
+
+commit 34eb301c01db63ecddbc13c49c32e3a8248a728b
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Mon Mar 3 01:05:40 2008 +0100
+
+ Revert "tial to ulutize contractbl"
+
+ This reverts commit 99685a757ddc777074888a0ef72890a70c4fe168.
+
+commit 99685a757ddc777074888a0ef72890a70c4fe168
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Mon Mar 3 01:00:25 2008 +0100
+
+ tial to ulutize contractbl
+
+commit b9332abfaa147ba287bd90ff928e4f8b50d9cd90
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Feb 29 11:12:33 2008 +0100
+
+ AdeUlut lib
+
+commit 9319620cba583f8a5e0d4eb3a6976f588f539008
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Feb 28 16:02:34 2008 +0100
+
+ Copy data passed in argument in fwp_send to msgb.
+
+commit fb4ea826583ce09aa5f73ab584ef70556e5e4092
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Feb 28 15:58:46 2008 +0100
+
+ Revert "Bug fixes in fwp_vres, budget mechanism modified. For testing purposes and easy testing , budget counts number of messages not bytes."
+
+ This reverts commit c9dea3dc90ebedd8e93ffce4f1deade4e6c01416.
+
+commit c9dea3dc90ebedd8e93ffce4f1deade4e6c01416
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Feb 28 15:55:38 2008 +0100
+
+ Bug fixes in fwp_vres, budget mechanism modified. For testing purposes and easy testing , budget counts number of messages not bytes.
+
+commit 02cf867e6bd0b33180801180bbae73692beaa4b7
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Feb 28 15:54:36 2008 +0100
+
+ Bug fixes in fwp_vres, budget mechanism modified. For testing purposes and easy testing , budget counts number of messages not bytes.
+
+commit 8832dd611f5b2d01dd4ba3e65818a53e40ef5240
+Merge: 882fd8b... 3dbad8f...
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Feb 27 18:21:08 2008 +0100
+
+ Merge branch 'martin'
+
+commit 3dbad8fd7c890c8a3ef201955c3fe81d63b27987
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Feb 22 17:47:19 2008 +0100
+
+ fwp_ac files removed
+
+commit 4d3dafd09fa8278741916a776b8ac9833f2f7371
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Feb 22 17:36:46 2008 +0100
+
+ Each vres now open socket for its communication
+
+commit 882fd8bd3df19b2c19086d33d59519a8e7028e2c
+Merge: 7e3fa40... e0f2900...
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Feb 22 13:00:55 2008 +0100
+
+ Merge branch 'martin'
+
+commit e0f2900a35a67e485e288905999b408d83700467
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Feb 21 18:02:07 2008 +0100
+
+ Added fwp_vrestest2
+
+commit d671ec50b6290986210004124ca2c03a0ee68b87
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Feb 20 18:55:14 2008 +0100
+
+ fwp_contratbl files moved to mngt directory
+
+commit 9dcd2689a0b1919b85a62fd8d269c0d9caf38b82
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Feb 20 18:49:59 2008 +0100
+
+ Added packet budgeting into vres_tx_thread
+
+commit 963aaf42afb8a8c0751aa2cee1e14850e5c1281f
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Feb 20 18:07:25 2008 +0100
+
+ Fix in vres_tx_thread- setting period
+
+commit 2b5c5df2a045fecaa1df13af7b588e4abf7f3f9f
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Feb 20 11:31:53 2008 +0100
+
+ fwp_vrestest added
+
+commit 845a08e21fe2885f3536a794870427785cc1e05f
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Feb 20 11:30:44 2008 +0100
+
+ Bug fix v fwp_msgq and fwp_forwardtbl
+
+commit fed0db23892d79c56fdd8c327b029dce1a0e9f36
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Feb 19 18:32:43 2008 +0100
+
+ fixes in fwp_contract
+
+commit 84937f8e440662646d0da6f08af2d7fb637d07cc
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Feb 19 15:49:02 2008 +0100
+
+ Adding fwpagent forwarding table
+
+commit ef20a323f5cfc8b133b9cb91fbe6c913a5bb7989
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Tue Feb 19 02:27:22 2008 +0100
+
+ Fixes in fwp_contract - small msgb for both response
+
+commit 03261e2e2f0913c866b1ddafeb636ad67b847c7d
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Tue Feb 19 00:41:49 2008 +0100
+
+ Fix - id return in hashtbl_insert function
+
+commit 13b2a170cc812c7600a0aee3326ee0825d15a7a2
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Feb 18 18:51:21 2008 +0100
+
+ Fixes in fwp_agent and manager
+
+commit 36d731dde7bbfcf231fcf666ddee78758793df51
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Mon Feb 18 01:57:50 2008 +0100
+
+ Many fixes
+
+commit 425ccaf7d0a20ff2ff7ffea7c5902422e423cdd0
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Sun Feb 17 00:26:49 2008 +0100
+
+ Change the names of diectories
+
+commit 2a35d84ef68f7da58839c306ee4e8bdcb1531cb8
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Sat Feb 16 23:44:38 2008 +0100
+
+ Agent and manager compilation fixes
+
+commit a3e80a9fbfd279376fafdc0bb4b62fbb84d9c3d9
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Feb 15 17:44:44 2008 +0100
+
+ fwp manager compilation fixes
+
+commit 7ad25090c253f7c22bb654c809c97f15ef38c464
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Feb 15 14:18:36 2008 +0100
+
+ Move files from include and src directory up to libfwp directory
+
+commit d9418c4ba4f3d16c059a934eb0e5753a1a68e6ee
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Feb 15 13:58:41 2008 +0100
+
+ Remove Makefiles in libfwp
+
+commit 0ab19307c1d11129fe3ab7f6c27c2a5f3fe47d16
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Feb 15 13:42:03 2008 +0100
+
+ Added macros _fwp_sendto and _fwp_recfrom for sendto and recvfrom operations
+
+commit d0b4393035178dbae68803f26d93c3856d176bcb
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Feb 15 10:58:45 2008 +0100
+
+ libfwp test fixes
+
+commit bc4f901dccf1a6322f953c3a317e7179a2d6f9a7
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Feb 15 10:19:29 2008 +0100
+
+ rewrite of fwp_agent, adding hastable
+
+commit da3c99ae22798b0f15ede9c56851de54941087e3
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Feb 15 10:17:43 2008 +0100
+
+ rewrite of fwp_agent, adding hastable
+
+commit e5a554ef37398301938a1578ac906f2158a0d752
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Fri Feb 15 00:46:18 2008 +0100
+
+ libfwp compilation fixes
+
+commit 5e776bad6039872b9340397c657b82fc8c3ce949
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Thu Feb 14 01:46:20 2008 +0100
+
+ compilation fixes
+
+commit 5775fb01027e4f592dda5670c73f53324c46324d
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Feb 13 19:19:02 2008 +0100
+
+ introduced fwp_vres_param, fwp_contarct_data
+
+commit eafcfca169c8660c481df26061f4cbf689999ee9
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Feb 13 12:34:22 2008 +0100
+
+ Split fwpmngr.c and change the name of directory - fwpme - FWP management entity is more comprehensive
+
+commit 1eb9d76645363dc9f829f090b502ee4e8f2886de
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Wed Feb 13 02:08:34 2008 +0100
+
+ fwp_msgb preparation change in mngr_input
+
+commit 8af62955be82793cd3b03e0d190aed11b4e39afa
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Feb 12 17:29:45 2008 +0100
+
+ compilation fixes
+
+commit a8f25f193413bea3efa18fce31183ed5f1fb57ee
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Feb 12 17:03:15 2008 +0100
+
+ Rename ctable->cntable and fwp_contract->fwp_cnt
+
+commit 72046daf10bf711c26ce9c942940d991c72b15ce
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Feb 12 16:53:38 2008 +0100
+
+ Contract table and operations modification
+
+commit 8e12cde82c64eeb4c4fcda49a1de1c03f2902485
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Feb 12 12:49:40 2008 +0100
+
+ Split internal and external representation of contract
+
+commit 7e3fa409ef9a38f2670ceee7934a28f4514a3c5b
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Mon Feb 11 23:01:06 2008 +0100
+
+ Fixes and additions to more_sta scripts.
+
+commit 6f388988288240bd8616828a610759f33629524c
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Mon Feb 11 21:23:50 2008 +0100
+
+ Fixed bug in generated data files.
+
+commit a31cbabea4aad0185aef25b0c5452bb0e815f544
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Mon Feb 11 19:33:01 2008 +0100
+
+ Updated version of more_sta scripts
+
+commit ffb0bd9b599d51a2055d653d72f047236960cb7d
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Mon Feb 11 17:08:58 2008 +0100
+
+ Added scripts for testing transmission from multiple stations.
+
+commit 369e41d7661e3108937524ac9a745028c72a816c
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Mon Feb 11 17:06:32 2008 +0100
+
+ Removed debug message
+
+commit 152fb71def8200cc17458b69c2c8aacc2fc129d3
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Feb 11 16:18:54 2008 +0100
+
+ remove flag parameter from fwp ops
+
+commit a89ce5bc10439738b42baf7720caab5eb64ad2b4
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Feb 11 15:30:53 2008 +0100
+
+ fwp_prototets changed to use fwp_endpoints. Test passed.
+
+commit de7c277401b28242ccbd200c1eb0fde212e7d250
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Mon Feb 11 14:56:39 2008 +0100
+
+ Delete all -o flags from title of graph.
+
+commit b3b5c14731224e1feb2c800687e8bb94479b2869
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Mon Feb 11 01:33:51 2008 +0100
+
+ fwp_endpoint compilation fixes
+
+commit e32e95266e3e524ea196e474794972521478929b
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Feb 8 18:01:56 2008 +0100
+
+ function parameter changes in fw_endpoint
+
+commit 139d5bf13c90ed36c2ed4abdb7626213f89d18ed
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Feb 8 09:17:02 2008 +0100
+
+ Use thicker lines for plotting individual directions.
+
+commit dbe943ee97c24508061b2cb627ee131c3d65ee6d
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Feb 8 09:12:41 2008 +0100
+
+ Allow wclient and wserver to send packets with a specified interface.
+
+ In combination with send-to-self patch (http://www.ssi.bg/~ja/#loop),
+ this allows to have both wserver and wclient running in one machine
+ and use multiple interfaces for communication.
+
+commit a193db919f72628f083c2e7eb85f179ef79fd975
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Fri Feb 8 00:31:54 2008 +0100
+
+ revert the last change
+
+commit a06668722dd2066438fb9b7ed7cbe7376f84f73f
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Feb 7 18:03:02 2008 +0100
+
+ change *epoint to epoint_id in endpoint calls
+
+commit b4626165880f3d599a29a477c19d0e3bc006b8aa
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Feb 7 16:09:54 2008 +0100
+
+ Added comments to fwp_endpoint
+
+commit 93ab2d4f22eebc1004b85142461e750f7626b395
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Feb 7 15:27:47 2008 +0100
+
+ Added endpoint bind and unbind ops
+
+commit 6f1d00c47c1d6ba3c48dad8671d88496594371a2
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Feb 7 07:16:19 2008 +0100
+
+ Opacity set to 1 in svg files. It is still slow :-)
+
+commit d53ce455f07f82e2030bdcc7334a4fdeb3613778
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Feb 6 17:59:29 2008 +0100
+
+ fwp_socket - addr field predefined to array of chars
+
+commit 9eb6d9a01881505672925890bbbfe42c6a5ec5a2
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Feb 6 16:48:04 2008 +0100
+
+ schedlat.c added
+
+commit b5f491e40a169d1c659b3c891cadcf9f02fdbfe4
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Feb 6 16:46:05 2008 +0100
+
+ Added test for measuring of CPU scheduler latency.
+
+ I get strange results when measurements are run on my old laptop. This
+ application should help to determine, whether it is caused by the
+ laptop or something else.
+
+commit b73955ffa0c4b870a85c23df9e5afc7cdd845b6b
+Merge: ee842f8... 92d4606...
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Feb 6 16:40:29 2008 +0100
+
+ Merge branch 'master' of rtime:/var/git/frescor
+
+commit ee842f8785c99fb7454be36373b2e30f5ffed15f
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Feb 6 16:39:33 2008 +0100
+
+ Final version of presentation for CAK colloquium
+
+commit 72b6e6d45b453ed509dcda8fa2383ce5450591be
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Feb 6 15:30:26 2008 +0100
+
+ Adding pointer to fwp_socket into fwp_endpoint
+
+commit 92d46060d0eb93af77c84bb78ce179641306c3d1
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Feb 5 19:14:58 2008 +0100
+
+ Adding martin branch
+
+commit 9f8a97ea1437b0b654c1bf2e071cab46540e071d
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Feb 5 16:08:03 2008 +0100
+
+ Little compilation fixes
+
+commit c78cffec714b7ab9e87fea336bb4a2c56007f28c
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Feb 5 16:01:13 2008 +0100
+
+ Created branch martin
+
+commit 561c2fe93efbc04c872309ffaa396127c81fc99a
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Mon Feb 4 22:42:48 2008 +0100
+
+ First version of kolokvium presentation.
+
+commit e382bab54b1bea6ca1b34eda1f5f1635f0ea30dc
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Feb 4 17:33:23 2008 +0100
+
+ Modification of figures of Paris presentation- adding svg files
+
+commit c0495cc1cfc20ea19396d7d3fef7786317885632
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Feb 4 16:28:04 2008 +0100
+
+ Modification of figures of Paris presentation
+
+commit 2584cf4a3582f50daa474e3ffbc702f4a6ca50bf
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Feb 4 13:25:42 2008 +0100
+
+ Paris presentation modified
+
+commit 58e07664e0814cfe8a686c2443a0e3579b0f6371
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Feb 1 18:17:26 2008 +0100
+
+ Admission test now calulates even PHY overhead for all possible PHYs.
+
+commit f5449bdbbb9a0ca69a6672ecd0bbdc3c5c7f6c80
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Jan 30 10:53:45 2008 +0100
+
+ Modified plot of admtest comparion graph to produce PDF and have better readability.
+
+commit 2ed31eea5c2cd71e9427c6faf379ffc14d841497
+Merge: 1917640... d251106...
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Jan 30 01:48:22 2008 +0100
+
+ Merge branch 'master' of rtime:/var/git/frescor
+
+commit 191764098f6f11698ebe989fdff0cf3a2d8f0fa6
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Jan 30 01:48:01 2008 +0100
+
+ Prezentation updated and added my slides.
+
+commit d251106d173050dc6690faacbfb6aa47f59e6012
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Wed Jan 30 01:21:02 2008 +0100
+
+ Add type fwp_vres_id_t
+
+commit 410d2ed7520c890b679faf1b46e8ed06260f533d
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Jan 30 00:44:51 2008 +0100
+
+ Added todo to utilization test
+
+commit 85d433e528863a492d8e4d4d769895cb92dd9463
+Merge: 5643381... 8c19e50...
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Wed Jan 30 00:27:01 2008 +0100
+
+ Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit 5643381a3865388c7b70e344b888c3ad5e7ad1e8
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Wed Jan 30 00:26:42 2008 +0100
+
+ Fixes in fwp_endpoint, split fwp_endpoint_cretae to fwp_send_endpoint and fwp_recv_endpoint
+
+commit 8c19e50e30bd03c4b51e5d0e0870ae49d6688e92
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Tue Jan 29 23:44:38 2008 +0100
+
+ Added some FIXMEs
+
+commit 721afdb0b617011706bd3330519e6d744e670656
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Tue Jan 29 23:43:04 2008 +0100
+
+ Added utilization based admission test and a testing application.
+
+ The testing application compares results of utilization test with real
+ measured values.
+
+commit c732867c6fd103ccb20bde85276c7e48d0afd3b2
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Jan 29 17:37:47 2008 +0100
+
+ Created presentation dir, added Paris 2008 fwp presentation
+
+commit 2b2c4692be07cf18f593ce1489c4171b5412a3e6
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Tue Jan 29 10:07:54 2008 +0100
+
+ Admission test moved to a separate file to easily switch between different ones.
+
+commit 298251fd1c5c0eb2350f985271e873cad57efc0b
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Tue Jan 29 09:20:17 2008 +0100
+
+ Other wclient modifications for FWP. Still not finished.
+
+commit e6cf160db78c208c0d56d521a7275e149a041e49
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Tue Jan 29 09:18:57 2008 +0100
+
+ Added warnings where I think something is wrong. Modified some doxygen documentation.
+
+commit 14b4283078b4c9dc420e3f530b48cf7fd968b3d7
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Tue Jan 29 09:15:41 2008 +0100
+
+ Fixes for wclient with FWP.
+
+commit da50199be80279e10b9264c24292632fb8712e94
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Tue Jan 29 09:13:57 2008 +0100
+
+ Fixed (updated) Makefile.rules
+
+commit fabcc73bf811c74df5fa59dc09a2c3ba44b26023
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Tue Jan 29 07:26:03 2008 +0100
+
+ Start of wclient rewrite for FWP.
+
+commit 87b7abb3b4006756e2ba1a5811f2326e438e0d67
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Tue Jan 29 02:58:09 2008 +0100
+
+ fwp_endpoint modification
+
+commit bbaf09fd7ee8957056f98cf8390b672e4338d1fb
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Tue Jan 29 02:57:54 2008 +0100
+
+ fwp_endpoint modification
+
+commit b0c6ed65161ae751384436df53493febcaaead31
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Jan 28 19:13:32 2008 +0100
+
+ Added fiel for fwp endpoint imlementation
+
+commit abde2bea695d78405c3f8e2a9ac5ce1d189ca1c9
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Jan 28 15:59:46 2008 +0100
+
+ changed return value in fwp_contract_negotiate
+
+commit ded5e7809b62314b1e47f688cf31d78cce921680
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Mon Jan 28 14:23:04 2008 +0100
+
+ Added wme_test to fwp compilation tree. Updated Makefile.rules.
+
+commit 87f1c881beb6b807948b9fd00b914e22d3c1ab15
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Jan 28 12:26:48 2008 +0100
+
+ Added temporal flag socketshare to fwp_msgb, to indicate whether socket is shared, if not it is destroyed when msgb is sent
+
+commit f163c1f440033e9adbf3d45a22a0f1e52ad54ba4
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Jan 28 12:17:43 2008 +0100
+
+ Bugfix in fwp_negotiate_response
+
+commit 615c2afe5b6ff046143606d8d4a0dc93ad8cd6a5
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Mon Jan 28 02:25:18 2008 +0100
+
+ changing msgb addr storage, fixes in fwp_mngr
+
+commit 7e61f9351512d348ffcca5896a83235c85980fa7
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Sat Jan 26 14:37:05 2008 +0100
+
+ Put a little documentation into fwp_proto.c
+
+commit c2e46222aaa99f3650b4276e1570854d9dfc7a5a
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Jan 25 17:51:52 2008 +0100
+
+ Change of fwp contract states
+
+commit 47ab6350fa37229352720041aa80fb308ff7d736
+Merge: bdb670b... 1776768...
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Jan 25 17:37:13 2008 +0100
+
+ Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit bdb670b0b4fd969ebed7bbf0719f14f11c937ec1
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Jan 25 17:37:00 2008 +0100
+
+ tx_thread cancellation modified by using pthread_cancel call
+
+commit 177676889a9df1d3e2cb80b1f8bf64812bba9408
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Jan 25 16:28:56 2008 +0100
+
+ Fixed bug in handling of default parameters introduced by ptevious commit.
+
+commit 021fe7b524d999d18065b679bfa3c658bbdc3a0a
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Jan 25 11:26:41 2008 +0100
+
+ Fixed handling of some command line arguments witout respoect of their position.
+
+commit b3bcb0a97f0448514c6df7f523bc820648406f9e
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Jan 25 10:11:24 2008 +0100
+
+ Tiny cleanups in sat-graph script.
+
+commit 657d07a81a682c35e4eaae77ac72adf46c01747a
+Merge: 78b4809... b4f2392...
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Jan 25 10:06:10 2008 +0100
+
+ Merge branch 'master' of rtime:/var/git/frescor
+
+commit 78b48097b0b2a84e9038c84a3594d71b36e77775
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Jan 25 10:05:14 2008 +0100
+
+ plot script rewritten to Perl to allow more complicated handling a various types of plot. Added -b to plot delay in both directions.
+
+commit b4f23929099a44618374a686445dfaa0cfbafff1
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Fri Jan 25 01:57:28 2008 +0100
+
+ Added fwp_vres_tx_thread cancelation
+
+commit 5f2793ef0687380e07a915547737cd6404e5fa76
+Merge: 30ba3f8... 95d225a...
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Jan 24 16:54:26 2008 +0100
+
+ Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit 30ba3f80199a246ffd17c1e20005d86f8a22e310
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Jan 24 16:54:12 2008 +0100
+
+ Fixes in fwp_manager: memcpy-size arg, msgb->tail setting etc., fwp_mngrtest passed
+
+commit 820397195a46087d5b6c21af6e07d468002c521b
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Jan 24 15:44:46 2008 +0100
+
+ Timestamp for the server is gathered and processed, so we can measure separately the delay from the client to server and from server to client. NTP synchronized hosts are required for this.
+
+commit 95d225a3c0259b62104f45983a5ae81a70db3c9c
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Jan 24 11:01:48 2008 +0100
+
+ Modification of various test scripts.
+
+commit 0bd4073bbf6f9e583a971352fa3d612ffd71f219
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Jan 24 11:01:09 2008 +0100
+
+ Added bounds for y axis in plots.
+
+commit d93a66e5398fec5c0382eb047846c34a03d531e6
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Thu Jan 24 03:13:47 2008 +0100
+
+ Manager fixes
+
+commit c6e2559e2e530d6d8d0d9805bcdc84987c969363
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Jan 23 21:00:01 2008 +0100
+
+ Fixes in fwp_mngr
+
+commit 3b34d018900af91305d8195a2d6fee8d25441b20
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Jan 23 09:40:10 2008 +0100
+
+ Added additional test and plot scripts
+
+commit d8444594a9f1db485028dfd0ebd17518cf9b45e6
+Merge: 1d88eb4... 54ef6fd...
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Jan 23 09:04:42 2008 +0100
+
+ Merge branch 'master' of rtime:/var/git/frescor
+
+commit 1d88eb426fc5d3039a3ba61e59819c5239c9f3ca
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Jan 23 09:04:32 2008 +0100
+
+ Without setting the queue size, the program behaves as before.
+
+commit 54ef6fd83261597b0c2c33b8e80b83b6d25ace53
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Wed Jan 23 01:01:27 2008 +0100
+
+ Compilation fixes, added fwp_mngrtest as fwp demo
+
+commit f57f27f2a1f0eb1ac84030d448a47775b353135a
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Wed Jan 23 01:00:56 2008 +0100
+
+ Compilation fixes, added fwp_mngrtest as fwp demo
+
+commit 7978d999985a6833af05c91377fbf74f0cf58ee6
+Merge: 8d5b05b... cd1c4c4...
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Jan 22 19:23:57 2008 +0100
+
+ Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit 8d5b05bd03f8a020dc16139a285f587d37c29ec2
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Jan 22 19:23:46 2008 +0100
+
+ Changes in fwp_mgr
+
+commit cd1c4c4ed18bf41419bf4bbf201890a8c4cddfde
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Tue Jan 22 16:38:44 2008 +0100
+
+ Modified be_sat plot commands to produce better graph.
+
+commit 82a70df849cc3bb74bb92d14a472638e03538e84
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Tue Jan 22 15:50:59 2008 +0100
+
+ Added be_influence test scripts.
+
+commit 648565555bb3c46b8c86f6fd52b6cf95b0d0652a
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Tue Jan 22 15:49:29 2008 +0100
+
+ Fixed multipaged graph pdf generation.
+
+commit 9aad5f4c098ab13138b76ca2f832129d86b73736
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Tue Jan 22 14:57:09 2008 +0100
+
+ Added -Q option to specify socket queue size. Fixed generation of text
+ comments in saver_results. Fixed error in calc_stream_params.
+
+commit 30aee11958de312fb05a7cf95285dc2ce738a95c
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Tue Jan 22 14:55:32 2008 +0100
+
+ Plot script reworked to have test aligned.
+
+commit 28a45549fd886487afb9da279519e3464b5fd953
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Tue Jan 22 10:14:41 2008 +0100
+
+ The size of socket's send buffers set to zero to decrease queuing delay.
+
+commit 641847e53a4eed6d980df1dafb1316af60d51f78
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Jan 22 08:51:30 2008 +0100
+
+ Adding old wifi presentation to CAK Kolokvium directory
+
+commit e3d0ff5034614d938b569dbc625f64f38ecea935
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Tue Jan 22 02:33:17 2008 +0100
+
+ Changing the name of sockets in fwp_init
+
+commit 1938bf2e1ada703386a3cb179b59a05cc8832291
+Merge: bba7705... 56a8855...
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Jan 21 19:24:49 2008 +0100
+
+ Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit bba7705e7d4180c31a60b0df417620328dec9d6a
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Jan 21 19:24:22 2008 +0100
+
+ lots of changes in fwp_init and fwp_mngr
+
+commit 56a88554db16903044f9e210a358140636730f7b
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Mon Jan 21 16:02:25 2008 +0100
+
+ Added scripts for running and drawing saturation tests.
+
+commit ba7a613b8b01710e22825c645688c661a26824b5
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Mon Jan 21 10:16:49 2008 +0100
+
+ Fixed bug in send_packet.
+
+commit 36b2bcd9bd92f617e54131b6b00b90ff49f05385
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Sun Jan 20 16:20:33 2008 +0100
+
+ Change in in fwp_msgb: addr is pointer to include unix/inet address and head changed to buf_start.
+
+commit 8cab450b8463a847e8cad8d7ec6dfeb54adc9ef6
+Merge: d30337f... 9968b3c...
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Sat Jan 19 21:49:04 2008 +0100
+
+ Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit d30337fa06bc981ec48e3a894af02a299985b7c6
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Sat Jan 19 21:48:51 2008 +0100
+
+ Added mutex to msgq and vres_table
+
+commit 9968b3c5d6cb235b4b322ef5bc6ab8f700e9ed45
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Sat Jan 19 10:21:45 2008 +0100
+
+ wclient cleanup
+
+commit 1566570c841ffb70a2806092e70404e45e1db277
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Sat Jan 19 09:18:02 2008 +0100
+
+ Added PNG output
+
+commit fb303b5c000f3dd28ec5e7ebbcedeb30bc405724
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Jan 18 19:23:56 2008 +0100
+
+ Compiled with -O2
+
+commit bd45080ba9cba0ab094e502d8bc8d1e37e1c698d
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Jan 18 19:20:33 2008 +0100
+
+ Removed unnecessary fields from msg strcuture.
+
+commit 4a5c81b698fcec3cd82a282bd91d1c767d6ab232
+Merge: 05ac88f... 451c865...
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Jan 18 19:01:11 2008 +0100
+
+ Merge branch 'master' of rtime:/var/git/frescor
+
+commit 05ac88ff71d53c07b2843b7428995e5dd03e7d12
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Jan 18 19:01:03 2008 +0100
+
+ Satration measurements removed, added real bandwidth measurement.
+
+commit 451c8656a4ae57b8a930ffc093f21e919edcc307
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Jan 18 18:41:36 2008 +0100
+
+ fwp_sendrecvtest -done, fixes in fwp_vres, added fwp_set_rt_prio
+
+commit aa7593a4053a8b91f879972a330be633b7270a49
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Jan 18 18:25:37 2008 +0100
+
+ Attempt to make saturation measurement more precise. Not very sucessfull.
+
+commit 18e2eee95f9895566f6e04a3e789b4ea7323daf5
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Jan 18 18:12:40 2008 +0100
+
+ Unsucessfull attempt to measure send and sendback delays.
+
+commit 926acafc1a538a108226ae14e79b9a7c57887c72
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Jan 18 17:52:52 2008 +0100
+
+ Added -o option to plot command. Renamed some variables.
+
+commit 9e98519ca8349baaee4a992a9a13992b60388b0a
+Merge: a71aa50... 0442299...
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Jan 18 17:51:51 2008 +0100
+
+ Merge branch 'master' of rtime:/var/git/frescor
+
+commit a71aa50df71d90adec9278ab949e99b5c565d43f
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Jan 18 17:51:44 2008 +0100
+
+ Added a possibility to measure saturation bandwidth.
+
+commit 53e2e86b458d4f11c667e829a42835ac53e53eb0
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Jan 18 14:05:05 2008 +0100
+
+ Fixed processing when resetting statistics.
+
+commit 0442299ab58cba8025476dbcf28488456aabc9f5
+Merge: a1c62ca... 4f522a5...
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Jan 18 14:02:31 2008 +0100
+
+ Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit a1c62ca3758d4d7c2b0ec1ee3880ae10cb345a0e
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Jan 18 14:02:14 2008 +0100
+
+ Added config.omk, lifwp fixes in fwp_ac and fwp_vres
+
+commit 4f522a5ec517be632bc2f9c3f1d7c030229bf006
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Jan 18 13:07:28 2008 +0100
+
+ Added -q switch to reset statistics when some queue becomes full.
+
+commit 580c9d23c93d5c048e1288cee3a6e4ded248344b
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Jan 18 11:09:22 2008 +0100
+
+ It is possible to specify message size per stream.
+
+commit 04e37e3a061c0106a9ab8a5d60f6c4a3b1e704fa
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Jan 18 11:08:08 2008 +0100
+
+ Fixed handling of send when it would block.
+
+commit ba149a651aec9ed5efd3f11bf159e2f6622e8e7f
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Fri Jan 18 02:06:38 2008 +0100
+
+ fwp_vrestest dir changed to fwp_prototest and test renamed to fwp_sendrecvtest
+
+commit 77134012adff0d3ed3397d43974b38d97ac52570
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Jan 17 18:49:05 2008 +0100
+
+ Added fwp_vrestest-not completed
+
+commit 3267c081fe8f06bc911ba30316f9f8776794f098
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Jan 17 14:58:12 2008 +0100
+
+ Added test for unix-dgram
+
+commit 0b2755a541854004b9a7e662454f9f25a298e309
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Jan 17 11:10:45 2008 +0100
+
+ Added Makelfiles to fwp_msgtest and unixoscktest
+
+commit ae6c4b211196114b14bb4b48d42e8b9fb0ef641b
+Merge: af8b0a1... d1d8a1c...
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Jan 16 20:39:46 2008 +0100
+
+ Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit af8b0a1b8a91409505dc09b64864547e309b29ff
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Jan 16 20:39:33 2008 +0100
+
+ Added unixclient_thread - test for threaded unix communication
+
+commit d1d8a1c047180145536efb8231790bbd64f9f540
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Jan 16 18:30:02 2008 +0100
+
+ Modified Makefile.rules to support compilation together with FRESCOR without the need of rewriting their Makefile.
+
+commit 3c0447fb21c5d9bf1f074cb9d601c0adece76f6f
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Jan 16 17:48:01 2008 +0100
+
+ Sending socket changed to non-blocking mode.
+
+commit 2f17f10761a343a589af554c592148fbff93f80a
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Jan 16 17:23:13 2008 +0100
+
+ In resulting graphs 100% represents the number of sent packets and if
+ there is packet loss, the graph don't reach 100%.
+
+commit 66908fd85d3645f519c828a095d62ea8b78f6986
+Merge: 280e4cf... b866360...
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Jan 16 16:57:14 2008 +0100
+
+ Merge branch 'master' of rtime:/var/git/frescor
+
+commit 280e4cf85e1694d81c6911e7cd59d07500e5e2f0
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Jan 16 16:31:25 2008 +0100
+
+ Server adds timestamp to the packet
+
+commit b8663609a5c1bb89abe5cf2e147c471180d3343f
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Jan 16 16:07:52 2008 +0100
+
+ Added tests/README and change msgtest to fwp_msgtest
+
+commit c882166fd30d32239ea3e870e265cac60b722974
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Jan 16 15:41:05 2008 +0100
+
+ Unixsocktest-finished, hashtest(incomplete) moved to hastest directory
+
+commit 459509d31889b453397263a0cd767d259bf0f274
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Jan 16 13:50:45 2008 +0100
+
+ Move unixserver-client to unixsocktest and msgqtest to msgtest
+
+commit 313b53c2623b354c08bcac8e77c232777a9e56a4
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Jan 16 13:44:20 2008 +0100
+
+ Move unixserver-client to unixsocktest and msgqtest to msgtest
+
+commit bbaa3f12a581830b468da9b27ec3eae637b01ec0
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Wed Jan 16 00:56:39 2008 +0100
+
+ Added test for unix sockets - not finished
+
+commit 19079d3f7cd4b213e14f717aee6c428b4af6a26a
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Tue Jan 15 21:44:19 2008 +0100
+
+ Message queue test finished. Libfwp passed test
+
+commit cb570312f09c480a1387d1cfc907350d1bb329a8
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Jan 15 18:50:06 2008 +0100
+
+ Added msgq test-not finished.
+
+commit 6114525c64b8f6ad7407d7b65799e2d1246209fc
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Jan 15 11:21:53 2008 +0100
+
+ Fixed fwpmgr compilation error
+
+commit 4969cee3c000c6493ebbec2d03199b801a91fda9
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Tue Jan 15 00:51:43 2008 +0100
+
+ Few fwp mngr compilation error fixes.
+
+commit 2ebe0337296835fa132764e5d125462fce1a96f1
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Jan 14 19:20:50 2008 +0100
+
+ Small modifications in fwp_mgr
+
+commit ab881f8f785885621b16212d3648853e275fff76
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Jan 14 15:41:36 2008 +0100
+
+ change msgq pamars first->out, last->in
+
+commit 9bb0636d9c9fbd704c2bb9201e1045d9e92160ec
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Mon Jan 14 11:27:18 2008 +0100
+
+ Fixed compilation problems.
+
+commit eaa6ea02ea246437d64309d4b0a48bc8d82844ac
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Jan 14 01:56:23 2008 +0100
+
+ Changing the structure of fwp client,server threads
+
+commit dc492490138ab672aff0109573282eefbfff9c6d
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Sun Jan 13 18:14:22 2008 +0100
+
+ fwp_client modification - wake up when a new message comes
+
+commit bd0e02dfcb24efc5b54a36961c4aec48cead118e
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Sat Jan 12 09:51:32 2008 +0100
+
+ Change fwp_msgb.buf_start to fwp_msgb.head
+
+commit f5552fffd719887d6c69b6595bfe315bc481d80f
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Jan 11 22:18:10 2008 +0100
+
+ Zmena fwpman.c na fwpmgr, da se skompilovat beta verze manageru
+
+commit 87cf9882efe63448a4d16e2167b0c36d28b964df
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Jan 3 15:47:06 2008 +0100
+
+ Pridanie makefile suborov do fwp_manager adresare
+
+commit d29f7a39424579e7bdfe57295e9f59cfdf4e6132
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Jan 3 15:40:45 2008 +0100
+
+ Presun souborov fwp manageri
+
+commit 59d7929d584388dc67ac50f213bed15e3bd869c0
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Fri Jan 11 00:21:01 2008 +0100
+
+ Upravy vo funkci fwp klienta
+
+commit 23b512d743e741bbdec700599e6e52b969205861
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Jan 10 19:30:43 2008 +0100
+
+ Upravy ve funkci fwp servera
+
+commit 732dbd0495bc4bd1c44665cd1982cf1357073a3b
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Jan 10 12:39:41 2008 +0100
+
+ Added warnings with notes to sources
+
+commit f380c205a8aec0047b0dd176e8abba7698eea97b
+Merge: 465235e... d48652c...
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Jan 10 12:38:08 2008 +0100
+
+ Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit 465235ec144df44dd9fea824d73117e5e2006f9a
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Thu Jan 10 12:35:22 2008 +0100
+
+ Upravy fwp managera
+
+commit d48652ce0f402be208b2547350b687a9732736ed
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Jan 10 10:54:16 2008 +0100
+
+ Added forgotten Makefile
+
+commit 18ca0eb55aa1541829c45e38cf8a00ce9f131c7e
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Jan 10 10:53:30 2008 +0100
+
+ Added .gitignore files
+
+commit 0f8b9a0134465ab11f5bc10bcd9e18c124eac275
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Jan 10 10:37:51 2008 +0100
+
+ Now, the comments are better recognize by doxygen.
+
+commit b375ae428ab9bcdbbe233b44877ae0aef45b8ae3
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Jan 10 10:11:07 2008 +0100
+
+ Updated Makefile.rules and leaf Makefile from current OMK repository.
+
+commit fd9ba5584da1aceff8316ab3e4428c9e56cd0ed4
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Thu Jan 10 01:29:20 2008 +0100
+
+ drobne zmeny v fwp_manager
+
+commit 48ed412ddc7ec1c1d687970f5eb94fd0f7481f67
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Wed Jan 9 23:47:46 2008 +0100
+
+ pridanie fwp_init
+
+commit 80307c91d1a1a56a20ed2419e9e71887e57aa6a9
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Jan 9 19:02:26 2008 +0100
+
+ pridani posilani negotita zparv pres unix socket v fwp_negotiate
+
+commit ff5ae217778862977d62502e024550d737a33e08
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Jan 9 19:01:09 2008 +0100
+
+ pridani posilani negotita zparv pres unix socket v fwp_negotiate
+
+commit 923038f199ae78f5cf990e62fa5037aaef0b2414
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Jan 9 18:26:32 2008 +0100
+
+ Pridana kompilacia fwp_ctable
+
+commit f1595d35ac434638472b7a6d9be88c9f379c5499
+Merge: 89be03e... 03502c9...
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Jan 9 17:07:27 2008 +0100
+
+ Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit 89be03e935cebb061ff7a23a72c5d3db2ecb7da8
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Jan 9 17:06:25 2008 +0100
+
+ Prvni release fwp knihovny
+
+commit 03502c99e260682e7fe5c888f32b756a2ac2502b
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Jan 9 15:01:40 2008 +0100
+
+ Added Doxygen config file
+
+commit c0deac52e54066e84c7420ab41873bb2eca4700c
+Author: Martin Molnar <molnam1@fel.cvut.cz>
+Date: Wed Jan 9 03:04:09 2008 +0100
+
+ pokracovani v oprave chyb
+
+commit c3904e20008f1e21f4311e5b85b50501ef184d8b
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Jan 8 20:04:53 2008 +0100
+
+ upravy pred kompilaciou
+
+commit 5ba550fea99ff4761df86588f5e31782a43c412c
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Jan 7 17:58:51 2008 +0100
+
+ pridani fwp_ctable.h do libfwp
+
+commit 33ea7ac8f71e135ad69518818c36a2a4f6f88014
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Jan 7 17:53:50 2008 +0100
+
+ nacrt fna_negotiate funkce
+
+commit d76de837c9abb9bbba21904fadcd21ca349b0552
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Jan 7 11:16:57 2008 +0100
+
+ Pridani operaci pro praci s fwp_msgb
+
+commit 587496ad389d1cfa9db533dc1d304a14f6f2b2b2
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Jan 7 11:06:55 2008 +0100
+
+ zmena fwp_msg_entry na fwp_msgb, nastin seralizace v fwp_msg.c
+
+commit d93849e9a6b36e25d4a259b4354d61b993da1a85
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Wed Jan 2 13:54:37 2008 +0100
+
+ Added initial version of FWP.
+
+commit 86c0ce56c949eabe58769d980921662a0caeddb1
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Dec 7 18:46:53 2007 +0100
+
+ Fixed x axis label.
+
+commit 85c1c78df89d9a828976311ce2d557ef18b31f2b
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Dec 7 17:58:30 2007 +0100
+
+ run can be now called from arbitrary directory
+
+commit 5b32b9b7935cb6e9594262dcd7bfc00aee3760e5
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Dec 7 17:18:55 2007 +0100
+
+ Bandidth of 0 can be specified without errors.
+
+commit 1122eda1fdd61fe1d195eb762d8f5222b8b815da
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Dec 7 16:54:16 2007 +0100
+
+ Added forgotten -P option to plot
+
+commit bb3d7841e932bdf4687f1f9e2ce6676c491fa148
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Dec 7 16:38:17 2007 +0100
+
+ Fit program output to 80 chars wide terminal
+
+commit 4e89a8160969ebdaa8a3632c1aca88261a6188f8
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Dec 7 16:37:25 2007 +0100
+
+ No fixed ranges in plot, so we can zoom in an interactive mode.
+
+commit 76f89b6aaf25f372401e2274064aa8c9367eccc8
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Dec 7 09:47:45 2007 +0100
+
+ Fixed y axis title
+
+commit 35a679663abb8e9fa5ef61e2b37ab027f34c828a
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Dec 7 09:34:09 2007 +0100
+
+ Execute tests in alphabetical order
+
+commit c3058b5cc12f312dd8374fbddaa94f177be41136
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Dec 7 09:32:34 2007 +0100
+
+ Added -B and -T options for default parameters of -b
+
+commit 2d8b44f8364aa9a9bb66b6553c4f7828c0132def
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Fri Dec 7 09:31:20 2007 +0100
+
+ Added pdf output to plot
+
+commit 9a8fed4cc0e88b79c4a471bb3f17ed610d68176d
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Dec 6 19:30:01 2007 +0100
+
+ Test is easier to break by CTRL-C
+
+commit cfb607d380b3506ce7b8b3eb727683acd30664a6
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Dec 6 18:08:28 2007 +0100
+
+ Some plotting fixes
+
+commit 1032b8d8ce3ea1921991f4cbab856350e2d45708
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Dec 6 17:16:35 2007 +0100
+
+ Fixed stream statistics and their display in graph.
+
+commit 952f7c420dd0b081e0182630420f03563713143c
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Dec 6 17:08:25 2007 +0100
+
+ When plotting, a point is down only if the PDF function changes its value.
+
+commit 5e0107ce61c10ef1b11748dd5252d0bbaa0ac145
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Dec 6 16:19:39 2007 +0100
+
+ All statistics in plots (used enhanced mode).
+
+commit 7fb4427a5d83449e29e20e6802744c1320346e99
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Dec 6 15:22:24 2007 +0100
+
+ Small fixes of wclient terminal output.
+
+commit 19bae345036415cffbb7ac7f65dc51438c08c116
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Dec 6 14:21:33 2007 +0100
+
+ Added scripts for running multiple experiments in batch manner and plot their results.
+
+commit a82b6a1329cf8553af8287620db68fad40187f55
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Dec 6 13:10:38 2007 +0100
+
+ Fixed graph generation
+
+commit bec3d81eeae63551c617cdc6d20b887e2a303d21
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Dec 6 12:32:03 2007 +0100
+
+ Values equal to 100% are no longer displayed in graph
+
+commit 00b777320d2b22b68503d4c2a0eb868722cbf189
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Dec 5 17:44:16 2007 +0100
+
+ Graph is generated as delay probability distribution function.
+
+commit 5f356cf71c24069fa4064ef4da55cb4e3284fdd4
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Dec 5 15:45:51 2007 +0100
+
+ Added \n to help messages.
+
+commit 53ae4c68118e047f8eb1e6b3bca2737aed9d8169
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Dec 5 15:44:30 2007 +0100
+
+ Added -b (bandwidth) parameter
+
+commit 1290f28cb7c073bf2022ddcdabc099fefae82c47
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Wed Dec 5 10:19:03 2007 +0100
+
+ Added -g (granularity) option.
+
+commit c2a281d4bf28f7fb85bb529a887e15a3791481a0
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Dec 4 11:07:50 2007 +0100
+
+ Rozdelenie patchu na patch povoleni qos a nastavenie AC fornt(RALINK)
+
+commit 596cdd32cf0fa5071c7892c48b2267e472677892
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Dec 3 18:09:42 2007 +0100
+
+ Oprava chyby deleni nulou v save_results
+
+commit fb635eee995d15f1596ab8e493c7016e4095e409
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Dec 3 18:00:03 2007 +0100
+
+ MSEC nahrazen lepe za MSEC_TO_USEC
+
+commit 72cea358be6d3d48fcb29598d406f0958858e3db
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Dec 3 17:56:04 2007 +0100
+
+ Zmena AC_QUEUES->AC_NUM
+
+commit 5b69b656b5b034a85ccbf9c39f3e3c47a29504bb
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Dec 3 17:51:35 2007 +0100
+
+ SEC_TO_USEC,USEC_TO_NSEC, MSEC_TO_USEC makra pridany
+
+commit c0b69bb4a1937c584bea85edd6cf2ecde825881b
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Sun Dec 2 13:12:27 2007 +0100
+
+ Fixed compitation of sender period
+
+commit 7788c3fcc024eb3bc93a126213259cfc0559d902
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Sun Dec 2 02:30:45 2007 +0100
+
+ Added -o and -c command line options. Output file contains information on how was wclient invoked.
+
+commit 551b27f149519503ada4bd673d6c88f35e027a48
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Sun Dec 2 00:41:09 2007 +0100
+
+ Added jitter option -j.
+
+commit bc68b35b3df7c9e8d11d6699bcab0a3d71a4f270
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Sat Dec 1 23:43:53 2007 +0100
+
+ gethostbyname() works. Can send differently sized packets
+
+commit 816c30994b4dba230bafbdd718762058cf5577b1
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Sat Dec 1 18:46:33 2007 +0100
+
+ Added runtime statistics (to check correctness of results).
+
+commit 6abeb141d4cd25f79e1aec58ed0f5be1bde934bd
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Sat Dec 1 17:25:27 2007 +0100
+
+ All time units are in microseconds.
+
+commit 7a2efcfd096dc83dc9f37d21cd9c3304a0cb1b74
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Sat Dec 1 12:46:01 2007 +0100
+
+ Task runs with RT priority, added run script, common code added to common.c.
+
+commit 8b46f7cb490978248533815f371eafe6b894713a
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Nov 30 14:12:56 2007 +0100
+
+ Kosmeticke upravy wclient.c, pridani DEBUG volby
+
+commit bf03e79fb4f7941247efa2880b5af768647ec99d
+Merge: 46af599... 9f21e1b...
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Nov 30 14:05:22 2007 +0100
+
+ Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit 9f21e1b5f4d4ef526189344da161b1a3edc05b61
+Author: root <root@sum2.felk.cvut.cz>
+Date: Fri Nov 30 14:00:42 2007 +0100
+
+ Pridana DEBUG podminka do wserver
+
+commit 46af5990453301bc8f9c31b60de49096226b3a6e
+Merge: dd18ec1... 6b4685d...
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Nov 30 13:57:27 2007 +0100
+
+ Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit 6b4685da67a5613caee6ba408a7e3d9b1a696678
+Author: root <root@sum2.felk.cvut.cz>
+Date: Fri Nov 30 12:53:18 2007 +0100
+
+ Kosmeticke uopravy wserver.c
+
+commit dd18ec13d7994ef4912d8294a50b4f9987e85c35
+Merge: e3450bb... c5caf7f...
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Nov 30 10:07:09 2007 +0100
+
+ Merge branch 'master' of molnam1@rtime.felk.cvut.cz:/var/git/frescor
+
+commit e3450bb09da7c7c13e717829bb866bac20be3e89
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Fri Nov 30 10:06:56 2007 +0100
+
+ wclient+plot_commands unknown changes
+
+commit c5caf7f938f9ff3aa40b026ebca1d420fbcfcec8
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Nov 29 19:22:46 2007 +0100
+
+ Fixed bug, where sender sent packets only to port 5100
+
+commit abfc31684ab8da9683f458c7c42b0bf219325845
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Thu Nov 29 18:43:36 2007 +0100
+
+ Granularity changed, results are normalized to percents
+
+commit a805f57eea582b96a377118f1a8e78762f545d1c
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Tue Nov 27 17:07:57 2007 +0100
+
+ Modifikace souboru pro genrovani grafu: generovani .eps formatu
+
+commit 0f4e00eddd67d11e986e51597be6fa3e4f31be85
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Mon Nov 26 21:10:40 2007 +0100
+
+ Inicializace struktury
+
+commit 01eb6b8fbd57f476a17bbabe92108dc9a09170c7
+Merge: 883d04e... f96a6e8...
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Nov 26 20:53:54 2007 +0100
+
+ oprava wclient
+
+commit 883d04eb8b6d1dec43180036e9a6a488aa42676b
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Nov 26 20:50:24 2007 +0100
+
+ oddeleni sendpointu
+
+commit f96a6e8291f2f74cacd057e4941d60f4184bdbed
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Mon Nov 26 18:37:57 2007 +0100
+
+ Predelano zadavani streamu
+
+commit 3465f90cea0598384651a38fac916845caf7889e
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Nov 26 17:59:51 2007 +0100
+
+ wmm kernel patch added
+
+commit 54858f4dc989b6ba1c373c571d2ad661b6991ec5
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Mon Nov 26 17:51:47 2007 +0100
+
+ Simplified Makefile
+
+commit b1b24842ef9610beef9e3a068a4b7f7d4b7f761a
+Author: Martin Molnar <molnar@sum.(none)>
+Date: Mon Nov 26 17:48:35 2007 +0100
+
+ Initial commit
+
+commit c70fea54041ebf45a01baf1d639529de2174002d
+Author: Michal Sojka <sojkam1@fel.cvut.cz>
+Date: Mon Nov 26 16:17:46 2007 +0100
+
+ Initial commit - empty readme
--- /dev/null
+FWP is built from source files by OCERA Make-System (OMK) [10]. Prior building FWP, default
+configuration file must be generated by running
+
+ make default-config
+
+Then, build process is started by calling
+
+ make
+
+in the top-level source directory. If the compilation is successful, the built targets are
+placed under compiled directory. To create documentation from comments in source files run
+doxygen from the top-level source directory. The generated documentation files are placed in the
+compiled/doc directory.
+The subdirectories of FWP main directory are:
+• libfwp contains sources of FWP library. The compiled library is called libfwp.a and is
+ placed in compiled/lib/libfwp.a.
+• fwp mngr contains sources of FWP agent and manager. The built application is called
+ fwpmngr resp. fwpagent and is placed in compiled/bin/fwpmngr and compiled/bin/fwpagent respectively.
+• tests contains sources of test programs. The built tests are placed in the compiled/bin-tests
+ directory.
+
+In order for application to use FWP, in must be linked to libfwp.a library. Further, FWP
+agent must be launched in every node. FWP agent can be started from command line by:
+
+ fwpagent -a 192.168.1.1
+
+where -a specifies IP address of the
+manger.
+There is only one instace of fwp manager running on access point machine and started by command
+ fwpmngr
+
+The contents of tests directory is often changing. The actual detailed list of test programs
+with their descriptions can be found in README file included in the directory.
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+default_CONFIG = CONFIG_FWP=y
+
+ifeq ($(CONFIG_FWP),y)
+SUBDIRS = lib mngr wme_test tests
+CFLAGS+= -Wall -Wextra -D_REENTRANT
+endif
--- /dev/null
+Software description
+=====================
+Name:
+ FRESCOR WLAN Protocol (FWP)
+Version:
+ 0.1
+Status:
+ Alpha
+Authors:
+ Martin Molnar,
+ Michal Sojka
+Licence:
+ GPL
+
+Brief description:
+ The protocol that applies FRESCOR to 802.11 networks
+
+Bugs:
+
+Description:
+ FRESCOR WLAN protocol (FWP) is a set of software components enabling FRSH applications
+ to communicate over IEEE 802.11 WLANs. It is designed to work on hardware conforming
+ to WMM specification and employs EDCA medium access mechanism. EDCA extends legacy DCF
+ function by prioritized medium access so that the packets in higher priority queue have
+ a higher probability to access the medium first.
+
+ FWP includes centralized admission control mechanism, which is conceptually very similar
+ to IEEE 802.11e HCCA admission control.
+ FRESCOR applications negotiate network contracts that are analogous to TSPECs but
+ unlike IEEE 802.11e admission control,where IEEE 802.11 management services are used,
+ FWP uses FNA services [8] to manage the negotiation process.
+
--- /dev/null
+#!/bin/bash
+
+KONSOLE=${KONSOLE:-"konsole --profile bigfont"}
+TARGET=${TARGET:-192.168.1.100}
+#TARGET=localhost
+
+sudo iwconfig wlan0 rate 1M
+
+#export FWP_MNGR_ADDR=192.168.1.100
+
+$KONSOLE --geometry +0+0 --vt_sz 80x13 --noclose -e bash -c "_compiled/bin/fwpmngr" &
+BGM=$!
+
+sleep 1
+echo "Press a key..."
+read
+
+$KONSOLE --geometry +0+430 --vt_sz 80x2 -e bash -c "sudo fwptester $TARGET; sleep 10"&
+BG0=$!
+
+echo "Press a key..."
+read
+
+$KONSOLE --geometry +0+550 --vt_sz 80x2 -e bash -c "sudo fwptester -B 1000 $TARGET; sleep 10" &
+
+echo "Press a key..."
+read
+
+(
+ RANDOM=5
+ while true; do
+ $KONSOLE --geometry +0+550 --vt_sz 80x3 -e bash -c "sudo fwptester -c 30 -B $((RANDOM%200)) -s $((RANDOM%1300+40)) $TARGET; echo Finished; sleep 10"
+ sleep 10
+ done
+
+) &
+
+BG1=$!
+
+(
+ RANDOM=3
+ while true; do
+ $KONSOLE --geometry +0+700 --vt_sz 80x3 -e bash -c "sudo fwptester -c 20 -b VO:$((RANDOM%100)),VO:$((RANDOM%100)) -s $((RANDOM%1300+40)) $TARGET; echo Finished; sleep 10"
+ sleep 10
+ done
+
+) &
+BG2=$!
+
+echo "Press a key to finish demo..."
+read
+
+kill $BGM $BG0 $BG1 $BG2
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+CFLAGS += -Wall -D_REENTRANT -g -D_FWP_INTERNALS_
+SUBDIRS= fwp frsh_fwp
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+shared_LIBRARIES = frsh_fwp
+CFLAGS += -D_FWP_INTERNALS_
+frsh_fwp_SOURCES += fwp_fna.c fwp_fra.c fwp_block.c
+include_HEADERS= fwp_res.h fwp_fna.h
+frsh_fwp_CLIENT_IDL += fwp_idl.idl
+include_GEN_HEADERS= fwp_idl.h
+lib_LOADLIBES+= fna fra
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#include <fwp_res.h>
+#include <fres_container.h>
+
+static const struct fres_block_desc fwp_sched_block_desc = {
+ .size = sizeof(fres_block_fwp_sched),
+ .serialize = (fres_block_serialize_fnc_t*)fres_block_fwp_sched_serialize,
+ .deserialize = (fres_block_deserialize_fnc_t*)fres_block_fwp_sched_deserialize,
+ .duplicate = fres_block_duplicate_default
+};
+
+static const struct fres_block_desc fwp_block_desc = {
+ .size = sizeof(fres_block_fwp),
+ .serialize = (fres_block_serialize_fnc_t*)fres_block_fwp_serialize,
+ .deserialize = (fres_block_deserialize_fnc_t*)fres_block_fwp_deserialize,
+ .duplicate = fres_block_duplicate_default
+};
+
+int fres_block_register_fwp()
+{
+ int ret;
+ ret = fres_block_register(FRES_BLOCK_FWP_SCHED,
+ &fwp_sched_block_desc);
+ if (ret)
+ return ret;
+ ret = fres_block_register(FRES_BLOCK_FWP,
+ &fwp_block_desc);
+ return ret;
+}
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#include <fna.h>
+#include <fres_vres.h>
+#include <frsh_forb.h>
+#include "fwp_endpoint.h"
+#include "fwp_vres.h"
+#include "fwp.h"
+#include "fwp_res.h"
+#include "fwp_utils.h"
+#include "fwp_debug.h"
+
+int fwp_fna_init(const frsh_resource_id_t resource_id)
+{
+ int rv;
+
+ if ((rv = fwp_init()))
+ return rv;
+
+ return fra_fwp_init();
+}
+
+int fwp_fna_network_budget_to_bytes(const frsh_resource_id_t resource_id,
+ const frsh_rel_time_t *budget, size_t *nbytes)
+{
+ *nbytes = budget->tv_nsec;
+ return 0;
+}
+
+int fwp_fna_network_bytes_to_budget(const frsh_resource_id_t resource_id,
+ const size_t nbytes, frsh_rel_time_t *budget)
+{
+ budget->tv_nsec = nbytes;
+ budget->tv_sec = 0;
+ return 0;
+}
+
+int fwp_fna_send_endpoint_created(fna_endpoint_data_t *endpoint)
+{
+ unsigned int node, port;
+ fwp_endpoint_attr_t *attr;
+ struct fwp_endpoint *fwp_epoint;
+ int rv;
+ frsh_send_endpoint_protocol_info_t *spi;
+
+ node = (unsigned int) endpoint->destination;
+ port = (unsigned int) endpoint->stream_id;
+ attr = NULL;
+
+ spi = &endpoint->endpoint_protocol_info.send;
+ if (spi->size == sizeof(fwp_endpoint_attr_t))
+ attr = (fwp_endpoint_attr_t*)spi->body;
+ rv = fwp_send_endpoint_create(node, port, attr, &fwp_epoint);
+ endpoint->protocol_info.body = fwp_epoint;
+ return rv;
+}
+
+int fwp_fna_receive_endpoint_created(fna_endpoint_data_t *endpoint)
+{
+ unsigned int node,port;
+ fwp_endpoint_attr_t *attr;
+ struct fwp_endpoint *fwp_epoint;
+ int rv;
+
+ node = (unsigned int) endpoint->destination;
+ port = (unsigned int) endpoint->stream_id;
+ attr = (fwp_endpoint_attr_t*) endpoint->protocol_info.body;
+ rv = fwp_receive_endpoint_create(port, attr, &fwp_epoint);
+ if (rv)
+ return rv;
+
+ endpoint->protocol_info.body = fwp_epoint;
+ fwp_endpoint_get_params(fwp_epoint, &node, &port, attr);
+ endpoint->stream_id = port;
+ FWP_DEBUG("PORT= %d\n", port);
+
+ return 0;
+}
+
+int fwp_fna_send_endpoint_bind(fna_endpoint_data_t *endpoint, fna_vres_id_t vres)
+{
+ return fwp_send_endpoint_bind(endpoint->protocol_info.body,
+ (struct fwp_vres *) vres->priv);
+}
+
+int fwp_fna_send_endpoint_unbind(fna_endpoint_data_t *endpoint)
+{
+ return fwp_send_endpoint_unbind(endpoint->protocol_info.body);
+}
+
+int fwp_fna_endpoint_destroy(fna_endpoint_data_t *endpoint)
+{
+ return fwp_endpoint_destroy(endpoint->endpoint_protocol_info.send.body);
+}
+
+/** FNA send routine */
+int fwp_fna_send_sync(const fna_endpoint_data_t *endpoint, const void *msg,
+ const size_t size)
+{
+ struct fwp_endpoint *fwp_epoint;
+
+ fwp_epoint = endpoint->protocol_info.body;
+ return fwp_send_sync(fwp_epoint, msg, size);
+}
+
+int fwp_fna_send_async(const fna_endpoint_data_t *endpoint,const void *msg,
+ const size_t size)
+{
+ struct fwp_endpoint *fwp_epoint;
+
+ fwp_epoint = (struct fwp_endpoint*) endpoint->protocol_info.body;
+ return fwp_send_async(fwp_epoint, msg, size);
+}
+
+/** FNA receive routines */
+int fwp_fna_receive(const fna_endpoint_data_t *endpoint,
+ void *buffer, const size_t buffer_size,
+ size_t *received_bytes, frsh_network_address_t *from)
+{
+ unsigned int from_addr;
+ ssize_t len;
+ struct fwp_endpoint *fwp_epoint;
+ int flags = 0;
+
+ fwp_epoint = (struct fwp_endpoint*) endpoint->protocol_info.body;
+ len = fwp_recv(fwp_epoint, buffer, buffer_size, &from_addr, flags);
+ if (len < 0)
+ return len;
+
+ *received_bytes = len;
+ *from = from_addr;
+
+ return 0;
+}
+
+int fwp_fna_receive_sync(const fna_endpoint_data_t *endpoint, void *buffer,
+ const size_t buffer_size, size_t *received_bytes,
+ frsh_network_address_t *from)
+{
+ unsigned int from_addr;
+ ssize_t len;
+ struct fwp_endpoint *fwp_epoint;
+ int flags = 0;
+
+ fwp_epoint = (struct fwp_endpoint*) endpoint->protocol_info.body;
+ len = fwp_recv(fwp_epoint, buffer, buffer_size, &from_addr, flags);
+ if (len < 0)
+ return len;
+
+ if (received_bytes)
+ *received_bytes = len;
+ if (from)
+ *from = from_addr;
+
+ return 0;
+}
+
+int fwp_fna_receive_async(const fna_endpoint_data_t *endpoint, void *buffer,
+ const size_t buffer_size, size_t *received_bytes,
+ frsh_network_address_t *from)
+{
+ unsigned int from_addr;
+ ssize_t len;
+ struct fwp_endpoint *fwp_epoint;
+ int flags = 0;
+
+ fwp_epoint = (struct fwp_endpoint*) endpoint->protocol_info.body;
+ len = fwp_recv(fwp_epoint, buffer, buffer_size, &from_addr, flags);
+ if (len < 0)
+ return len;
+
+ if (received_bytes)
+ *received_bytes = len;
+ if (from)
+ *from = from_addr;
+
+ return 0;
+}
+
+int fwp_fna_vres_destroy(const frsh_resource_id_t resource_id,
+ const fna_vres_id_t vres)
+{
+// return fwp_vres_close(vres);
+ return 0;
+}
+
+fna_operations_t fwp_fna_operations = {
+ .fna_init = fwp_fna_init,
+ .fna_contract_negotiate = NULL,
+ .fna_contract_renegotiate_sync = NULL,
+ .fna_contract_renegotiate_async = NULL,
+ .fna_vres_get_renegotiation_status = NULL,
+ .fna_vres_destroy = fwp_fna_vres_destroy,
+ .fna_vres_get_contract = NULL,
+ .fna_vres_get_usage = NULL,
+ .fna_vres_get_remaining_budget = NULL,
+ .fna_vres_get_budget_and_period = NULL,
+ .fna_resource_get_capacity = NULL,
+ .fna_resource_get_total_weight = NULL,
+ .fna_vres_decrease_capacity = NULL,
+ .fna_send_sync = fwp_fna_send_sync,
+ .fna_send_async = fwp_fna_send_async,
+ .fna_receive_sync = fwp_fna_receive_sync,
+ .fna_receive_async = fwp_fna_receive_async,
+ .fna_send_endpoint_get_status = NULL,
+ .fna_endpoint_destroy = fwp_fna_endpoint_destroy,
+ .fna_send_endpoint_created = fwp_fna_send_endpoint_created,
+ .fna_send_endpoint_bind = fwp_fna_send_endpoint_bind,
+ .fna_send_endpoint_unbind = fwp_fna_send_endpoint_unbind,
+ .fna_receive_endpoint_created = fwp_fna_receive_endpoint_created,
+ .fna_receive_endpoint_get_status = NULL,
+ .fna_network_get_max_message_size = NULL,
+ .fna_network_bytes_to_budget = fwp_fna_network_bytes_to_budget,
+ .fna_network_budget_to_bytes = fwp_fna_network_budget_to_bytes,
+ .fna_network_get_min_eff_budget = NULL
+};
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#ifndef _FWP_FNA_H
+#define _FWP_FNA_H
+
+#include "fwp.h"
+
+extern fna_operations_t fwp_fna_operations;
+
+#endif /* _FWP_FNA_H */
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <fra_generic.h>
+#include <fwp.h>
+//#include <fwp_fna.h>
+#include <frsh_distributed.h>
+#include "fwp_res.h"
+#include "fwp_idl.h"
+#include <stdio.h>
+#include <arpa/inet.h>
+
+
+UL_LOG_CUST(ulogd_fra_fwp);
+ul_log_domain_t ulogd_fra_fwp = {UL_LOGL_MSG, "fra_fwp"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(fra_fwp_logreg_domains, ulogd_fra_fwp);
+
+static int create_vres(fres_vres_t *vres, void *priv)
+{
+ char id[40];
+ fres_block_basic *basic;
+ fres_block_fwp_sched *fwp_sched;
+ fres_block_fwp *fwp;
+ fwp_vres_params_t vparams = {0};
+ struct fwp_vres *fwp_vres = NULL;
+ int rv;
+ size_t bytes;
+ char src[21] = "N/A";
+
+ /* Prepare vres parameters */
+ basic = fres_contract_get_basic(vres->new);
+ fwp_sched = fres_contract_get_block(vres->new, FRES_BLOCK_FWP_SCHED);
+ if (!fwp_sched)
+ return FRES_ERR_NEEDS_MORE_DATA_IN_CONTRACT;
+
+ fwp = fres_contract_get_block(vres->new, FRES_BLOCK_FWP);
+
+ frsh_network_budget_to_bytes(FRSH_NETPF_FWP, &basic->budget, &bytes);
+ vparams.budget = bytes;
+ vparams.period = basic->period;
+ vparams.ac_id = fwp_sched->ac_id;
+ if (fwp) {
+ vparams.src.s_addr = fwp->src;
+ snprintf(src, sizeof(src), "%s", inet_ntoa(vparams.src));
+ }
+ /* Create vres */
+ if ((rv = fwp_vres_create(&vparams, &fwp_vres)))
+ return (rv == -1) ? errno : rv;
+
+ vres->priv = fwp_vres;
+
+ fres_contract_id_to_string(id, &vres->id, sizeof(id));
+ ul_logmsg("Creating FWP VRes (id=%s, period=%ld ms, budget=%ld bytes AC=%d src=%s)\n",
+ id, fosa_rel_time_to_msec(basic->period),
+ vparams.budget, vparams.ac_id, src);
+
+ return 0;
+}
+
+static int cancel_vres(fres_vres_t *vres, void *priv)
+{
+ struct fwp_vres * fwp_vres;
+ fres_block_basic *basic;
+ char id[40];
+
+ fwp_vres = (struct fwp_vres *) vres->priv;
+ fwp_vres_destroy(fwp_vres);
+
+ basic = fres_contract_get_basic(vres->allocated);
+ fres_contract_id_to_string(id, &vres->id, sizeof(id));
+ ul_logmsg("Canceling FWP VRes (id=%s, period=%ld ms, budget=%ld bytes)\n",
+ id, fosa_rel_time_to_msec(basic->period), basic->budget.tv_sec);
+
+ return 0;
+}
+
+int change_vres(fres_vres_t *vres, void *priv)
+{
+ char id[40];
+ fres_block_basic *basic;
+ fres_block_fwp_sched *fwp_sched;
+ fwp_vres_params_t vparams;
+ struct fwp_vres *fwp_vres;
+ int rv;
+ size_t bytes;
+
+ /* Prepare vres parameters */
+ basic = fres_contract_get_basic(vres->new);
+ fwp_sched = fres_contract_get_block(vres->new, FRES_BLOCK_FWP_SCHED);
+
+ frsh_network_budget_to_bytes(FRSH_NETPF_FWP, &basic->budget, &bytes);
+ vparams.budget = bytes;
+ vparams.period = basic->period;
+ vparams.ac_id = fwp_sched->ac_id;
+ fwp_vres = vres->priv;
+
+ /* Changing vres */
+ if ((rv = fwp_vres_set_params(fwp_vres, &vparams))) {
+ return rv;
+ }
+
+ fres_contract_id_to_string(id, &vres->id, sizeof(id));
+ printf("Changing FWP VRes (id=%s, period=%ld ms, budget=%ld bytes AC=%d)\n",
+ id, fosa_rel_time_to_msec(basic->period),
+ vparams.budget, vparams.ac_id);
+
+ vres->perceived = vres->new;
+
+ return 0;
+}
+
+static struct fres_allocator fwp_allocator = {
+ .res_type = FRSH_RT_NETWORK,
+ .res_id = FRSH_NETPF_FWP,
+ .create_vres = create_vres,
+ .cancel_vres = cancel_vres,
+ .change_vres = change_vres,
+ .priv = NULL
+};
+
+int fra_fwp_init(void)
+{
+ fres_block_register_fwp();
+ return fra_register(&fwp_allocator);
+}
--- /dev/null
+/**
+ * @file fwp_idl.idl
+ * @author Martin Molnar <molnam1@fel.cvut.cz>
+ * @date Thu Oct 30 14:27:12 2008
+ *
+ * @brief Contract data block for fwp resource
+ *
+ *
+ */
+module fres {
+ module block {
+ /// Data passed from FWP manager to allocator.
+ struct fwp_sched {
+ octet ac_id;
+ };
+ /// Data passed by application to manager and/or
+ /// allocator.
+ struct fwp {
+ /// Non-zero value speciefies source address
+ /// used for sending packets. This value is
+ /// used to set ipi_spec_dst field of
+ /// IP_PKTINFO socket option - see ip(7).
+ long src;
+ };
+ };
+};
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#ifndef FWP_RES_H
+#define FWP_RES_H
+
+#include <forb.h>
+#include <fcb.h>
+#include <frsh_distributed.h>
+#include "fwp_idl.h"
+
+int fra_fwp_init();
+int fres_block_register_fwp();
+
+#include <fres_container.h>
+FRES_CONTAINER_ACCESSOR(FWP_SCHED, fwp_sched)
+FRES_CONTAINER_ACCESSOR(FWP, fwp)
+
+#include <fres_contract.h>
+FRES_CONTRACT_ACCESSOR(fwp_sched)
+FRES_CONTRACT_ACCESSOR(fwp)
+
+#endif /* FWP_RES_H */
--- /dev/null
+# Doxyfile 1.5.4
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+DOXYFILE_ENCODING = UTF-8
+PROJECT_NAME = FWP
+PROJECT_NUMBER =
+OUTPUT_DIRECTORY = doc
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = YES
+QT_AUTOBRIEF = YES
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP = NO
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 8
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = YES
+OPTIMIZE_OUTPUT_JAVA = NO
+BUILTIN_STL_SUPPORT = NO
+CPP_CLI_SUPPORT = NO
+SIP_SUPPORT = NO
+DISTRIBUTE_GROUP_DOC = YES
+SUBGROUPING = YES
+TYPEDEF_HIDES_STRUCT = NO
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = NO
+EXTRACT_ANON_NSPACES = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_DIRECTORIES = NO
+FILE_VERSION_FILTER =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT =
+INPUT_ENCODING = UTF-8
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.d \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.idl \
+ *.odl \
+ *.cs \
+ *.php \
+ *.php3 \
+ *.inc \
+ *.m \
+ *.mm \
+ *.dox \
+ *.py \
+ *.f90 \
+ *.C \
+ *.CC \
+ *.C++ \
+ *.II \
+ *.I++ \
+ *.H \
+ *.HH \
+ *.H++ \
+ *.CS \
+ *.PHP \
+ *.PHP3 \
+ *.M \
+ *.MM \
+ *.PY \
+ *.F90
+RECURSIVE = YES
+EXCLUDE = _build _compiled fna fosa frsh utils
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXCLUDE_SYMBOLS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS = *
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = YES
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+REFERENCES_LINK_SOURCE = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+HTML_DYNAMIC_SECTIONS = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = YES
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED =
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = NO
+MSCGEN_PATH =
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = YES
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = YES
+CALLER_GRAPH = YES
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+DOT_GRAPH_MAX_NODES = 50
+MAX_DOT_GRAPH_DEPTH = 1000
+DOT_TRANSPARENT = YES
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+#lib_LIBRARIES = fwp
+shared_LIBRARIES = fwp
+CFLAGS += -D_FWP_INTERNALS_ #-DFWP_WITHOUT_CONTNEGT
+SUBDIRS = tests
+#LDFLAGS = -lpthread -lrt
+fwp_SOURCES = fwp_utils.c fwp_vres.c fwp_msgb.c fwp_msgq.c fwp_endpoint.c fwp.c
+include_HEADERS= fwp_conf.h fwp_confdefs.h fwp_endpoint.h fwp_vres.h fwp.h fwp_msgb.h\
+ fwp_msgq.h fwp_utils.h
+
+include_HEADERS += fwp_debug.h # This file (and maybe even some \
+ others) should not be exported!
+
+lib_LOADLIBES+= pthread rt ulut
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#include "fwp_conf.h"
+#include "fwp_vres.h"
+#include "fwp_utils.h"
+#include <ul_logreg.h>
+#include "fwp_debug.h"
+
+ul_log_domain_t ulogd_fwp = {UL_LOGL_MSG, "fwp"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(init_ulogd_fwo, ulogd_fwp);
+
+int fwp_init()
+{
+ return 0;
+}
+
+int fwp_done()
+{
+ FWP_DEBUG("FWP done\n");
+ /* TODO: Cancel all contracts */
+ return 0;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+@mainpage
+
+@section Introduction
+
+FRESCOR WLAN protocol (FWP) allows the application to specify its requirements
+(number of bytes transmitted per period, deadline, etc.) for communication over
+IEEE 802.11 WLAN network and proides the mechanism that tries to fulfill them if
+they are feasible.
+
+FWP’s goal is to adapt applications to the current conditions on WLAN network
+rather than guaranteeing realtime behavior. FWP is designed to work on
+hardware conforming to WMM specification which defines EDCA medium access
+mechanism. EDCA extends legacy DCF function by prioritized medium access so
+that the packets in higher priority queue have higher probability to access
+the medium first.
+
+*/
+
+#ifndef _FWP_H
+#define _FWP_H
+
+#ifndef _FWP_CONFDEFS_H
+//#error fwp_confdefs.h not included
+#endif
+
+
+#include "fwp_conf.h"
+#include "fwp_vres.h"
+#include "fwp_endpoint.h"
+
+int fwp_init(void);
+int fwp_done(void);
+
+#endif /* _FWP_H */
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#ifndef _FWP_CONF_H
+#define _FWP_CONF_H
+
+#define FWP_AC_NUM 4
+#define FWP_MSGQ_SIZE (1<<11) /* Must be power of 2 */
+
+#define FWP_MY_ADDR_DEFAULT "127.0.0.1"
+#define FWP_MNGR_ADDR_DEFAULT "127.0.0.1"
+
+typedef
+struct {
+ unsigned int max_vres;
+ unsigned int max_endpoints;
+ unsigned int mngt;
+ char my_addr[16];
+ unsigned int my_stream_id;
+ char mngr_addr[16];
+ unsigned int mngr_stream_id;
+ unsigned int my_node_id;
+ unsigned int mngr_node_id;
+} fwp_configuration_table_t;
+
+extern fwp_configuration_table_t fwp_configuration;
+
+#endif /* _FWP_CONF_H */
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#ifndef _FWP_CONFDEFS_H
+#define _FWP_CONFDEFS_H
+
+#include "fwp_conf.h"
+
+/** Number of ACs */
+#ifndef CONFUGURE_FWP_AC_NUM
+#define CONFIGURE_FWP_AC_NUM 4
+#endif
+
+/* Size of message queue (in message units). MUST BE POWER OF 2!! */
+#ifndef CONFIGURE_FWP_MSGQ_SIZE
+#define CONFIGURE_FWP_MSGQ_SIZE 32
+#endif
+
+/* Maximal number of fwp vres per application. */
+#ifndef CONFIGURE_FWP_VRES_MAXIMUM
+#define CONFIGURE_FWP_VRES_MAXIMUM 20
+#endif
+
+/* Maximal number of fwp contract in contract table */
+#ifndef CONFIGURE_FWP_CONTRACTS_MAXIMUM
+#define CONFIGURE_FWP_CONTRACTS_MAXIMUM 50
+#endif
+
+/* Maximal number of fwp endpoint per application. */
+#ifndef CONFIGURE_FWP_ENDPOINTS_MAXIMUM
+#define CONFIGURE_FWP_ENDPOINTS_MAXIMUM 50
+#endif
+
+/** Turn on/off FWP mnanagement */
+#ifndef CONFIGURE_FWP_MNGT
+#define CONFIGURE_FWP_MNGT 1
+#endif
+
+/** IP Address of interface FWP operates on */
+//#ifndef CONFIGURE_FWP_MY_ADDR
+//#define CONFIGURE_FWP_MY_ADDR "127.0.0.1"
+//#endif
+
+#ifndef CONFIGURE_FWP_MY_STREAM_ID
+#define CONFIGURE_FWP_MY_STREAM_ID 0
+#endif
+
+//#ifndef CONFIGURE_FWP_MNGR_ADDR
+//#define CONFIGURE_FWP_MNGR_ADDR "255.255.255.255"
+//#endif
+
+#ifndef CONFIGURE_FWP_MNGR_STREAM_ID
+#define CONFIGURE_FWP_MNGR_STREAM_ID 3000
+#endif
+
+fwp_configuration_table_t fwp_configuration = {
+ CONFIGURE_FWP_VRES_MAXIMUM,
+ CONFIGURE_FWP_ENDPOINTS_MAXIMUM,
+ CONFIGURE_FWP_MNGT,
+#ifdef CONFIGURE_FWP_MY_ADDR
+ CONFIGURE_FWP_MY_ADDR,
+#else
+ FWP_MY_ADDR_DEFAULT,
+#endif
+ CONFIGURE_FWP_MY_STREAM_ID,
+#ifdef CONFIGURE_FWP_MNGR_ADDR
+ CONFIGURE_FWP_MNGR_ADDR,
+#else
+ FWP_MNGR_ADDR_DEFAULT,
+#endif
+ CONFIGURE_FWP_MNGR_STREAM_ID,
+ 0,
+ 0
+};
+
+
+#endif /*_FWP_CONFDEFS_H*/
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+#ifndef FWP_DEBUG_H
+#define FWP_DEBUG_H
+
+#include <ul_log.h>
+
+extern UL_LOG_CUST(ulogd_fwp);
+
+#define FWP_DEBUG(fmt,args...) ul_logdeb("%s: " fmt, __func__ , ##args)
+#define FWP_ERROR(fmt,args...) ul_logerr("%s: " fmt, __func__ , ##args)
+
+
+#endif
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#include "fwp_endpoint.h"
+#include "fwp_msgb.h"
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include "fwp_utils.h"
+#include "fwp_vres.h"
+#include <frsh_error.h>
+
+#include <pthread.h>
+#include "fwp_debug.h"
+#include "fwp_msgq.h"
+
+typedef unsigned int fwp_endpoint_id_t;
+
+/**
+ * Default fwp endpoint attributes
+ */
+static fwp_endpoint_attr_t fwp_epoint_attr_default ={
+ .reliability = FWP_EPOINT_BESTEFFORT,
+ .max_connections = 20,
+};
+
+/**
+ * FWP endpoint structure
+ */
+struct fwp_endpoint{
+ /** Fwp endpoint attributes */
+ fwp_endpoint_attr_t attr;
+ /* Vres this fwp endpoint is bound to */
+ fwp_vres_t *vres;
+ /** For send enpoint it contains destination address for
+ * receive endpoint it is filled with the msg source address
+ */
+ struct fwp_sockaddr peer;
+ /** Source/destination port */
+ unsigned int port;
+ /** Destination node */
+ int node;
+ /** Socket descriptor.
+ * In case of rebliable epoint it is a listen tcp socket.
+ */
+ int sockd;
+ /** File descriptor array of peers connected
+ * to this fwp receive endpoint.*/
+ int *c_sockd;
+ /**
+ * Number of connections
+ */
+ unsigned int nr_connections;
+ /** client fdset */
+ fd_set fdset;
+ /** specific operation options*/
+ int flags;
+ /** Forced source address. If non-zero, packets are sent over
+ * the specified interface. */
+ struct in_addr src;
+};
+
+/**
+ * Allocates endpoint
+ *
+ * \return On success returns fwp endpoint structure.
+ * On error, NULL is returned.
+ *
+ */
+static struct fwp_endpoint* fwp_endpoint_alloc()
+{
+ return (struct fwp_endpoint*) calloc(1,sizeof(struct fwp_endpoint));
+}
+
+/**
+ * Allocates endpoint
+ *
+ * \return On success returns endpoint structure.
+ * On error, NULL is returned.
+ *
+ */
+static inline void fwp_endpoint_free(struct fwp_endpoint *endpoint)
+{
+ free(endpoint);
+}
+
+/**
+ * Destroy endpoint
+ *
+ * \param[in] epd Endpoint descriptor
+ * \return On success 0 is returned.
+ * On error, negative error value is returned and errno is set appropriately.
+ */
+int fwp_endpoint_destroy(struct fwp_endpoint *ep)
+{
+ if (ep->sockd > 0)
+ close(ep->sockd);
+
+ fwp_endpoint_free(ep);
+ return 0;
+}
+
+/**
+ * Get endpoint parameters
+ *
+ * \param[in] ep Endpoint descriptor
+ * \param[out] node Node identifier
+ * \param[out] port Port
+ * \param[out] attr Endpoint`s attributes
+ * \return On success 0 is returned.
+ * On error, negative error value is returned.
+ */
+int fwp_endpoint_get_params(struct fwp_endpoint *ep, unsigned int *node,
+ unsigned int *port, fwp_endpoint_attr_t *attr)
+{
+ if (node) *node = ep->node;
+ if (port) *port = ep->port;
+ if (attr) *attr = ep->attr;
+
+ return 0;
+}
+
+int fwp_endpoint_attr_init(fwp_endpoint_attr_t *attr)
+{
+ bzero(attr, sizeof(fwp_endpoint_attr_t));
+ *attr = fwp_epoint_attr_default;
+
+ return 0;
+}
+
+/**
+ * Creates send endpoint
+ *
+ * \param[in] node IP address of destination node
+ * \param[in] port UDP port
+ * \param[in] attr Endpoint attributes
+ * \param[out] epp Pointer to the descriptor of newly created endpoint
+ *
+ * \return Non-negative number on success, -1 on error and sets errno appropriately.
+ *
+ */
+int fwp_send_endpoint_create(unsigned int node,
+ unsigned int port,
+ fwp_endpoint_attr_t *attr,
+ struct fwp_endpoint **epoint)
+{
+ struct sockaddr_in *addr;
+ struct fwp_endpoint *fwp_epoint;
+
+ fwp_epoint = fwp_endpoint_alloc();
+ if (!fwp_epoint) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ /*epoint->type = FWP_SEND_EPOINT;
+ epoint->status = FWP_EPOINT_UNBOUND;
+ epoint->node = node;
+ epoint->port = port;
+ */
+ if (attr)
+ fwp_epoint->attr = *attr;
+ else
+ fwp_epoint->attr = fwp_epoint_attr_default;
+
+ addr = (struct sockaddr_in *)&(fwp_epoint->peer.addr);
+ bzero((char*) addr, sizeof(*addr));
+ addr->sin_family = AF_INET;
+ addr->sin_addr.s_addr = node;
+ addr->sin_port = htons(port);
+ fwp_epoint->peer.addrlen = sizeof(struct sockaddr_in);
+
+ if (fwp_epoint->attr.reliability == FWP_EPOINT_RELIABLE) {
+ fwp_epoint->sockd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (fwp_epoint->sockd < 0) {
+ goto err;
+ }
+ } else {
+ fwp_epoint->sockd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (fwp_epoint->sockd < 0) {
+ goto err;
+ }
+
+ /* Enable broadcasts */
+ /*unsigned int yes = 1;
+ if (setsockopt(fwp_epoint->sockd,SOL_SOCKET, SO_BROADCAST,
+ &yes, sizeof(yes)) == -1) {
+ FWP_DEBUG("setsockopt(SO_BROADCAST): %s", strerror(errno));
+ goto err;
+ }*/
+
+ }
+
+ unsigned int yes = 1;
+ if (setsockopt(fwp_epoint->sockd,SOL_SOCKET, SO_REUSEADDR,
+ &yes, sizeof(yes)) == -1) {
+ FWP_DEBUG("setsockopt(SO_REUSEADDR): %s", strerror(errno));
+ goto err;
+ }
+
+#if 0
+ /* TODO: Allow using connect if it is specified in attr */
+ if (connect(fwp_epoint->sockd,
+ (struct sockaddr*) &fwp_epoint->peer.addr,
+ fwp_epoint->peer.addrlen)) {
+ FWP_DEBUG("FWp connect error\n");
+ goto err;
+ }
+#endif
+ FWP_DEBUG("FWP Send endpoint created.\n");
+
+#ifdef FWP_WITHOUT_CONTNEGT
+ /* Create vres with default parameters */
+ FWP_DEBUG("Creating default vres\n");
+ if (fwp_vres_create(&fwp_vres_params_default, &fwp_epoint->vresd)) {
+ goto err;
+ }
+
+ fwp_send_endpoint_bind(fwp_epoint, fwp_epoint->vresd);
+#endif
+
+ *epoint = fwp_epoint;
+ return fwp_epoint->sockd;
+err:
+ fwp_endpoint_destroy(fwp_epoint);
+ return -1;
+}
+
+/**
+ * Creates receive endpoint
+ *
+ * \param[in] port UDP port
+ * \param[in] attr Endpoint attributes
+ * \param[out] epointdp Pointer to the descriptor of newly created endpoint
+ *
+ * \return Non-negative number on success, -1 on error and errno is set.
+ */
+int fwp_receive_endpoint_create(unsigned int port,
+ fwp_endpoint_attr_t *attr,
+ struct fwp_endpoint **epp)
+{
+ struct sockaddr_in *addr;
+ struct fwp_endpoint *fwp_epoint;
+
+ fwp_epoint = fwp_endpoint_alloc();
+ if (!fwp_epoint) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ /*epoint->type = FWP_RECV_EPOINT;
+ epoint->status = FWP_EPOINT_UNBOUND;*/
+
+ if (attr)
+ fwp_epoint->attr = *attr;
+ else
+ fwp_epoint->attr = fwp_epoint_attr_default;
+
+ addr = (struct sockaddr_in *) &(fwp_epoint->peer.addr);
+ addr->sin_family = AF_INET;
+ /* TODO: set listen interface, maybe through config struct*/
+ addr->sin_addr.s_addr = FWP_ANY_NODE;
+ fwp_epoint->port = addr->sin_port = htons(port);
+ fwp_epoint->peer.addrlen = sizeof(struct sockaddr_in);
+
+ if (fwp_epoint->attr.reliability == FWP_EPOINT_RELIABLE) {
+ if ((fwp_epoint->sockd = socket(PF_INET, SOCK_STREAM,
+ IPPROTO_TCP)) < 0) {
+ FWP_ERROR("Unable to open socket: %s", strerror(errno));
+ goto err;
+ }
+
+ int yes = 1;
+ if (setsockopt(fwp_epoint->sockd,SOL_SOCKET, SO_REUSEADDR,
+ &yes, sizeof(yes)) == -1) {
+ FWP_ERROR("setsockopt(SO_REUSEADDR):%s",strerror(errno));
+ goto err;
+ }
+
+ if (bind(fwp_epoint->sockd, (struct sockaddr*) &fwp_epoint->peer.addr,
+ fwp_epoint->peer.addrlen) == -1) {
+ FWP_ERROR("Bind error: %s", strerror(errno));
+ /* TODO: remove all error messages from all libraries */
+ goto err;
+ }
+
+ if (listen(fwp_epoint->sockd, fwp_epoint->attr.max_connections)){
+ FWP_ERROR("Error on listen call: %s\n", strerror(errno));
+ goto err;
+ }
+
+ FD_ZERO(&fwp_epoint->fdset);
+ /*add listen socket */
+ FD_SET(fwp_epoint->sockd, &fwp_epoint->fdset);
+ fwp_epoint->c_sockd =
+ (int*)malloc(fwp_epoint->attr.max_connections);
+ bzero(fwp_epoint->c_sockd, fwp_epoint->attr.max_connections);
+ fwp_epoint->nr_connections = 0;
+
+ FWP_DEBUG("Reliable receive endpoint port=%d created.\n",
+ fwp_epoint->port);
+ } else {
+ if ((fwp_epoint->sockd = socket(PF_INET, SOCK_DGRAM,
+ IPPROTO_UDP)) < 0) {
+ FWP_ERROR("Unable to open socket: %s", strerror(errno));
+ goto err;
+ }
+
+ if (bind(fwp_epoint->sockd,
+ (struct sockaddr*) &fwp_epoint->peer.addr,
+ fwp_epoint->peer.addrlen) == -1) {
+
+ FWP_ERROR("Bind error: %s", strerror(errno));
+ goto err;
+ }
+ FWP_DEBUG("Best-Effort receive endpoint port=%d created.\n",
+ fwp_epoint->port);
+ }
+
+ /*if (setsockopt(epoint->sockd, SOL_SOCKET, SO_RCVBUF,
+ &rcvbuf_size, sizeof(rcvbuf_size)) == -1) {
+
+ FWP_ERROR("Unable to set socket buffer size: %s", strerror(errno));
+ return -1;
+ }else {
+ FWP_DEBUG("Receive endpoint buffer size is set.\n");
+ }
+ */
+
+ getsockname(fwp_epoint->sockd, (struct sockaddr*)&fwp_epoint->peer.addr,
+ &fwp_epoint->peer.addrlen);
+
+ addr = (struct sockaddr_in*) fwp_epoint->peer.addr;
+ fwp_epoint->port = ntohs(addr->sin_port);
+ FWP_DEBUG("Recv port= %d\n",ntohs(addr->sin_port));
+ *epp = fwp_epoint;
+ return fwp_epoint->sockd;
+err:
+ fwp_endpoint_destroy(fwp_epoint);
+ return -1;
+}
+
+/**
+ * Binds send endpoint to vres
+ *
+ * \param[in] vres identifier of vres
+ * \param[in] ep send endpoint identifier
+ *
+ * \return On success returns 0. On error, -1 and errno is set appropriately.
+ */
+int fwp_send_endpoint_bind(struct fwp_endpoint *ep, fwp_vres_t *vres)
+{
+ int rv = 0;
+
+ if (ep->vres)
+ return FRSH_ERR_ALREADY_BOUND;
+
+ ep->vres = vres;
+ rv = fwp_vres_bind(vres, ep, ep->sockd, &ep->src);
+
+ return rv;
+}
+
+/**
+ * Unbinds send endpoint from vres
+ *
+ * \param[in] epointd Send endpoint descriptor
+ * \return On success returns 0. On error, -1 is returned and errno is set appropriately.
+ *
+ */
+int fwp_send_endpoint_unbind(struct fwp_endpoint *ep)
+{
+ int rv = 0;
+
+ /* unlink epoint-vres mutually */
+ if ((rv = fwp_vres_unbind(ep->vres)) < 0)
+ return rv;
+
+ return 0;
+}
+
+/**
+ * Accepts (TCP) client connection to receive endpoint
+ *
+ * \param[in] epointd Pointer to fwp endpoint
+ * \return
+ * On success, it returns zero.
+ *
+ */
+static int fwp_receive_endpoint_accept(struct fwp_endpoint *fwp_epoint)
+{
+ int csockd;
+// struct fwp_endpoint *fwp_epoint = epointd;
+ fwp_sockaddr_t peer;
+ int i;
+
+ if (fwp_epoint->nr_connections == fwp_epoint->attr.max_connections)
+ return -1;
+
+ peer.addrlen = sizeof(struct sockaddr_in);
+ csockd = accept(fwp_epoint->sockd, (struct sockaddr*)peer.addr,
+ &peer.addrlen);
+
+ if (csockd < 0) {
+ FWP_ERROR("Error on accept: %s\n", strerror(errno));
+ return errno;
+ }
+
+ FWP_DEBUG("New connection accepted\n");
+ /* find free place */
+ i = 0;
+ while ((fwp_epoint->c_sockd[i])&& (i < fwp_epoint->nr_connections))
+ i++;
+ fwp_epoint->c_sockd[i] = csockd;
+ fwp_epoint->nr_connections++;
+
+ FD_SET(csockd, &fwp_epoint->fdset);
+ return 0;
+}
+
+/**
+ * Receives message from stream (TCP)
+ *
+ * \param[in] epointd Descriptor of endpoint
+ * \param[in] buffer Buffer to store message
+ * \param[in] buffer_size Size of buffer
+ *
+ * \return
+ * On success, it returns number of received bytes.
+ * On error, -1 is returned and errno is set appropriately.
+ *
+ */
+int fwp_recv_conn(struct fwp_endpoint *ep, void *buffer,
+ size_t buffer_size)
+{
+ fwp_sockaddr_t *peer = &ep->peer;
+ fd_set fdset = ep->fdset;
+ ssize_t len;
+ int i;
+
+ FWP_DEBUG("Checking for tcp data\n");
+ for (i = 0; i < ep->nr_connections; i++) {
+ if (!FD_ISSET(ep->c_sockd[i], &fdset)) {
+ continue;
+ }
+
+ FWP_DEBUG("Prepare to receive tcp data\n");
+ peer->addrlen = sizeof(struct sockaddr_in);
+
+ len = recvfrom(ep->c_sockd[i], buffer, buffer_size, 0,
+ (struct sockaddr*)&peer->addr, &peer->addrlen);
+ if (len < 0) /* Error */
+ return len;
+
+ FWP_DEBUG("Received tcp data\n");
+ if (len)
+ return len;
+
+ /* tcp connection closed */
+ FWP_DEBUG("Connection closed\n");
+ FD_CLR(ep->c_sockd[i], &ep->fdset);
+ memcpy(ep->c_sockd+i, ep->c_sockd+i+1,
+ sizeof(int)*(ep->nr_connections -i-1));
+ ep->nr_connections--;
+ return 0;
+ }
+ return 0;
+}
+
+/**
+ * Receives message
+ *
+ * \param[in] epointd Descriptor of endpoint
+ * \param[in] buffer Buffer to store message
+ * \param[in] buffer_size Size of buffer
+ *
+ * \return
+ * On success, it returns number of received bytes.
+ * On error, -1 is returned and errno is set appropriately.
+ *
+ */
+ssize_t fwp_recv(struct fwp_endpoint *ep,
+ void *buffer, const size_t buffer_size,
+ unsigned int *from, int flags)
+{
+ fwp_sockaddr_t *peer = &ep->peer;
+ struct sockaddr_in *addr = (struct sockaddr_in*) ep->peer.addr;
+ ssize_t len;
+ fd_set fdset;
+
+ /*if (!fwp_endpoint_is_valid(epointd)) {
+ errno = EINVAL;
+ return -1;
+ }*/
+
+ if (ep->attr.reliability == FWP_EPOINT_BESTEFFORT) {
+ len = recvfrom(ep->sockd, buffer, buffer_size, 0,
+ (struct sockaddr*)&peer->addr, &peer->addrlen);
+ *from = addr->sin_addr.s_addr;
+ return len;
+ }
+
+ while (1){
+ /* FWP_EPOINT_RELIABLE */
+ fdset = ep->fdset;
+ if (select(FD_SETSIZE, &fdset, (fd_set *)0,
+ (fd_set *)0, NULL) < 0) {
+
+ FWP_ERROR("Error in select: %s", strerror(errno));
+ return -1;
+ }
+
+ if (FD_ISSET(ep->sockd, &fdset)) { /* is it listen socket? */
+ fwp_receive_endpoint_accept(ep);
+ continue;
+ }
+
+ /* Check client TCP sockets */
+ len = fwp_recv_conn(ep, buffer, buffer_size);
+ if (len) {
+ *from = addr->sin_addr.s_addr;
+ return len;
+ }
+ }
+}
+/**
+ * Physically send the message.
+ *
+ * This function should be called either by fwp_send_sync()/async() of
+ * by VRES to send delayed messaged.
+ *
+ * @param ep
+ * @param data
+ * @param size
+ *
+ * @return
+ */
+ssize_t fwp_endpoint_do_send(struct fwp_endpoint *ep,
+ const void *data, const size_t size)
+{
+ struct iovec iov;
+ struct msghdr msg = {0};
+ ssize_t ret;
+ char cmsg_buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
+
+ iov.iov_base = (void*)data;
+ iov.iov_len = size;
+
+ msg.msg_name = &ep->peer.addr;
+ msg.msg_namelen = ep->peer.addrlen;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
+ if (ep->src.s_addr != 0) {
+ struct cmsghdr *cmsg;
+ struct in_pktinfo *ipi;
+
+ memset(cmsg_buf, 0, sizeof(cmsg_buf));
+
+ msg.msg_control = cmsg_buf;
+ msg.msg_controllen = sizeof(cmsg_buf);
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+
+ cmsg->cmsg_level = SOL_IP;
+ cmsg->cmsg_type = IP_PKTINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+
+ ipi = (struct in_pktinfo*)CMSG_DATA(cmsg);
+ ipi->ipi_spec_dst = ep->src;
+ }
+ ret = sendmsg(ep->sockd, &msg, 0);
+ return ret;
+}
+
+/**
+ * Sends message through vres
+ *
+ * \param[in] epointd Endpoint descriptor
+ * \param[in] msg Message to sent
+ * \param[in] size Message size
+ *
+ * \return
+ * On success, it returns zero.
+ * On error, -1 is returned and errno is set appropriately.
+ *
+ */
+int fwp_send_async(struct fwp_endpoint *ep, const void *msg, size_t size)
+{
+ int ret;
+
+ if (!ep->vres)
+ return FRSH_ERR_NOT_BOUND;
+
+ ret = fwp_vres_consume_budget(ep->vres, size, false);
+ if (ret == 0)
+ ret = fwp_endpoint_do_send(ep, msg, size);
+ else if (ret == 1)
+ ret = fwp_vres_enqueue(ep->vres, ep, msg, size);
+ return ret;
+}
+
+int fwp_send_sync(struct fwp_endpoint *ep, const void *msg, size_t size)
+{
+ int ret;
+
+ if (!ep->vres)
+ return FRSH_ERR_NOT_BOUND;
+
+ ret = fwp_vres_consume_budget(ep->vres, size, true);
+ if (ret)
+ return ret;
+ ret = fwp_endpoint_do_send(ep, msg, size);
+ return ret;
+}
+
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#ifndef _FWP_ENDPOINT_H
+#define _FWP_ENDPOINT_H
+
+#define FWP_ANY_NODE INADDR_ANY
+
+typedef enum {
+ FWP_EPOINT_BESTEFFORT = 0,
+ FWP_EPOINT_RELIABLE = 1,
+} fwp_endpoint_reliability_t;
+
+struct fwp_endpoint;
+
+typedef unsigned int fwp_addr_t;
+
+/**
+ * Endpoint attributes
+ */
+typedef
+struct fwp_endpoint_attr {
+ /** Specifies whether fwp endpoint is reliable (TCP) or not (UDP)*/
+ unsigned int reliability;
+ /** Specifies max number of allowed connections (for TCP only) */
+ unsigned int max_connections;
+} fwp_endpoint_attr_t;
+
+#include "fwp_vres.h"
+
+int fwp_endpoint_get_params(struct fwp_endpoint *ep, unsigned int *node,
+ unsigned int *port, fwp_endpoint_attr_t *attr);
+int fwp_send_endpoint_create(unsigned int node, unsigned int port,
+ fwp_endpoint_attr_t *attr,
+ struct fwp_endpoint **epoint);
+int fwp_receive_endpoint_create(/*unsigned int node,*/ unsigned int port,
+ fwp_endpoint_attr_t *attr,
+ struct fwp_endpoint **epoint);
+int fwp_endpoint_destroy(struct fwp_endpoint *ep);
+
+int fwp_send_endpoint_bind(struct fwp_endpoint *ep, fwp_vres_t *vres);
+int fwp_send_endpoint_unbind(struct fwp_endpoint *ep);
+
+ssize_t fwp_recv(struct fwp_endpoint *ep,
+ void *buffer, const size_t buffer_size,
+ unsigned int *from, int flags);
+int fwp_send_sync(struct fwp_endpoint *ep, const void *msg, const size_t size);
+int fwp_send_async(struct fwp_endpoint *ep, const void *msg, const size_t size);
+ssize_t fwp_endpoint_do_send(struct fwp_endpoint *ep,
+ const void *data, const size_t size);
+int fwp_endpoint_attr_init(fwp_endpoint_attr_t *attr);
+
+static inline int fwp_endpoint_attr_setreliability(fwp_endpoint_attr_t *attr,
+ int reliability)
+{
+ attr->reliability = reliability;
+ return 0;
+}
+
+/* Sets queueing policy */
+/*int fwp_endpoint_attr_setqpolicy(fwp_endpoint_attr_t *attr);*/
+#ifdef _FWP_INTERNALS_
+
+int fwp_endpoint_table_init(unsigned int nr_endpoints);
+
+#endif /*_FWP_INTERNALS_*/
+#endif /*_FWP_ENDPOINT_H */
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+/**
+ * \file fwp_msgb.c
+ *
+ * Routines for manipulation with fwp message buffer (msgb)
+ *
+ */
+
+#include "fwp_msgb.h"
+#include "fwp_utils.h"
+#include <stdlib.h>
+
+/*unsigned char* fwp_msgb_dealloc(size_t buf_size) */
+/*unsigned char* fwp_msgb_pool_init(size_t buf_size) */
+
+/**
+ * Allocates msgb.
+ *
+ * \param buf_size Size of msgb
+ * \return Allocated msgb
+ *
+ */
+struct fwp_msgb* fwp_msgb_alloc(size_t buf_size)
+{
+ struct fwp_msgb* msgb;
+
+ /*fwp_msgb_pool_dequeue; other choice*/
+ msgb = (struct fwp_msgb*) malloc(sizeof(struct fwp_msgb) + buf_size);
+ if (!msgb)
+ return NULL;
+
+ msgb->buffer_size = buf_size;
+ msgb->len = 0;
+ msgb->data = (unsigned char*) msgb + sizeof(struct fwp_msgb);
+ msgb->tail = msgb->data;
+
+ return msgb;
+}
+
+/**
+ * Deallocates msgb.
+ *
+ * \param msgb Pointer to msgb
+ *
+ */
+void fwp_msgb_free(struct fwp_msgb *msgb)
+{
+ free((void*) msgb);
+ msgb = NULL;
+}
+
+/**
+ * Routine is usually called after putting data of length len to msgb
+ * to adjust internal tail pointer and len fields of msgb
+ *
+ * \param msgb Pointer to msgb
+ * \param len The lenght data put to msgb
+ * \return Previous tail pointer
+ *
+ */
+unsigned char* fwp_msgb_put(struct fwp_msgb *msgb, unsigned int len)
+{
+ unsigned char *tmp= msgb->tail;
+
+ msgb->tail+=len;
+ msgb->len+=len;
+ return tmp;
+}
+
+/**
+ * Routine is usually called after reading data of lenght len from msgb to
+ * adjust internal data pointer and len of msgb
+ *
+ * \param msgb Pointer to msgb
+ * \param len The lenght data
+ * \return Previous tail pointer on NULL in case of lack of space in the buffer.
+ *
+ */
+unsigned char* fwp_msgb_pull(struct fwp_msgb *msgb, unsigned int len)
+{
+ if (len > msgb->len)
+ return NULL;
+
+ msgb->len -= len;
+ return msgb->data += len;
+}
+
+/**
+ * Routine is usually called after fwp_msgb_reserve after reserved area is filled
+ * adjust pointers
+ *
+ * \param msgb Pointer to msgb
+ * \param len The lenght data
+ * \return Current data pointer
+ *
+ */
+unsigned char* fwp_msgb_push(struct fwp_msgb* msgb, unsigned int len)
+{
+ msgb->data-=len;
+ msgb->len+=len;
+ return msgb->data;
+}
+
+unsigned char* fwp_msgb_shift(struct fwp_msgb *msgb, unsigned int len)
+{
+ if (msgb->data + len > msgb->tail)
+ return NULL;
+
+ return msgb->data += len;
+}
+
+/**
+ * Sets data pointer to the start of buffer
+ *
+ * \param msgb Pointer to msgb
+ *
+ */
+void fwp_msgb_reset_data_pointer(struct fwp_msgb *msgb)
+{
+ msgb->data = (unsigned char*) msgb + sizeof(struct fwp_msgb);
+}
+
+/**
+ * Sets data pointer to the start of buffer and the length of used data to zero
+ *
+ * \param msgb Pointer to msgb
+ */
+void fwp_msgb_reset_data(struct fwp_msgb* msgb)
+{
+ msgb->len = 0;
+ msgb->data = (unsigned char*) msgb + sizeof(struct fwp_msgb);
+ msgb->tail = msgb->data;
+}
+
+/**
+ * Reserve place of length len in msgb
+ *
+ * \param msgb Pointer to msgb
+ * \param len The lenght data
+ */
+void fwp_msgb_reserve(fwp_msgb_t *msgb, unsigned int len)
+{
+ msgb->data+=len;
+ msgb->tail+=len;
+}
+
+/*struct fwp_socket* fwp_socket_create(struct sockaddr *_addr, socklen_t _addrlen)
+{
+ struct fwp_socket* fwpsock;
+ unsigned char *addr;
+
+ fwpsock = (struct fwp_socket*) malloc(sizeof(struct fwp_socket) +
+ _addrlen);
+ if (!fwpsock)
+ return NULL;
+
+ addr = (unsigned char*) fwpsock + sizeof(struct fwp_socket);
+ memcpy(addr, (void*) _addr, _addrlen);
+
+ fwpsock->addr = (struct sockaddr*) addr;
+ fwpsock->addrlen = _addrlen;
+
+ return fwpsock;
+}
+
+inline void fwp_socket_set(struct fwp_socket *fwpsock, struct sockaddr *_addr,
+ socklen_t _addrlen)
+{
+ fwpsock->addr = _addr;
+ fwpsock->addrlen = _addrlen;
+}
+
+void fwp_socket_free(struct fwp_socket *fwpsock)
+{
+ free((void*)fwpsock);
+ fwpsock = NULL;
+}*/
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#ifndef _FWP_MSGB_H
+#define _FWP_MSGB_H
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <string.h>
+
+#define ADDRLEN_MAX 30
+
+typedef
+struct fwp_sockaddr{
+ char addr[ADDRLEN_MAX];
+ socklen_t addrlen;
+} fwp_sockaddr_t;
+
+/**
+ * Message buffer structure
+ */
+typedef
+struct fwp_msgb {
+ size_t buffer_size;
+ size_t len; /**< msg data length*/
+ unsigned char *data; /**< msg data */
+ unsigned char *tail; /**< msg data end*/
+} fwp_msgb_t;
+
+struct fwp_msgb* fwp_msgb_alloc(size_t buf_size);
+void fwp_msgb_free(struct fwp_msgb* msgb);
+
+unsigned char* fwp_msgb_put(struct fwp_msgb *msgb, unsigned int len);
+unsigned char* fwp_msgb_pull(struct fwp_msgb *msgb, unsigned int len);
+unsigned char* fwp_msgb_push(struct fwp_msgb* msgb, unsigned int len);
+void fwp_msgb_reset_data_pointer(struct fwp_msgb* msgb);
+void fwp_msgb_reset_data(struct fwp_msgb* msgb);
+unsigned char* fwp_msgb_shift(struct fwp_msgb* msgb, unsigned int len);
+void fwp_msgb_reserve(fwp_msgb_t *msgb, unsigned int len);
+
+/*struct fwp_socketaddr* fwp_socket_create(struct sockaddr *_addr, socklen_t _addrlen);
+inline void fwp_socket_set(struct fwp_socketaddr *fwpsock, struct sockaddr *_addr,
+ socklen_t _addrlen);
+*/
+#endif /* _FWP_MSGB_H */
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#include "fwp_msgq.h"
+#include <errno.h>
+
+/**
+ *Initialize message queue
+ *@param[in] msgq Message queue
+ **/
+void fwp_msgq_init(struct fwp_msgq *msgq)
+{
+ msgq->nr_pending = 0;
+ msgq->in = 0;
+ msgq->out = 0;
+ pthread_mutex_init(&msgq->lock, NULL); /* fast mutex */
+ sem_init(&msgq->msg_sem, 0, 0);
+}
+
+/**
+ * Enqueue message in message queue
+ *
+ * @param[in] msgq Message queue
+ *`@param[in] msgb Message buffer which stores a message
+ * @return
+ * Zero on success, -1 or error.
+ **/
+int fwp_msgq_enqueue(struct fwp_msgq *msgq, struct fwp_msgb *msgb)
+{
+ /* acquire queue mutex */
+ pthread_mutex_lock(&msgq->lock);
+
+ if (!(msgq->nr_pending < FWP_MSGQ_SIZE)){
+ /*if (msgq->qr_policy == NEWCOMER) {*/
+
+ /*release queue mutex*/
+ pthread_mutex_unlock(&msgq->lock);
+ errno = ENOBUFS;
+ return -1;
+ /* }
+ * if (msgq->qr_policy == OLDEST)
+ msgq->first = (msgq->first++) % FWP_MSGQ_SIZE;
+ msgq->nr_pending--;
+ */
+ }
+
+ /* depends on queuing policy specifies in endpoint */
+ msgq->queue[msgq->in] = msgb;
+ msgq->nr_pending++;
+ msgq->in = (++msgq->in) & (FWP_MSGQ_SIZE - 1);
+
+ sem_post(&msgq->msg_sem);
+ /* release queue mutex */
+ pthread_mutex_unlock(&msgq->lock);
+
+ return 0;
+}
+
+/**
+ * Dequeue message from message queue
+ *
+ * @param[in] msgq Message queue
+ * @return
+ * NULL if message queue in empty
+ * else returns pointer to message buffer(msgb)
+ **/
+struct fwp_msgb* fwp_msgq_dequeue(struct fwp_msgq *msgq)
+{
+ struct fwp_msgb* msgb;
+
+ sem_wait(&msgq->msg_sem);
+ /* acquire queue mutex */
+ pthread_mutex_lock(&msgq->lock);
+
+ msgb = msgq->queue[msgq->out];
+ msgq->nr_pending--;
+ msgq->out = (++msgq->out) & (FWP_MSGQ_SIZE - 1);
+
+ /* release queue mutex */
+ pthread_mutex_unlock(&msgq->lock);
+
+ return msgb;
+}
+
+struct fwp_msgb* fwp_msgq_peek(struct fwp_msgq *msgq)
+{
+ struct fwp_msgb* msgb;
+
+ pthread_mutex_lock(&msgq->lock);
+
+ if (msgq->nr_pending > 0)
+ msgb = msgq->queue[msgq->out];
+ else
+ msgb = NULL;
+ pthread_mutex_unlock(&msgq->lock);
+
+ return msgb;
+}
+
+/*
+ * Dequeue all messages from message queue
+ *
+ * @param[in] msgq Message queue
+ * @return
+ * NULL if message queue is empty
+ * else returns pointer to message buffer(msgb)
+ **/
+void fwp_msgq_dequeue_all(struct fwp_msgq *msgq)
+{
+ struct fwp_msgb *msgb;
+
+ /* acquire queue mutex */
+ pthread_mutex_lock(&msgq->lock);
+
+ while (msgq->in != msgq->out){
+ msgb = msgq->queue[msgq->out];
+ msgq->nr_pending--;
+ msgq->out = (++msgq->out) & (FWP_MSGQ_SIZE - 1);
+ fwp_msgb_free(msgb);
+ }
+
+ sem_init(&msgq->msg_sem, 0, 0);
+ /* release queue mutex */
+ pthread_mutex_unlock(&msgq->lock);
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#ifndef _FWP_MSGQ_H
+#define _FWP_MSGQ_H
+
+#include "fwp_conf.h"
+#include "fwp_msgb.h"
+
+#include <pthread.h>
+#include <semaphore.h>
+
+/**
+ * Message queue structure
+ *
+ */
+struct fwp_msgq {
+ unsigned int nr_pending; /**< number of messages in the queue */
+ struct fwp_msgb* queue[FWP_MSGQ_SIZE];
+ unsigned int in; /**< add at offset (in % size) */
+ unsigned int out; /**< extracted from offset (out % size) */
+ pthread_mutex_t lock; /**< queue lock */
+ sem_t msg_sem; /**< semaphore to block on empty mqueue */
+
+ /* queue reject policy */
+ /*queue_rejection_policy qr_policy;*/
+};
+
+void fwp_msgq_init(struct fwp_msgq *msgq);
+
+int fwp_msgq_enqueue(struct fwp_msgq *msgq, struct fwp_msgb* msgb);
+
+struct fwp_msgb* fwp_msgq_dequeue(struct fwp_msgq *msgq);
+struct fwp_msgb* fwp_msgq_peek(struct fwp_msgq *msgq);
+void fwp_msgq_dequeue_all(struct fwp_msgq *msgq);
+
+/* void fwp_msgq_setpolicy */
+
+#endif /* _FWP_MSGQ_H */
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#ifndef _FWP_TYPES
+#define _FWP_TYPES
+
+/* Flags values */
+#define FWP_RELIABLE 1
+#define FWP_BEST_EFFORT 2
+
+#endif /* _FWP_TYPES */
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#include "fwp_utils.h"
+
+#include <unistd.h>
+#include <sched.h>
+/*#include <stdlib.h>*/
+#include "fwp_debug.h"
+#include <errno.h>
+
+/*const int prio_to_ac[8] = {2,3,3,2,1,1,0,0};
+const unsigned int ac_to_tos[4] = {224,160,96,64};
+const char *ac_to_text[4] = {[AC_VO] = "AC_VO", [AC_VI] = "AC_VI",
+ [AC_BE] = "AC_BE", [AC_BK] = "AC_BK", };
+*/
+
+void fwp_timespec_add (struct timespec *sum, const struct timespec *left,
+ const struct timespec *right)
+{
+ sum->tv_sec = left->tv_sec + right->tv_sec;
+ sum->tv_nsec = left->tv_nsec + right->tv_nsec;
+
+ if (sum->tv_nsec >= 1000000000){
+ ++sum->tv_sec;
+ sum->tv_nsec -= 1000000000;
+ }
+}
+
+void fwp_timespec_sub (struct timespec *diff, const struct timespec *left,
+ const struct timespec *right)
+{
+ diff->tv_sec = left->tv_sec - right->tv_sec;
+ diff->tv_nsec = left->tv_nsec - right->tv_nsec;
+
+ if (diff->tv_nsec < 0){
+ --diff->tv_sec;
+ diff->tv_nsec += 1000000000;
+ }
+}
+
+void fwp_timespec_modulo(struct timespec *remainder, struct timespec *dividend,
+ struct timespec *dividor)
+{
+ long long a, b, res;
+
+ a = dividend->tv_sec * SEC_TO_USEC + dividend->tv_nsec / USEC_TO_NSEC;
+ b = dividor->tv_sec * SEC_TO_USEC + dividor->tv_nsec / USEC_TO_NSEC;
+ res = a % b;
+ remainder->tv_sec = res / SEC_TO_USEC;
+ remainder->tv_nsec = ( res % SEC_TO_USEC ) * USEC_TO_NSEC;
+}
+
+int fwp_set_rt_prio(int priority)
+{
+ int maxpri, minpri;
+ static struct sched_param param;
+
+ if ((maxpri = sched_get_priority_max(SCHED_FIFO)) == -1) {
+ FWP_ERROR("sched_get_priority_max call failed: %s\n",
+ strerror(errno));
+ return -1;
+ }
+
+ if ((minpri = sched_get_priority_min(SCHED_FIFO)) == -1) {
+ FWP_ERROR("sched_get_priority_min call failed: %s\n",
+ strerror(errno));
+ return -1;
+ }
+
+ if (priority > maxpri) {
+ FWP_ERROR("parameter %d is greater than the maximal allowed"
+ " priority %d.\n", priority, maxpri);
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (priority < minpri) {
+ FWP_ERROR("priority parameter %d is lower than the minimal "
+ "allowed priority %d.\n", priority, minpri);
+ errno = EINVAL;
+ return -1;
+ }
+
+ param.sched_priority = priority;
+
+ if (sched_setscheduler(0, SCHED_FIFO, ¶m) == -1) {
+ /*FWP_ERROR("sched_setscheduler call failed: %s\n",
+ strerror(errno));*/
+ return -1;
+ }
+
+ return 0;
+}
+
+int fwp_create_unix_socket(char *path, struct sockaddr_un *addr)
+{
+ int sockfd;
+
+ if ((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1){
+ FWP_ERROR("socket error: %s", strerror(errno));
+ return (-1);
+ }
+
+ bzero(addr, sizeof(addr));
+ addr->sun_family = AF_UNIX;
+ strcpy(addr->sun_path, path);
+
+ unlink(path);
+
+ if (bind(sockfd, (struct sockaddr*)addr,
+ sizeof(*addr)) == -1) {
+ FWP_ERROR("fwp_open_unix_socket - bind error: %s", strerror(errno));
+ return (-1);
+ }
+
+ return sockfd;
+}
+
+int fwp_create_inet_socket(unsigned int port, struct sockaddr_in *addr)
+{
+ int sockfd;
+
+ if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
+ FWP_ERROR("socket error: %s", strerror(errno));
+ return (-1);
+ }
+
+ addr->sin_family = AF_INET;
+ addr->sin_addr.s_addr = INADDR_ANY;
+ addr->sin_port = htons(port);
+
+ if (bind(sockfd, (struct sockaddr*)addr,
+ sizeof(*addr)) == -1) {
+
+ FWP_ERROR("bind error: %s", strerror(errno));
+ return (-1);
+ }
+
+ return sockfd;
+}
+
+/*void block_signals(void)
+{
+ sigset_t sigset;
+ int ret;
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGINT);
+ sigaddset(&sigset, SIGTERM);
+ ret = pthread_sigmask(SIG_BLOCK, &sigset, NULL);
+ if (ret != 0) {
+ FWP_ERROR("pthread_sigmask failed: %s", strerror(errno));
+ exit(1);
+ }
+}
+*/
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#ifndef _FWP_UTILS_H
+#define _FWP_UTILS_H
+
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <fwp_msgb.h>
+
+#define Kbit 1000
+#define Mbit (Kbit*Kbit)
+
+#define SEC_TO_NSEC 1000000000LL
+#define SEC_TO_USEC 1000000LL
+#define MSEC_TO_USEC 1000LL
+#define USEC_TO_NSEC 1000LL
+
+/*extern const int prio_to_ac[8];
+extern const unsigned int ac_to_tos[4];
+extern const char *ac_to_text[4];
+*/
+
+void fwp_timespec_add (struct timespec *sum, const struct timespec *left,
+ const struct timespec *right);
+void fwp_timespec_sub (struct timespec *diff, const struct timespec *left,
+ const struct timespec *right);
+void fwp_timespec_modulo(struct timespec *dividend, struct timespec *dividor,
+ struct timespec *remainder);
+
+int fwp_set_rt_prio(int priority);
+int fwp_create_unix_socket(char *path, struct sockaddr_un *addr);
+int fwp_create_inet_socket(unsigned int port, struct sockaddr_in *addr);
+
+#endif /* _FWP_UTILS_H */
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2009 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+#include "fwp_utils.h"
+#include "fwp_vres.h"
+
+#include "fwp_msgq.h"
+#include "fwp_endpoint.h"
+#include "fwp_debug.h"
+
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+static void* fwp_vres_tx_thread(void *_vres);
+
+typedef enum {
+ UNTOUCHED,
+ CHANGED,
+ QUEUED,
+} fwp_vres_flag_t;
+
+fwp_vres_params_t fwp_vres_params_default = {
+ .ac_id = FWP_AC_VO,
+ .budget = 100,
+ .period = {.tv_sec = 2 , .tv_nsec = 111111},
+ .src = { 0 },
+};
+
+/**
+ * Structure of FWP vres.
+ * Internal representation of vres
+ *
+ */
+struct fwp_vres{
+ struct fwp_vres_params params;
+ fwp_vres_flag_t flags;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond; /**< Signalizes budget replenishment */
+ fwp_budget_t budget; /**< Current remaining budget */
+ fwp_period_t period; /**< Period for this "activation" */
+ struct timespec replenish_at; /**< Time of next replenishment */
+ sem_t consumed;
+ /**< endpoint bounded to this vres */
+ struct fwp_endpoint *epoint;
+ pthread_t tx_thread; /**< tx_thread id*/
+ pthread_attr_t tx_thread_attr;
+ /** Copy of bound enpoint's socket - used for future changes
+ * of vres parameters. */
+ int ac_sockd;
+ /** Queue for messages to send */
+ struct fwp_msgq msg_queue;
+ /** If true, it is always allowed to send messages through this vres. */
+ bool bypass;
+};
+
+/**< mapping priority to ac*/
+static const int prio_to_ac[8] = {2,3,3,2,1,1,0,0};
+/**< IP tos for AC_VI, AC_VO, AC_BE, AC_BK */
+static const unsigned int ac_to_tos[4] = {224,160,96,64};
+
+/**
+ * Set access category (AC) to socket
+ *
+ * \param[in] sockd Socket descriptor
+ * \param[in] ac_id AC identifier
+ *
+ * \return On success returns zero.
+ * On error, negative error code is returned.
+ *
+ */
+static inline int fwp_vres_set_ac(int sockd, fwp_ac_t ac_id)
+{
+ unsigned int tos;
+
+ tos = ac_to_tos[ac_id];
+ if (setsockopt(sockd, SOL_IP, IP_TOS, &tos, sizeof(tos)) == -1) {
+ FWP_ERROR("setsockopt: %s", strerror(errno));
+ return (-1);
+ }
+
+ return 0;
+}
+
+static inline void set_flag(fwp_vres_t *vres, fwp_vres_flag_t flag)
+{
+ vres->flags |= (1 << flag);
+}
+
+static inline void clear_flag(fwp_vres_t *vres, fwp_vres_flag_t flag)
+{
+ vres->flags &= ~(1 << flag);
+}
+
+static inline int get_flag(fwp_vres_t *vres, fwp_vres_flag_t flag)
+{
+ return !!(vres->flags & (1 << flag));
+}
+
+static inline void clear_all_flags(fwp_vres_t *vres)
+{
+ vres->flags = 0;
+}
+
+static inline void fwp_vres_free(fwp_vres_t *vres)
+{
+ free(vres);
+}
+
+/*inline int fwp_vres_get(fwp_vres_id_t vres_id, fwp_vres_t **vres )
+{
+ if ((vres_id < 0) || (vres_id > fwp_vres_table.nr_vres - 1))
+ return -EINVAL;
+ *vres = &fwp_vres_table.entry[vres_id];
+ return 0;
+}
+*/
+
+/**
+ * Allocate vres
+ *
+ * \return On success returns vres descriptor.
+ */
+fwp_vres_t *fwp_vres_alloc()
+{
+ fwp_vres_t *vres = malloc(sizeof(*vres));
+ if (vres) {
+ memset(vres, 0, sizeof(*vres));
+ FWP_DEBUG("Allocated vres\n");
+ }
+ return vres;
+}
+
+static int apply_params(fwp_vres_t *vres)
+{
+ int rv = 0;
+ vres->period = vres->params.period;
+ vres->budget = vres->params.budget;
+ set_flag(vres, UNTOUCHED);
+ if (get_flag(vres, CHANGED)) {
+ clear_flag(vres, CHANGED);
+ rv = fwp_vres_set_ac(vres->ac_sockd, vres->params.ac_id);
+ }
+ return rv;
+}
+
+/**
+ * Set vres params
+ *
+ * \param[in] vresp Vres descriptor
+ * \param[in] params Vres parameters
+ *
+ * \return On success returns zero.
+ * On error, negative error code is returned.
+ *
+ */
+int fwp_vres_set_params(fwp_vres_t *vres, fwp_vres_params_t *params)
+{
+ int rv = 0;
+
+ if (!vres) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ pthread_mutex_lock(&vres->mutex);
+
+ if (vres->epoint &&
+ params->src.s_addr != vres->params.src.s_addr) {
+ errno = EREMCHG;
+ rv = -1;
+ goto out;
+ }
+ vres->params = *params;
+ if (vres->epoint) {
+ set_flag(vres, CHANGED);
+ if (get_flag(vres, UNTOUCHED))
+ rv = apply_params(vres);
+ }
+out:
+ pthread_mutex_unlock(&vres->mutex);
+ return rv;
+}
+
+/**
+ * Creates new vres
+ *
+ * \param[in] params Vres parameters
+ * \param[out] vresp Pointer to the descriptor of newly created vres
+ *
+ * \return Zero on success, -1 on error and errno is set
+ * appropriately.
+ */
+int fwp_vres_create(fwp_vres_params_t *params, fwp_vres_t **vresp)
+{
+ int rv;
+ fwp_vres_t *vres;
+
+ vres = fwp_vres_alloc();
+ if (!vres) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ pthread_mutexattr_t ma;
+ rv = pthread_mutexattr_init(&ma);
+ rv = pthread_mutexattr_setprotocol(&ma, PTHREAD_PRIO_INHERIT);
+ if (rv) return rv;
+ pthread_mutex_init(&vres->mutex, &ma);
+ pthread_cond_init(&vres->cond, NULL);
+
+ vres->params = *params;
+ apply_params(vres);
+ fwp_msgq_init(&vres->msg_queue);
+
+ if (getenv("FWP_BYPASS"))
+ vres->bypass = true;
+
+ pthread_attr_init(&vres->tx_thread_attr);
+ if ((rv = pthread_create(&vres->tx_thread, &vres->tx_thread_attr,
+ fwp_vres_tx_thread, (void*) vres)) != 0){
+ goto err;
+ }
+
+ *vresp = vres;
+
+ return 0;
+err:
+ fwp_msgq_dequeue_all(&vres->msg_queue);
+ fwp_vres_free(vres);
+ return -1;
+}
+
+/**
+ * Destroys vres
+ *
+ * \param[in] vres Vres descriptor
+ *
+ * \return Zero on success, -1 on error and errno is set
+ * appropriately.
+ */
+int fwp_vres_destroy(fwp_vres_t *vres)
+{
+ if (!vres) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ pthread_cancel(vres->tx_thread);
+ pthread_cond_destroy(&vres->cond);
+ pthread_mutex_destroy(&vres->mutex);
+
+ fwp_msgq_dequeue_all(&vres->msg_queue);
+ fwp_vres_free(vres);
+
+ FWP_DEBUG("Vres destroyed.\n");
+ return 0;
+}
+
+static void do_consume_budget(struct fwp_vres *vres, size_t size)
+{
+ if (get_flag(vres, UNTOUCHED)) {
+ /* Setup next replenish time */
+ struct timespec now;
+ clear_flag(vres, UNTOUCHED);
+ if (get_flag(vres, QUEUED))
+ now = vres->replenish_at;
+ else
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ fwp_timespec_add(&vres->replenish_at, &now, &vres->period);
+ sem_post(&vres->consumed);
+ }
+ vres->budget -= size;
+}
+
+int __consume_budget(struct fwp_vres *vres, size_t size, bool can_block)
+{
+ int ret = 0;
+ if (vres->bypass)
+ return 0;
+ if (vres->params.budget < size) {
+ errno = ENOSR;
+ return -1;
+ }
+ while (can_block && vres->budget < size) {
+ ret = pthread_cond_wait(&vres->cond, &vres->mutex);
+ /* The budget might have been changed while we were
+ * waiting, so check it again. */
+ if (vres->params.budget < size) {
+ errno = ENOSR;
+ return -1;
+ }
+ }
+ if (ret == 0) {
+ if (vres->budget >= size) {
+ do_consume_budget(vres, size);
+ ret = 0;
+ } else {
+ set_flag(vres, QUEUED);
+ ret = 1;
+ }
+ }
+ return ret;
+}
+
+/**
+ * Tries to consume (a part of) budget
+ *
+ * @param vres VRES whose budget is conumed.
+ * @param size How much to consume (in bytes).
+ * @param can_block True, indicates that the function can block to
+ * wait for budget replenishment. False causes no blocking and if 1 is
+ * returned, the calles must call fwp_vres_enqueue() to enqueue the
+ * packet to be sent later after replenishing.
+ *
+ * @return Zero if budget was consumed, 1 if there is not enough
+ * budget available and blocking was not allowed, -1 in case of error.
+ */
+int fwp_vres_consume_budget(struct fwp_vres *vres, size_t size, bool can_block)
+{
+ int ret = 0;
+ pthread_mutex_lock(&vres->mutex);
+ ret = __consume_budget(vres, size, can_block);
+ pthread_mutex_unlock(&vres->mutex);
+ return ret;
+}
+
+int fwp_vres_enqueue(struct fwp_vres *vres, struct fwp_endpoint *ep,
+ const void *msg, size_t size)
+{
+ struct fwp_msgb *msgb;
+ int ret;
+
+ if (!(msgb = fwp_msgb_alloc(size)))
+ return -1;
+ memcpy(msgb->data, msg, size);
+ fwp_msgb_put(msgb, size);
+ ret = fwp_msgq_enqueue(&vres->msg_queue, msgb);
+ if (ret) {
+ fwp_msgb_free(msgb);
+ return ret;
+ }
+ return ret;
+}
+
+static void wait_for_replenish(struct fwp_vres *vres)
+{
+ sem_wait(&vres->consumed);
+ clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME,
+ &vres->replenish_at, NULL);
+}
+
+static void send_queue(struct fwp_vres *vres)
+{
+ struct fwp_msgb *msgb;
+ bool can_send;
+ msgb = fwp_msgq_dequeue(&vres->msg_queue);
+ can_send = (0 == __consume_budget(vres, msgb->len, false));
+ if (!can_send) {
+ fwp_msgb_free(msgb);
+ FWP_ERROR("Cannot send queued packet (budget decreased?)\n");
+ return;
+ }
+ /* If we cannot send the whole queue, the flag will be set
+ * later by __consume_budget(). */
+ clear_flag(vres, QUEUED);
+
+ while (msgb) {
+ fwp_endpoint_do_send(vres->epoint, msgb->data, msgb->len);
+ fwp_msgb_free(msgb);
+ msgb = fwp_msgq_peek(&vres->msg_queue);
+ if (msgb) {
+ can_send = (0 == __consume_budget(vres, msgb->len, false));
+ if (can_send) {
+ msgb = fwp_msgq_dequeue(&vres->msg_queue);
+ } else {
+ msgb = NULL;
+ return;
+ }
+ }
+ }
+}
+
+static void replenish(struct fwp_vres *vres)
+{
+ pthread_mutex_lock(&vres->mutex);
+ apply_params(vres);
+ if (get_flag(vres, QUEUED))
+ send_queue(vres);
+ pthread_cond_broadcast(&vres->cond);
+ pthread_mutex_unlock(&vres->mutex);
+}
+
+/**
+ * Thread that does budgeting
+ *
+ */
+static void* fwp_vres_tx_thread(void *_vres)
+{
+ struct fwp_vres *vres = (struct fwp_vres*)_vres;
+ unsigned int ac_id = vres->params.ac_id;
+
+ fwp_set_rt_prio(90 - ac_id);
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
+
+ while (1) {
+ wait_for_replenish(vres);
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+ replenish(vres);
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+ }
+
+ return NULL;
+}
+
+/*int fwp_vres_bind(fwp_vres_t *vres, struct fwp_endpoint *epoint)*/
+int fwp_vres_bind(fwp_vres_t *vres, struct fwp_endpoint *ep, int sockd, struct in_addr *src)
+{
+ int rv = 0;
+
+ if (!vres) {
+ errno = EINVAL;
+ rv = -1;
+ goto err;
+ }
+
+ if (vres->epoint) { /*if already bounded */
+ errno = EBUSY;
+ rv = -1;
+ goto err;
+ }
+
+ vres->ac_sockd = sockd;
+ *src = vres->params.src;
+ rv = fwp_vres_set_ac(vres->ac_sockd, vres->params.ac_id);
+ if (rv)
+ goto err;
+ vres->epoint = ep;
+err:
+ return rv;
+}
+
+int fwp_vres_unbind(fwp_vres_t *vres)
+{
+ if (!vres) {
+ errno = EINVAL;
+ return -1;
+ }
+ pthread_mutex_lock(&vres->mutex);
+ vres->epoint = NULL;
+ pthread_mutex_unlock(&vres->mutex);
+ /* TODO: consider what to do with pending messages */
+ fwp_msgq_dequeue_all(&vres->msg_queue);
+ return 0;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#ifndef _FWP_VRES_H
+#define _FWP_VRES_H
+
+#include <netinet/in.h>
+#include <stdbool.h>
+
+struct fwp_vres;
+typedef struct fwp_vres fwp_vres_t;
+
+/** WMM defines 4 queues */
+typedef enum {
+ FWP_AC_VO = 0,
+ FWP_AC_VI = 1,
+ FWP_AC_BE = 2,
+ FWP_AC_BK = 3
+} fwp_ac_t;
+
+fwp_ac_t fwp_vres_get_ac(fwp_vres_t *vres);
+
+
+#ifdef _FWP_INTERNALS_
+
+#include "fwp_msgb.h"
+
+typedef unsigned int fwp_vres_id_t;
+typedef unsigned int fwp_vparam_id_t;
+typedef unsigned long int fwp_budget_t;
+typedef struct timespec fwp_period_t;
+
+/**
+ * FWP vres parameters
+ *
+ */
+typedef
+struct fwp_vres_params {
+ fwp_budget_t budget; /**< bytes per period */
+ /** all time units are in microseconds */
+ fwp_period_t period;
+ fwp_ac_t ac_id; /**< AC id ~ priority of vres */
+ struct in_addr src;
+} fwp_vres_params_t;
+
+fwp_vres_t *fwp_vres_alloc();
+int fwp_vres_set_params(fwp_vres_t *vres, fwp_vres_params_t *params);
+int fwp_vres_create(fwp_vres_params_t *params, fwp_vres_t **vresp);
+int fwp_vres_destroy(fwp_vres_t *vres);
+
+int fwp_vres_consume_budget(struct fwp_vres *vres, size_t size, bool can_block);
+struct fwp_endpoint;
+int fwp_vres_enqueue(struct fwp_vres *vres, struct fwp_endpoint *ep,
+ const void *msg, size_t size);
+int fwp_vres_bind(fwp_vres_t *vres, struct fwp_endpoint *ep, int sockd, struct in_addr *src);
+int fwp_vres_unbind(fwp_vres_t *vres);
+
+extern fwp_vres_params_t fwp_vres_params_default;
+
+#endif /* _FWP_INTERNALS_ */
+#endif /* _FWP_VRES_H */
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+SUBDIRS= fwp_msgtest fwp_vrestest fwp_prototest
+#fwp_prototest fwp_mngrtest
+#SUBDIRS= fwp_msgtest fwp_vrestest fwp_prototest fwp_mngrtest
+#fwp_mngrtest unixsocktest
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+test_PROGRAMS = fwp_msgtest
+CFLAGS+= -D_FWP_INTERNALS_
+fwp_msgtest_SOURCES+= fwp_msgtest.c
+lib_LOADLIBES += pthread rt fwp
--- /dev/null
+/**
+ * \file fwp_msgtest.c
+ *
+ * This is a test application for msg handling that
+ * - allocates two msgb
+ * - serializes two contracts into msgb
+ * - put both msgb to message queue
+ * - revert previous steps
+ * - compare contracts
+ */
+#include "fwp_msgq.h"
+#include "fwp_msgb.h"
+
+#include <semaphore.h>
+#include <stdio.h>
+
+int main(int argc, char** argv)
+{
+ struct fwp_msgq msgq;
+ struct fwp_msgb *msgb;
+ int val_w1 = 1;
+ int val_w2 = 2;
+ int val_r1, val_r2;
+ int nparams;
+
+ nparams = argc;
+ fwp_msgq_init(&msgq);
+ printf("in=%d out=%d pending=%d \n",msgq.in,msgq.out,msgq.nr_pending);
+
+ /* prepare and enqueue the first message buffer */
+ msgb = fwp_msgb_alloc(sizeof(val_w1));
+ if (!msgb) {
+ printf("Could not allocate msgb for message A\n");
+ return -1;
+ }else
+ printf("Message buffer for message A allocated\n");
+
+ memcpy(msgb->data, &val_w1, sizeof(val_w1));
+ printf("Enqueue message A. ");
+ if (!fwp_msgq_enqueue(&msgq, msgb))
+ printf("OK.\n");
+ else {
+ printf("Failed! \n");
+ return -1;
+ }
+
+ printf("in=%d out=%d pending=%d \n",msgq.in,msgq.out,msgq.nr_pending);
+ /* prepare and enqueue the second message buffer */
+ msgb = fwp_msgb_alloc(sizeof(val_w2));
+ if (!msgb) {
+ printf("Could not allocate msgb for message B\n");
+ return -1;
+ }else
+ printf("Message buffer for message B allocated\n");
+
+ memcpy(msgb->data, &val_w2, sizeof(val_w2));
+ printf("Enqueue message B. ");
+ if (!fwp_msgq_enqueue(&msgq, msgb))
+ printf("OK.\n");
+ else {
+ printf("Failed! \n");
+ return -1;
+ }
+
+ printf("in=%d out=%d pending=%d \n",msgq.in,msgq.out,msgq.nr_pending);
+
+ /* dequeue the first message and compare with original contract*/
+ printf("Dequeue message A. ");
+ msgb = fwp_msgq_dequeue(&msgq);
+ if (!msgb) {
+ printf("Failed! \n");
+ return -1;
+ }else
+ printf("OK.\n");
+
+ printf("in=%d out=%d pending=%d \n",msgq.in,msgq.out,msgq.nr_pending);
+
+ memcpy(&val_r1, msgb->data, sizeof(val_w1));
+ fwp_msgb_free(msgb);
+
+ if (val_w1 != val_r1) {
+ printf("Message A: W/R values do not match.\n");
+ return -1;
+ }
+ printf("Message A: W/R values matches.\n");
+
+
+ /* dequeue the second message and compare with original contract*/
+ printf("Dequeue message B. ");
+ msgb = fwp_msgq_dequeue(&msgq);
+ if (!msgb) {
+ printf("Failed! \n");
+ return -1;
+ }else
+ printf("OK.\n");
+
+ printf("in=%d out=%d pending=%d \n",msgq.in,msgq.out,msgq.nr_pending);
+
+ memcpy(&val_r2, msgb->data, sizeof(val_w2));
+ fwp_msgb_free(msgb);
+
+ if (val_w2 != val_r2) {
+ printf("Message B: W/R values do not match.\n");
+ return -1;
+ }
+ printf("Message B: W/R values matches.\n");
+
+ msgb = fwp_msgq_dequeue(&msgq);
+
+ if (msgb) {
+ printf("Message should be empty but is is not\n");
+ return -1;
+ }
+
+ printf("%s PASSED!\n", argv[0]);
+ return 0;
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+test_PROGRAMS = fwp_sendrecv_test1 fwp_sendrecv_test2
+CFLAGS+= -D_FWP_INTERNALS_
+fwp_sendrecv_test1_SOURCES+= fwp_sendrecv_test1.c
+fwp_sendrecv_test2_SOURCES+= fwp_sendrecv_test2.c
+lib_LOADLIBES += fwp pthread rt ulut
--- /dev/null
+/**
+ * \file fwp_sendrecv_test1.c
+ *
+ * This a test application that:
+ * - creates two vres without negotiation
+ * - creates send and receive endpoint
+ * - binds that endpoint to vres
+ * - sends two messages
+ * - receives messages
+ * - destroys vres
+ *
+ */
+#define CONFIGURE_FWP_MNGT 0
+#include "fwp_confdefs.h"
+#include "fwp.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <arpa/inet.h>
+
+int main()
+{
+// struct sockaddr_in local_addr, rem_addr, from;
+ ssize_t len;
+ fwp_vres_t *vres1, *vres2;
+ int i;
+ struct fwp_vres_params vparam1, vparam2;
+ char msg1[] = "Hello1";
+ char msg2[] = "Hello2";
+ char buffer[30];
+ struct fwp_endpoint *sepoint1, *sepoint2, *repoint1, *repoint2;
+ fwp_endpoint_attr_t attr;
+ fwp_addr_t from;
+
+ fwp_endpoint_attr_init(&attr);
+
+ vparam1.ac_id = FWP_AC_VO;
+ vparam1.budget = 100;
+ vparam1.period.tv_sec = 2;
+ vparam1.period.tv_nsec = 0;
+
+ vparam2.ac_id = FWP_AC_BK;
+ vparam2.budget = 100;
+ vparam2.period.tv_sec = 0;
+ vparam2.period.tv_nsec = 100000;
+
+ printf("Start\n");
+ fwp_init();
+
+ printf("Create vres1, vres2\n");
+ if (fwp_vres_create(&vparam1, &vres1) < 0) {
+ printf("Unable to create vres1\n");
+ return -1;
+ }
+ printf("Vres1 created \n");
+
+ if (fwp_vres_create(&vparam2, &vres2) < 0){
+ fprintf(stderr,"Unable to create vres2\n");
+ return -1;
+ }
+ printf("Vres2 created\n");
+
+ /* local_addr should be handled when creating socket */
+ if (fwp_receive_endpoint_create(7777, &attr,&repoint1) < 0){
+ return -1;
+ }
+ printf("Receive endpoint created\n");
+
+ if (fwp_receive_endpoint_create(7778, &attr,&repoint2) < 0){
+ return -1;
+ }
+ printf("Receive endpoint created\n");
+
+ if (fwp_send_endpoint_create(inet_addr("127.0.0.1"), 7777, 0,
+ &sepoint1) < 0) {
+ return -1;
+ }
+ printf("Send endpoint 1 created\n");
+ fwp_send_endpoint_bind(sepoint1, vres1);
+
+ if (fwp_send_endpoint_create(inet_addr("127.0.0.1"), 7778, 0,
+ &sepoint2) < 0){
+ return -1;
+ }
+ printf("Send endpoint 2 created\n");
+ fwp_send_endpoint_bind(sepoint2, vres2);
+
+ fwp_send_sync(sepoint1, msg1, sizeof(msg1));
+ fwp_send_sync(sepoint1, msg2, sizeof(msg2));
+
+ for (i = 0; i < 2; i++) {
+ if ((len = fwp_recv(repoint1, buffer, sizeof(buffer), &from,
+ 0)) < 0) {
+ perror("Error while receiving data");
+ return -1;
+ }
+ else printf("Received - %s\n", buffer);
+ }
+
+ if (fwp_vres_destroy(vres1) < 0) {
+ perror("Unable to destroy vres1\n");
+ return -1;
+ }
+ printf("Vres1 destroyed\n");
+
+ if (fwp_vres_destroy(vres2) < 0){
+ perror("Unable to destroy vres2\n");
+ return -1;
+ }
+ printf("Vres2 destroyed\n");
+
+ printf("Test PASSED!\n");
+ return 0;
+}
--- /dev/null
+/**
+ * \file fwp_sendrecv_test2.c
+ *
+ * This a test application that:
+ * - creates vres without negotiation
+ * - creates reliable send endpoint
+ * - cretaes receiver thread and receive endpoint within it
+ * - binds that endpoint to vres
+ * - sends two messages
+ * - receives messages
+ *
+ */
+#define CONFIGURE_FWP_MNGT 0
+#include "fwp_confdefs.h"
+#include "fwp.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <arpa/inet.h>
+
+#define MSGN 2
+
+fwp_endpoint_attr_t attr;
+
+void* receiver(void* arg)
+{
+ struct fwp_endpoint *repoint1;
+ int i,len;
+ char buffer[30];
+ fwp_addr_t from;
+
+ printf("Creating receive endpoint\n");
+ if (fwp_receive_endpoint_create(7777, &attr,&repoint1) < 0){
+ perror("Error while creating receive endpoint\n");
+ return NULL;
+ }
+
+ printf("Receive endpoint created \n");
+ for (i = 0; i < MSGN; i++) {
+ if ((len = fwp_recv(repoint1, buffer, sizeof(buffer), &from,
+ 0)) < 0) {
+ perror("Error while receiving data::");
+ return NULL;
+ } else {
+ printf("Received %s\n",buffer);
+ //for (j = 0 ; j < 10; i++)
+ // printf("%c", buffer[i]);
+
+ }
+ printf("END\n");
+ }
+
+ return NULL;
+}
+
+int main()
+{
+ fwp_vres_t *vres1;
+ struct fwp_vres_params vparam1, vparam2;
+ char msg1[] = "Hello1";
+ char msg2[] = "Hello2";
+ struct fwp_endpoint *sepoint1;
+ pthread_t thread;
+
+ vparam1.ac_id = FWP_AC_VO;
+ vparam1.budget = 100;
+ vparam1.period.tv_sec = 0;
+ vparam1.period.tv_nsec = 10000;
+
+ vparam2.ac_id = FWP_AC_BK;
+ vparam2.budget = 100;
+ vparam2.period.tv_sec = 0;
+ vparam2.period.tv_nsec = 100000;
+
+ printf("Start\n");
+ if (fwp_init() != 0) {
+ printf("FWP initialization failed!\n");
+ return -1;
+ }
+
+ fwp_endpoint_attr_init(&attr);
+ fwp_endpoint_attr_setreliability(&attr, FWP_EPOINT_RELIABLE);
+
+ pthread_create(&thread, NULL, &receiver, (void*) NULL);
+ printf("Create vres1, vres2\n");
+ if (fwp_vres_create(&vparam1, &vres1) < 0) {
+ printf("Unable to create vres1\n");
+ return -1;
+ }
+ printf("Vres1 created \n");
+
+ if (fwp_send_endpoint_create(inet_addr("127.0.0.1"), 7777, &attr,
+ &sepoint1) < 0) {
+ return -1;
+ }
+ printf("Send endpoint 1 created\n");
+ fwp_send_endpoint_bind(sepoint1, vres1);
+
+ fwp_send_sync(sepoint1, msg1, sizeof(msg1));
+ printf("Sent msg1\n");
+ fwp_send_sync(sepoint1, msg2, sizeof(msg2));
+ printf("Sent msg2\n");
+
+ pthread_join(thread, (void**) NULL);
+ /*if (fwp_vres_destroy(vres1) < 0) {
+ perror("Unable to destroy vres1\n");
+ return -1;
+ }
+ printf("Vres1 destroyed\n");
+
+ if (fwp_vres_destroy(vres2) < 0){
+ perror("Unable to destroy vres2\n");
+ return -1;
+ }
+ printf("Vres2 destroyed\n");
+ */
+
+ printf("Test PASSED!\n");
+ scanf("Press key");
+
+ return 0;
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+test_PROGRAMS = fwp_vrestest1 fwp_vrestest2
+CFLAGS+= -D_FWP_INTERNALS_
+fwp_vrestest1_SOURCES+= fwp_vrestest1.c
+fwp_vrestest2_SOURCES+= fwp_vrestest2.c
+lib_LOADLIBES += fwp pthread rt ulut
--- /dev/null
+/**
+ * \file fwp_vrestest1.c
+ *
+ * This a test application that:
+ * - creates vres without negotiation
+ * - creates send and receive endpoint
+ * - binds that endpoint to vres
+ * - in cycle (NUM loops) sends messages and prints send time
+ * - receives messages
+ * - destroys vres
+ *
+ */
+#define CONFIGURE_FWP_MNGT 0
+#include "fwp_confdefs.h"
+#include "fwp.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <arpa/inet.h>
+#include <time.h>
+
+#define NUM 10000
+
+int main()
+{
+// struct sockaddr_in local_addr, rem_addr, from;
+ ssize_t len;
+ fwp_vres_t *vres1, *vres2;
+ struct fwp_vres_params vparam1;
+ char msg1[15];
+ char buffer[30];
+ struct fwp_endpoint *sepoint, *repoint;
+ int count;
+ struct timespec sendtime;
+ fwp_endpoint_attr_t attr;
+ unsigned int from;
+
+ fwp_endpoint_attr_init(&attr);
+
+ vparam1.ac_id = FWP_AC_VO;
+ vparam1.budget = 100;
+ vparam1.period.tv_sec = 2;
+ vparam1.period.tv_nsec = 111111;
+
+ printf("Start\n");
+ if (fwp_init() != 0) {
+ printf("fwp_init failed!\n");
+ return -1;
+ }
+
+ printf("Create vres1\n");
+ if ((fwp_vres_create(&vparam1, &vres1) < 0)) {
+ printf("Unable to create vres1\n");
+ return -1;
+ }
+ printf("Vres1 created\n");
+
+ printf("Create vres2\n");
+ if ((fwp_vres_create(&vparam1, &vres2) < 0)) {
+ printf("Unable to create vres2\n");
+ return -1;
+ }
+ printf("Vres2 created\n");
+ /* local_addr should be handled when creating socket */
+ if (fwp_receive_endpoint_create(7777, &attr, &repoint) < 0) {
+ return -1;
+ }
+ printf("Receive endpoint created\n");
+
+ if (fwp_send_endpoint_create(inet_addr("127.0.0.1"), 7777, &attr,
+ &sepoint) < 0){
+ return -1;
+ }
+ printf("Send endpoint 1 created\n");
+ fwp_send_endpoint_bind(sepoint, vres1);
+
+ for (count = 0; count < NUM; count++) {
+ sprintf(msg1,"msg%d",count);
+ fwp_send_sync(sepoint, msg1, sizeof(msg1));
+
+ clock_gettime(CLOCK_MONOTONIC, &sendtime);
+ printf("Sent: sec = %ld nsec = %ld \n", sendtime.tv_sec,
+ sendtime.tv_nsec);
+
+ if ((len = fwp_recv(repoint, buffer, sizeof(buffer), &from, 0)) < 0) {
+ perror("Error while receiving data");
+ return -1;
+ }
+ else printf("Received - %s\n", buffer);
+ }
+
+ if (fwp_vres_destroy(vres1) < 0) {
+ perror("Unable to destroy vres1\n");
+ return -1;
+ }
+ printf("Vres1 detroyed\n");
+ printf("Test PASSED!\n");
+ return 0;
+}
--- /dev/null
+/**
+ * \file fwp_vrestest2.c
+ *
+ * This a test application that:
+ * - creates vres without negotiation
+ * - creates send and receive endpoint
+ * - binds that endpoint to vres
+ * - in cycle (NUM loops) sends messages in separate thread and
+ * prints send time
+ * - receives messages in separate receiver thread
+ * - destroys vres
+ *
+ */
+#define CONFIGURE_FWP_MNGT 0
+#include "fwp_confdefs.h"
+#include "fwp.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#include <arpa/inet.h>
+#include <fwp_utils.h>
+
+#define NUM 20
+#define PORT 65111
+
+int exit_flag = 0;
+fwp_endpoint_attr_t attr;
+
+void* sender()
+{
+ struct fwp_endpoint *sepoint;
+ fwp_vres_t *vres;
+ struct fwp_vres_params vparam1;
+ char msg1[10];
+ int count;
+ /*struct timespec sendtime;*/
+
+ vparam1.ac_id = FWP_AC_VO;
+ vparam1.budget = 3;
+ vparam1.period.tv_sec = 5;
+ vparam1.period.tv_nsec = 0;
+
+ printf("Create vres1\n");
+ if (fwp_vres_create(&vparam1, &vres) < 0) {
+ printf("Unable to open vres1\n");
+ return NULL;
+ }
+ printf("Vres1 created\n");
+
+ if (fwp_send_endpoint_create(inet_addr("127.0.0.1"), PORT, &attr,
+ &sepoint) < 0){
+ return NULL;
+ }
+ printf("Send endpoint 1 created\n");
+ fwp_send_endpoint_bind(sepoint, vres);
+
+ sleep(2);
+ //for (count = 0; count < NUM; count++) {
+ fwp_set_rt_prio(90);
+
+ count = 0;
+ while (count < NUM){
+ count++;
+ sprintf(msg1,"msg%d sent\n",count);
+ fwp_send_sync(sepoint, msg1, sizeof(msg1));
+
+ printf(msg1);
+ /*clock_gettime(CLOCK_MONOTONIC, &sendtime);
+ FWP_DEBUG("Sent %d: sec = %ld nsec = %ld \n", count,
+ sendtime.tv_sec, sendtime.tv_nsec);
+ usleep(1000);*/
+ }
+
+ while (!(exit_flag)) {
+ sleep(1);
+ }
+
+ if (fwp_vres_destroy(vres) < 0) {
+ perror("Unable to destroy vres1\n");
+ return NULL;
+ }
+ printf("Vres1 destroyed\n");
+
+ return NULL;
+}
+
+void* receiver()
+{
+ ssize_t len;
+ char buffer[30];
+ struct fwp_endpoint *repoint;
+ int count;
+ struct timespec recvtime;
+ fwp_addr_t from;
+
+ /* local_addr should be handled when creating socket */
+ if (fwp_receive_endpoint_create(PORT, &attr, &repoint) < 0){
+ perror("Not initialized\n");
+ return NULL;
+ }
+ printf("Receive endpoint created\n");
+
+ for (count = 1; count <= NUM; count++) {
+
+ if ((len = fwp_recv(repoint, buffer, sizeof(buffer), &from, 0)) < 0){
+ perror("Error while receiving data");
+ return NULL;
+ }
+ else printf("Received - %s\n", buffer);
+
+ clock_gettime(CLOCK_MONOTONIC, &recvtime);
+ printf("Received %d: sec = %ld nsec = %ld \n", count,
+ recvtime.tv_sec, recvtime.tv_nsec);
+ }
+
+ exit_flag = 1;
+
+ return NULL;
+}
+
+int main()
+{
+// struct sockaddr_in local_addr, rem_addr, from;
+ pthread_attr_t thattr;
+ pthread_t thread;
+
+ printf("Start\n");
+ fwp_init();
+
+ fwp_endpoint_attr_init(&attr);
+ pthread_attr_init(&thattr);
+ pthread_create(&thread, &thattr, sender, NULL);
+ pthread_create(&thread, &thattr, receiver, NULL);
+ pthread_join(thread, (void**) NULL);
+
+ printf("Test PASSED!\n");
+ return 0;
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+bin_PROGRAMS = frm_fwp
+frm_fwp_SOURCES = fwp_mngr.c fwp_admctrl.c
+frm_fwp_LIBS = frm forb contract fosa rt ulut fcb_client
+
+#include_HEADERS = res_fwp.h
+CFLAGS += -D_FWP_INTERNALS_
+lib_LOADLIBES+= frsh
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#include <fres_sa_scenario.h>
+#include <fwp.h>
+#include "fwp_idl.h"
+#include "fwp_admctrl.h"
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include "fwp_utils.h"
+
+UL_LOG_CUST(ulogd_fwp_admctrl);
+ul_log_domain_t ulogd_fwp_admctrl = {UL_LOGL_MSG, "fwp_admctrl"};
+UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(fwp_admctrl_logreg_domains, ulogd_fwp_admctrl);
+
+/* TODO: Find out the real value and determine what influences it (MTU
+ * of the interface minus header sizes?). */
+#define MTU 1472
+#define UDP_HEADER_SIZE 8
+#define IP_HEADER_SIZE 20
+#define LLC_HEADER_SIZE 2 /* ??? */
+#define MAC_HEADER_SIZE 26 /* With QoS field added */
+#define MAC_FCS_SIZE 4
+
+#define RTS_FRAME_SIZE 20
+#define CTS_FRAME_SIZE 14
+#define ACK_FRAME_SIZE 14
+
+#define ASLOTTIME_USEC 20 /* 802.11g-2003 p. 46 */
+#define ASIFSTIME_USEC 10
+#define ADIFSTIME_USEC (ASIFSTIME_USEC + 2*ASLOTTIME_USEC)
+#define AAIFSTIME_USEC(n) (ASIFSTIME_USEC + (n)*ASLOTTIME_USEC)
+
+/* Default values from 802.11e */
+const int aifsn[FWP_AC_NUM] = { 2, 2, 3, 7 };
+const int cwmin[FWP_AC_NUM] = { 3, 7, 15, 15 };
+
+/* Experimental konstants - weight of backoff */
+const int pisvejc[FWP_AC_NUM] = { 6, 5, 2, 2 };
+
+int fwp_reserved_utilization;
+
+/**
+ * Calucaltes frame duration in microseconds. If the real duration is
+ * represented by a fractional number, the value is rounded up.
+ *
+ * @param length Number of bytes in PSDU.
+ * @param rate_bps Transmit rate of PSDU. The rate should correspond
+ * to other parameters accoring to 19.3.2 (802.11g)
+ * @param erp_ofdm Whether Extended Rate PHY (part of 802.11g) and ERP-OFDM
+ * modulation is used.
+ * @param short_preamble Whether short preamble (HR/DSSS/short) is
+ * used (802.11b)
+ *
+ * @return The number of microseconds or a negative number in case of error.
+ */
+static int frame_duration(uint16_t length, int rate_bps, bool erp_ofdm, bool short_preamble)
+{
+ uint32_t duration_usec = 0;
+
+ if (!erp_ofdm) {
+ duration_usec = ((int64_t)(length) * 8 * SEC_TO_USEC / rate_bps);
+ if (short_preamble) {
+ /* For HR/DSSS/short (2, 5.5 and 11 Mbit,
+ * 802.11b-1999), also for DSSS-OFDM rates and
+ * ERP-PBCC rates.
+ * Preamble sent at 1 MBit, header at 2 Mbit */
+ duration_usec += 72/*bits*/+48/*bits*//2;
+ } else {
+ /* For DSSS PHY (1 and 2 Mbit rates,
+ * 802.11-1999) and for DSS-OFDM and ERP-PBCC
+ * rates. Always sent at 1 MBit */
+ duration_usec += 144/*bits*/+48/*bits*/;
+ }
+ } else {
+#define MBIT_TO_INDEX(rate_Mbps) ((rate_Mbps)/3 - 2)
+ const int N_dbps[] = {
+ [MBIT_TO_INDEX(6)] = 24,
+ [MBIT_TO_INDEX(9)] = 36,
+ [MBIT_TO_INDEX(12)] = 48,
+ [MBIT_TO_INDEX(18)] = 72,
+ [MBIT_TO_INDEX(24)] = 96,
+ [MBIT_TO_INDEX(36)] = 144,
+ [MBIT_TO_INDEX(48)] = 192,
+ [MBIT_TO_INDEX(54)] = 216
+ };
+ int rate_idx = MBIT_TO_INDEX(rate_bps/1000/1000);
+#undef MBIT_TO_INDEX
+ if (rate_idx < 0 ||
+ rate_idx >= sizeof(N_dbps)/sizeof(*N_dbps) ||
+ N_dbps[rate_idx] == 0)
+ return -1;
+
+ duration_usec += 16 + 4; /* Preamble, SIGNAL */
+ int bits =
+ 16 + /* SERVICE */
+ length * 8 +
+ 6; /* tail bits */
+ int Nsym = (bits + N_dbps[rate_idx] - 1)/N_dbps[rate_idx];
+
+ duration_usec += Nsym * 4;
+
+ duration_usec += 6; /* signal extension */
+ }
+ return duration_usec;
+}
+
+int fwp_admctrl_utilization(struct fres_sa_scenario *scenario, void *priv,
+ bool *schedulable)
+{
+ long long utilization = 0;
+ struct frm_fwp_priv *pr = priv;
+ const int rate = pr->rate_mbps*1000*1000;
+ struct fres_sa_contract *c;
+ long int period_usec;
+ fres_block_fwp_sched *fwp_sched;
+
+ size_t bytes;
+ long int duration_usec, tmp_usec;
+ int fragments;
+ int ac = FWP_AC_VO;
+
+ fres_sa_scenario_for_each_no_cancel_contract(scenario, c) {
+ fres_block_basic *basic;
+ char id[40];
+ fres_contract_id_to_string(id, &c->contract->id, sizeof(id));
+ basic = fres_contract_get_basic(c->contract);
+
+ frsh_network_budget_to_bytes(FRSH_NETPF_FWP,&basic->budget,&bytes);
+ ul_logmsg("processing: id=%s, period=%ld ms, budget=%lu bytes\n",
+ id,
+ fosa_rel_time_to_msec(basic->period),
+ (long unsigned int)bytes);
+
+ period_usec = basic ? fosa_rel_time_to_msec(basic->period)*1000 : 0;
+
+ /* Calculate protocol overhead */
+ fragments = (bytes + MTU - 1) / MTU;
+
+ if (fragments == 0 && period_usec != 0)
+ continue;
+
+ const int data_overhead = UDP_HEADER_SIZE + IP_HEADER_SIZE +
+ LLC_HEADER_SIZE + MAC_FCS_SIZE;
+
+ duration_usec = frame_duration(data_overhead + bytes%MTU, rate,
+ pr->erp_ofdm, pr->short_preamble);
+ tmp_usec = frame_duration(data_overhead + MTU, rate,
+ pr->erp_ofdm, pr->short_preamble);
+ duration_usec += tmp_usec*(fragments-1);
+ /* Add average backoff - assume there is no collision */
+ tmp_usec = ASLOTTIME_USEC*fragments*pisvejc[ac];
+ duration_usec += (aifsn[ac] + cwmin[ac]/2)*tmp_usec;
+ /* We use ACK and ignore burst */
+ tmp_usec = frame_duration(ACK_FRAME_SIZE, rate,
+ pr->erp_ofdm, pr->short_preamble)
+ + ASIFSTIME_USEC;
+ duration_usec += fragments * tmp_usec;
+ //printf("duration: %ld ms\n", duration_usec/1000);
+
+ /* TODO: If STA-to-STA, multiply it by two. Note that
+ * AP may use different values for backoff. */
+ duration_usec *= 2; /* For demo, we have always STA-to-STA */
+
+ if (c->contract == c->new) {
+ if (period_usec == 0) {
+ ul_logmsg("Period is zero!\n");
+ goto not_schedulable;
+ }
+
+ frsh_rel_time_t deadline;
+ long int d;
+ if (fres_contract_get_deadline(&c->contract, &deadline)) {
+ d = fosa_rel_time_to_msec(deadline)*1000;
+ } else {
+ d = 100/*sec*/*1000*1000;
+ }
+ if (d < 30/*msec*/*1000) {
+ ul_logmsg("Deadline shorter than 30 ms!\n");
+ goto not_schedulable;
+ };
+
+ fwp_sched = malloc(sizeof(*fwp_sched));
+ fwp_sched->ac_id =
+ d < 100*1000 ? FWP_AC_VO :
+ d < 500*1000 ? FWP_AC_VI :
+ d < 1000*1000 ? FWP_AC_BE :
+ FWP_AC_BK;
+ fres_contract_add_block(c->contract, FRES_BLOCK_FWP_SCHED, fwp_sched);
+ }
+
+ utilization += (long long)duration_usec * 10000 / period_usec;
+ }
+
+ if (utilization >= 10000 * 96/100 && !pr->bypass) {
+ goto not_schedulable;
+ }
+ scenario->utilization = utilization/100; /* For GUI */
+
+ ul_logmsg("accepted (utilization=%lld%%)\n", utilization/100);
+ *schedulable = true;
+ return 0;
+
+not_schedulable:
+ ul_logmsg("rejected (utilization=%lld%%)\n", utilization/100);
+ *schedulable = false;
+ return 0;
+}
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#ifndef _FWP_ADMCTRL_H
+#define _FWP_ADMCTRL_H
+
+#include <frsh_distributed.h>
+
+struct frm_fwp_priv {
+ int rate_mbps;
+ bool erp_ofdm;
+ bool short_preamble;
+ bool bypass;
+};
+
+int fwp_admctrl_utilization(struct fres_sa_scenario *scenario, void *priv,
+ bool *schedulable);
+
+#endif /*_FWP_AMDCTRL_H */
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FWP (Frescor WLAN Protocol) */
+/* */
+/* FWP is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FWP is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FWP; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FWP header files in a file, */
+/* instantiating FWP generics or templates, or linking other files */
+/* with FWP objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+#include <frm_generic.h>
+#include <forb.h>
+#include <error.h>
+#include <errno.h>
+#include <getopt.h>
+#include <fres_sa_scenario.h>
+#include <stdbool.h>
+#include <ul_log.h>
+#include <ul_logreg.h>
+#include <fwp_res.h>
+#include <stdio.h>
+#include "fwp_admctrl.h"
+
+#if 0
+static
+int dummy_admission_test(struct fres_sa_scenario *scenario, void *priv,
+ bool *schedulable)
+{
+ struct fres_sa_contract *c;
+
+ printf("Dummy admission test:\n");
+
+ fres_sa_scenario_for_each_no_cancel_contract(scenario, c) {
+ fres_block_basic *basic;
+ char id[40];
+ fres_contract_id_to_string(id, &c->contract->id, sizeof(id));
+ basic = fres_contract_get_basic(c->contract);
+
+ printf(" processing: id=%s, period=%ld ms, budget=%ld ms\n",
+ id,
+ fosa_rel_time_to_msec(basic->period),
+ fosa_rel_time_to_msec(basic->budget));
+
+ }
+ *schedulable = scenario->num_contracts <= 3;
+ printf("=> %s\n", schedulable?"schedulable":"not schedulable");
+
+ return 0;
+}
+#endif
+
+struct frm_fwp_priv priv = {
+ .rate_mbps = 1,
+ .erp_ofdm = false,
+ .short_preamble = false,
+};
+
+static const struct fres_res_manager frm = {
+ .res_type = FRSH_RT_NETWORK,
+ .res_id = FRSH_NETPF_FWP,
+ //.admission_test = dummy_admission_test,
+ .name = "WLAN",
+ .admission_test = fwp_admctrl_utilization,
+ .priv = &priv,
+};
+
+static struct option long_opts[] = {
+ { "loglevel", required_argument, 0, 'l' },
+ { "bitrate", required_argument, 0, 'b' },
+ { "ofdm", no_argument, 0, 'o' },
+ { "short-preamble", no_argument, 0, 's' },
+ { 0, 0, 0, 0}
+};
+
+static void
+usage(void)
+{
+ printf("usage: fwpmngr [ options ]\n");
+ printf(" -l, --loglevel <number>|<domain>=<number>,...\n");
+ printf(" -b, --bitrate <mbits/s>\n");
+ printf(" -o, --ofdm\n");
+ printf(" -s, --short-preamble\n");
+ printf(" -h, --help\n");
+}
+
+int main(int argc, char *argv[])
+{
+ forb_orb orb;
+ int ret;
+ forb_init_attr_t attr = { .orb_id = "org.frescor.frm.fwp" };
+ int opt;
+ bool opt_daemon = false;
+ char *opt_pidfile = NULL;
+
+ if (getenv("FWP_BYPASS"))
+ priv.bypass = true;
+
+
+ while ((opt = getopt_long(argc, argv, "b:d:hl:os", &long_opts[0], NULL)) != EOF) {
+ switch (opt) {
+ case 'd':
+ opt_daemon = true;
+ opt_pidfile = optarg;
+ break;
+ case 'l':
+ ul_log_domain_arg2levels(optarg);
+ break;
+ case 'b':
+ priv.rate_mbps = atol(optarg);
+ break;
+ case 's':
+ priv.short_preamble = true;
+ break;
+ case 'o':
+ priv.erp_ofdm = true;
+ break;
+ case 'h':
+ /*default:*/
+ usage();
+ exit(opt == 'h' ? 0 : 1);
+ }
+ }
+
+ if (opt_daemon)
+ forb_daemon_prepare(opt_pidfile);
+
+ orb = forb_init(&argc, &argv, &attr);
+ if (!orb) error(1, errno, "forb_init");
+
+ fres_block_register_fwp();
+ ret = frm_register_and_run(orb, &frm);
+
+ if (ret != 0) {
+ error(1, errno, "frm_generic_run");
+ }
+
+ return 0;
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+bin_PROGRAMS = fwpmngr
+CFLAGS += -Wall -D_REENTRANT -g -D_FWP_INTERNALS_
+#fwpagent_SOURCES+= fwp_agent.c
+#fwpmngr_SOURCES+= fwp_participant.c fwp_mngr.c fwp_contract_table.c\
+ fwp_agent_table.c fwp_admctrl.c
+fwpmngr_SOURCES+= fwp_mngr.c
+fwpmngr_SOURCES+= fwp_admctrl.c
+fwpmngr_SOURCES+= admtest_utilization.c
+#fwpmngr_SOURCES+= gui.c
+
+lib_LOADLIBES+= fwp ulut pthread rt
+#lib_LOADLIBES+= fwp ulut pthread rt ncurses
+
--- /dev/null
+#include "fwp_admctrl.h"
+#include <fwp_utils.h>
+#include <stdint.h>
+#include <fwp_conf.h>
+#include <stdbool.h>
+#include <fwp_participant.h>
+#include "fwp_participant_table.h"
+#include "fwp_foreach.h"
+
+/* TODO: Find out the real value and determine what influences it (MTU
+ * of the interface minus header sizes?). */
+#define MTU 1472
+#define UDP_HEADER_SIZE 8
+#define IP_HEADER_SIZE 20
+#define LLC_HEADER_SIZE 2 /* ??? */
+#define MAC_HEADER_SIZE 26 /* With QoS field added */
+#define MAC_FCS_SIZE 4
+
+#define RTS_FRAME_SIZE 20
+#define CTS_FRAME_SIZE 14
+#define ACK_FRAME_SIZE 14
+
+#define BITRATE_BPS (1000*1000)
+#define ASLOTTIME_USEC 20 /* 802.11g-2003 p. 46 */
+#define ASIFSTIME_USEC 10
+#define ADIFSTIME_USEC (ASIFSTIME_USEC + 2*ASLOTTIME_USEC)
+#define AAIFSTIME_USEC(n) (ASIFSTIME_USEC + (n)*ASLOTTIME_USEC)
+
+#define TXTIME_USEC(bytes) ((int64_t)(bytes) * 8 * SEC_TO_USEC / BITRATE_BPS)
+
+
+/* Default values from 802.11e */
+const int aifsn[FWP_AC_NUM] = { 2, 2, 3, 7 };
+const int cwmin[FWP_AC_NUM] = { 3, 7, 15, 15 };
+
+/* Experimental konstants - weight of backoff */
+const int pisvejc[FWP_AC_NUM] = { 6, 5, 2, 2 };
+
+int fwp_reserved_utilization;
+
+/**
+ * Calucaltes frame duration in microseconds. If the real duration is
+ * represented by a fractional number, the value is rounded up.
+ *
+ * @param length Number of bytes in PSDU.
+ * @param rate_bps Transmit rate of PSDU. The rate should correspond
+ * to other parameters accoring to 19.3.2 (802.11g)
+ * @param erp_ofdm Whether Extended Rate PHY (part of 802.11g) and ERP-OFDM
+ * modulation is used.
+ * @param short_preamble Whether short preamble (HR/DSSS/short) is
+ * used (802.11b)
+ *
+ * @return The number of microseconds or a negative number in case of error.
+ */
+static int frame_duration(uint16_t length, int rate_bps, bool erp_ofdm, bool short_preamble)
+{
+ uint32_t duration_usec;
+
+ if (!erp_ofdm) {
+ duration_usec = ((int64_t)(length) * 8 * SEC_TO_USEC / rate_bps);
+ if (short_preamble) {
+ /* For HR/DSSS/short (2, 5.5 and 11 Mbit,
+ * 802.11b-1999), also for DSSS-OFDM rates and
+ * ERP-PBCC rates.
+ * Preamble sent at 1 MBit, header at 2 Mbit */
+ duration_usec += 72/*bits*/+48/*bits*//2;
+ } else {
+ /* For DSSS PHY (1 and 2 Mbit rates,
+ * 802.11-1999) and for DSS-OFDM and ERP-PBCC
+ * rates. Always sent at 1 MBit */
+ duration_usec += 144/*bits*/+48/*bits*/;
+ }
+ } else {
+#define MBIT_TO_INDEX(rate_Mbps) ((rate_Mbps)/3 - 2)
+ const int N_dbps[] = {
+ [MBIT_TO_INDEX(6)] = 24,
+ [MBIT_TO_INDEX(9)] = 36,
+ [MBIT_TO_INDEX(12)] = 48,
+ [MBIT_TO_INDEX(18)] = 72,
+ [MBIT_TO_INDEX(24)] = 96,
+ [MBIT_TO_INDEX(36)] = 144,
+ [MBIT_TO_INDEX(48)] = 192,
+ [MBIT_TO_INDEX(54)] = 216
+ };
+ int rate_idx = MBIT_TO_INDEX(rate_bps/1000/1000);
+#undef MBIT_TO_INDEX
+ if (rate_idx < 0 ||
+ rate_idx >= sizeof(N_dbps)/sizeof(*N_dbps) ||
+ N_dbps[rate_idx] == 0)
+ return -1;
+
+ duration_usec += 16 + 4; /* Preamble, SIGNAL */
+ int bits =
+ 16 + /* SERVICE */
+ length * 8 +
+ 6; /* tail bits */
+ int Nsym = (bits + N_dbps[rate_idx] - 1)/N_dbps[rate_idx];
+
+ duration_usec += Nsym * 4;
+
+ duration_usec += 6; /* signal extension */
+ }
+ return duration_usec;
+}
+
+void fwp_admctrl_utilization(fwp_contract_data_t *contdata_new)
+{
+ int utilization = 0;
+
+ const int rate = 1*1000*1000;
+ const bool erp_ofdm = false;
+ const bool short_preamble = false;
+ fwp_contract_data_t *contdata;
+
+ struct foreach_contract fec;
+ fec.contdata_new = contdata_new;
+
+ for (contdata=foreach_contract_begin(&fec);
+ contdata;
+ contdata=foreach_contract_next(&fec)) {
+ int bytes, duration_usec, fragments;
+ struct fwp_contract *contract = &contdata->contract;
+ int ac = FWP_AC_VO; /* FIXME: assign to AC before this
+ * loop based on deadlines */
+ /* Calculate protocol overhead */
+
+ bytes = contract->budget;
+ fragments = (bytes + MTU - 1) / MTU;
+
+ if (fragments == 0)
+ continue;
+
+ const int data_overhead = UDP_HEADER_SIZE + IP_HEADER_SIZE +
+ LLC_HEADER_SIZE + MAC_FCS_SIZE;
+
+ duration_usec = frame_duration(data_overhead + bytes%MTU, rate, erp_ofdm, short_preamble);
+ duration_usec += frame_duration(data_overhead + MTU, rate, erp_ofdm, short_preamble)*(fragments-1);
+
+ /* Add average backoff - assume there is no collision */
+ duration_usec += (aifsn[ac] + cwmin[ac]/2)*ASLOTTIME_USEC*fragments*pisvejc[ac];
+ /* We use ACK and ignore burst */
+ duration_usec += fragments * (ASIFSTIME_USEC +
+ frame_duration(ACK_FRAME_SIZE, rate, erp_ofdm, short_preamble));
+
+ /* TODO: If STA-to-STA, multiply it by two. Note that
+ * AP may use different values for backoff. */
+ duration_usec *= 2; /* For demo, we have always STA-to-STA */
+ if (contract->period_usec == 0) {
+ if (contdata == contdata_new) {
+ contdata->status = FWP_CONT_NOTNEGOTIATED;
+ return;
+ }
+ }
+ utilization += (long long)(duration_usec * 10000) / contract->period_usec;
+ }
+
+ if (contdata_new) {
+ if (utilization >= 10000 * 96/100) {
+ contdata_new->status = FWP_CONT_NOTNEGOTIATED;
+ } else {
+ struct fwp_contract *c = &contdata_new->contract;
+ int d = c->deadline_usec;
+ if (d <= 0) d = 100*1000*1000;
+ if (d < 50000) {
+ contdata_new->status = FWP_CONT_NOTNEGOTIATED;
+ } else {
+ contdata_new->status = FWP_CONT_RESERVED;
+ }
+
+ contdata_new->vres_params.ac_id =
+ d < 100*1000 ? FWP_AC_VO :
+ d < 500*1000 ? FWP_AC_VI :
+ d < 1000*1000 ? FWP_AC_BE :
+ FWP_AC_BK;
+ contdata_new->vres_params.budget = c->budget;
+ contdata_new->vres_params.period_usec = c->period_usec;
+ }
+ }
+
+ /* Update utilization for GUI */
+ if (contdata_new == NULL || contdata_new->status == FWP_CONT_RESERVED) {
+ fwp_reserved_utilization = utilization;
+ }
+}
--- /dev/null
+#include "fwp_admctrl.h"
+#include "fwp_vres.h"
+
+static int nr_negotiated =0;
+/***/
+
+void fwp_admctrl_stupid(fwp_contract_data_t *contdata)
+{
+ contdata->vres_params.ac_id = FWP_AC_VI;
+ contdata->vres_params.budget = 100;
+ contdata->vres_params.period_usec = 20;
+
+ if (nr_negotiated <= 4) {
+ nr_negotiated++;
+ contdata->status = FWP_CONT_RESERVED;
+ }
+}
--- /dev/null
+#ifndef _FWP_ADMCTRL_H
+#define _FWP_ADMCTRL_H
+
+#include "fwp_contract_table.h"
+
+typedef void (*fwp_admctrl_test_t)(fwp_contract_data_t *contdata);
+
+void fwp_admctrl_stupid(fwp_contract_data_t *contdata);
+void fwp_admctrl_utilization(fwp_contract_data_t *contdata);
+
+extern int fwp_reserved_utilization;
+
+#endif /*_FWP_AMDCTRL_H */
--- /dev/null
+#ifndef FWP_FOREACH_H
+#define FWP_FOREACH_H
+
+#include <fwp_participant.h>
+#include "fwp_participant_table.h"
+
+struct foreach_contract {
+ fwp_participant_t *participant; /**< Current participant */
+ fwp_contract_data_t *contdata; /**< Current contract */
+ fwp_contract_data_t *contdata_new; /**< The contract being negotiated */
+};
+
+static inline fwp_contract_data_t *foreach_contract_begin(struct foreach_contract *fec)
+{
+ fec->contdata = NULL;
+ fec->participant = fwp_participant_table_foreach_begin();
+ while (1) {
+ if (fec->participant) {
+ fec->contdata= fwp_contract_table_foreach_begin
+ (&fec->participant->contract_table);
+ } else {
+ break;
+ }
+ if (fec->contdata == NULL) {
+ fwp_contract_table_foreach_end(&fec->participant->contract_table);
+ fec->participant = fwp_participant_table_foreach_next(fec->participant);
+ continue;
+ }
+ break;
+ };
+
+ if (fec->contdata == NULL) {
+ fwp_participant_table_foreach_end();
+ fec->contdata = fec->contdata_new;
+ }
+ return fec->contdata;
+}
+
+static inline fwp_contract_data_t *foreach_contract_next(struct foreach_contract *fec)
+{
+ if (fec->contdata == fec->contdata_new) {
+ /* This was the last contract */
+ return NULL;
+ }
+ fec->contdata=fwp_contract_table_foreach_next(&fec->participant->contract_table,
+ fec->contdata);
+ while (1) {
+ if (fec->contdata == NULL) {
+ fwp_contract_table_foreach_end(&fec->participant->contract_table);
+ fec->participant = fwp_participant_table_foreach_next(fec->participant);
+ if (fec->participant == NULL) {
+ break;
+ }
+ fec->contdata= fwp_contract_table_foreach_begin(
+ &fec->participant->contract_table);
+ continue;
+ }
+ break;
+ };
+
+ if (fec->contdata == NULL) {
+ fwp_participant_table_foreach_end();
+ fec->contdata = fec->contdata_new;
+ }
+ return fec->contdata;
+}
+
+#endif
--- /dev/null
+#define CONFIGURE_FWP_MY_STREAM_ID 3000
+#define CONFIGURE_FWP_MNGR_ADDR "127.0.0.1"
+
+#include <error.h>
+#include <errno.h>
+#include "fwp_confdefs.h"
+#include "fwp.h"
+
+#include "fwp_contract_table.h"
+#include "fwp_participant_table.h"
+#include "fwp_admctrl.h"
+#include "fwp_mngt.h"
+#include "gui.h"
+
+#define FWP_MTU 2346
+#define BUFFSIZE FWP_MTU
+
+/* Admission control test */
+fwp_admctrl_test_t fwp_admctrl_test = &fwp_admctrl_utilization;
+
+/**
+ * fwp_mngt_input
+ *
+ * Function waits for remote or local message
+ *
+ * @msgb received message
+ * \return
+ * On success, it returns 0 and the pointer to received message in msgb parameter.
+ * On error, it returns negative error code
+ *
+ */
+int fwp_mngr_input(struct fwp_msgb **pmsgb)
+{
+ /* buffer and socket for incomming message */
+ static unsigned char buffer[FWP_MTU];
+ struct fwp_msgb *msgb;
+ ssize_t size, expected;
+ struct fwp_msg_header *header = (void*)buffer;
+
+ FWP_DEBUG("Waiting for messages\n");
+ /* TODO: consider to replace with fwp_mngt_recv call */
+ size = fwp_recv(fwp_participant_this->epointd, buffer, sizeof(*header), 0);
+ if (size < 0) {
+ return size;
+ }
+ if (size < sizeof(*header)) {
+ return -EPROTO;
+ /* TODO: Use errno for error reporting */
+ }
+ expected = ntohs(header->length)-sizeof(*header);
+ size = fwp_recv(fwp_participant_this->epointd, buffer+size,
+ expected, 0);
+ if (size < expected) {
+ return -EPROTO;
+ }
+
+ /* For future: fwp_socket could be allocated behind data in msgb*/
+ if (!(msgb = fwp_msgb_alloc(ntohs(header->length)))) {
+ perror("No memory available.\n");
+ return -ENOMEM;
+ }
+ /*memcpy(fwp_msgb_put(msgb, len), buffer, len); */
+ msgb->data = buffer;
+ fwp_msgb_put(msgb, ntohs(header->length));
+
+ *pmsgb = msgb;
+ return (0);
+}
+
+/**
+ * Processes hello message.
+ *
+ * @param msgb
+ * @param participant_id
+ *
+ * @return Zero on success, -1 on error.
+ */
+int fwp_mngr_hello(fwp_msgb_t *msgb, fwp_participant_id_t participant_id)
+{
+ fwp_participant_info_t participant_info, my_info;
+ fwp_participant_t *participant;
+ fwp_endpoint_attr_t attr;
+ int ret;
+
+ FWP_DEBUG("Received HELLO msg from nodeid= %d appid= %d\n",
+ participant_id.node_id, participant_id.app_id);
+
+ fwp_endpoint_attr_init(&attr);
+ fwp_endpoint_attr_setreliability(&attr, FWP_MNGT_RELIABILITY);
+ /* Create a new participant */
+ fwp_msg_hello_out(msgb->data, &participant_info);
+ participant = fwp_participant_new(&participant_info);
+ if (!participant)
+ return -1;
+ ret = fwp_mngt_service_vres_create(&participant->service_contract,
+ &participant->vresd);
+ if (ret < 0)
+ goto err_vres;
+ ret = fwp_send_endpoint_create(participant->id.node_id, participant->stream_id,
+ &attr, &participant->epointd);
+ if (ret < 0)
+ goto err_endpoint;
+ ret = fwp_send_endpoint_bind(participant->epointd, participant->vresd);
+ if (ret < 0)
+ goto err_bind;
+ fwp_contract_table_init(&participant->contract_table);
+
+ /* Insert participant into table */
+ fwp_participant_table_insert(participant);
+
+ /* Send back hello msg with mngr`s info */
+ /* prepare hello message */
+ fwp_msgb_reset_data(msgb);
+ fwp_msgb_reserve(msgb, sizeof(struct fwp_msg_header));
+
+ my_info.id = fwp_participant_this->id;
+ my_info.stream_id = fwp_participant_this->stream_id;
+
+ fwp_msg_hello_in(msgb->tail, &my_info);
+ fwp_msgb_put(msgb, sizeof(struct fwp_msg_hello));
+
+ /* Send hello to manager */
+ ret = fwp_mngt_send(FWP_MSG_HELLO, msgb,
+ fwp_participant_this, participant);
+ if (ret < 0)
+ goto err_send;
+
+ FWP_DEBUG("Sent HELLO msg from nodeid= %d appid= %d\n",
+ participant_id.node_id, participant_id.app_id);
+ return 0;
+err_send:
+ fwp_send_endpoint_unbind(participant->epointd);
+err_bind:
+ fwp_endpoint_destroy(participant->epointd);
+err_endpoint:
+ /* FIXME: This function is probably not the opposite of
+ * fwp_mngt_service_vres_create(), beacuse it doesn't delete
+ * the service contract. */
+ /*fwp_vres_destroy(participant->vresd);*/
+ fwp_contract_destroy(participant->service_contract);
+err_vres:
+ fwp_participant_delete(participant);
+ return -1;
+}
+
+int fwp_mngr_bye(fwp_msgb_t *msgb, fwp_participant_id_t participant_id)
+{
+ fwp_participant_t *participant;
+ fwp_contract_data_t* contdata;
+
+ /* Find participant */
+ if (!(participant = fwp_participant_table_find(&participant_id))){
+ return -EPERM;
+ }
+
+ /* TODO: Check for errors */
+ fwp_participant_table_delete(participant);
+ fwp_send_endpoint_unbind(participant->epointd);
+ fwp_endpoint_destroy(participant->epointd);
+ fwp_contract_destroy(participant->service_contract);
+ //fwp_vres_destroy(participant->vresd);
+
+ /* Delete all participant's contracts */
+ for (contdata = fwp_contract_table_foreach_begin(&participant->contract_table);
+ contdata;
+ contdata = fwp_contract_table_foreach_next(&participant->contract_table, contdata)) {
+ fwp_contract_destroy(contdata);
+ }
+ fwp_contract_table_foreach_end(&participant->contract_table);
+
+ fwp_participant_delete(participant);
+
+ FWP_DEBUG("BYE nodeid = %d appid = %d\n", participant_id.node_id,
+ participant_id.app_id);
+
+ return 0;
+}
+
+int
+fwp_mngr_contract_reserve(fwp_msgb_t *msgb, fwp_participant_id_t participant_id)
+{
+ fwp_participant_t *participant;
+ fwp_contract_data_t *contdata;
+
+ /* Find participant */
+ if (!(participant = fwp_participant_table_find(&participant_id))){
+ return -EPERM;
+ }
+
+ contdata = fwp_contract_data_new();
+
+ /* Extract contract header */
+ fwp_msg_contracthdr_out(msgb->data, &contdata->id, &contdata->status);
+ fwp_msgb_pull(msgb, sizeof(struct fwp_msg_contracthdr));
+ /* Extract contract params */
+ fwp_msg_contract_out(msgb->data, &contdata->contract);
+ fwp_msgb_pull(msgb, sizeof(struct fwp_msg_contract));
+
+ /*launch admission test */
+ fwp_admctrl_test(contdata);
+
+ free(msgb);
+ msgb = fwp_msgb_alloc(sizeof(struct fwp_msg_header) +
+ sizeof(struct fwp_msg_contract) +
+ sizeof(struct fwp_msg_vres_params));
+ fwp_msgb_reserve(msgb,sizeof(struct fwp_msg_header));
+
+ /*Add contract header*/
+ fwp_msg_contracthdr_in(msgb->tail, contdata->id, contdata->status);
+ fwp_msgb_put(msgb, sizeof(struct fwp_msg_contracthdr));
+ /* Add contract params */
+ /* No needed to send back if spare capacity is not considered
+ * fwp_msg_contract_in(msgb->tail, &contdata->contract);
+ * fwp_msgb_put(msgb, sizeof(struct fwp_msg_contract));
+ * */
+
+ /*Send back contract reservation */
+ if (contdata->status == FWP_CONT_RESERVED) {
+ fwp_msg_vres_params_in(msgb->tail, &contdata->vres_params);
+ FWP_DEBUG("Sent vres params budget=%d period=%d ac=%d\n",
+ contdata->vres_params.budget,
+ contdata->vres_params.period_usec,
+ contdata->vres_params.ac_id);
+ fwp_msgb_put(msgb, sizeof(struct fwp_msg_vres_params));
+ /* Add contract to contract table */
+ fwp_contract_table_insert(&participant->contract_table,contdata);
+ FWP_DEBUG("Contract id=%d stored in table\n", contdata->id);
+
+ } else {
+ free(contdata);
+ }
+
+ fwp_mngt_send(FWP_MSG_RESERVE, msgb,
+ fwp_participant_this, participant);
+ return 0;
+}
+
+int
+fwp_mngr_contract_commit(fwp_msgb_t *msgb, fwp_participant_id_t participant_id)
+{
+ fwp_participant_t *participant;
+ fwp_contract_data_t *contdata;
+ fwp_contract_id_t id;
+ fwp_contract_status_t status;
+
+ /* Find participant */
+ if (!(participant = fwp_participant_table_find(&participant_id))){
+ return -EPERM;
+ }
+
+ fwp_msg_contracthdr_out(msgb->data, &id, &status);
+ fwp_msgb_pull(msgb, sizeof(struct fwp_msg_contracthdr));
+ FWP_DEBUG("Contract id=%d to commit\n", id);
+
+ contdata = fwp_contract_table_find(&participant->contract_table, id);
+ contdata->status = FWP_CONT_NEGOTIATED;
+
+ /* TODO: Send response to confirm reception */
+
+ return 0;
+}
+
+int
+fwp_mngr_contract_cancel(fwp_msgb_t *msgb, fwp_participant_id_t participant_id)
+{
+ fwp_participant_t *participant;
+ fwp_contract_data_t *contdata;
+ fwp_contract_id_t id;
+ fwp_contract_status_t status;
+
+ /* Find participant */
+ if (!(participant = fwp_participant_table_find(&participant_id))){
+ return -EPERM;
+ }
+
+ fwp_msg_contracthdr_out(msgb->data, &id, &status);
+ fwp_msgb_pull(msgb, sizeof(struct fwp_msg_contracthdr));
+
+ contdata = fwp_contract_table_find(&participant->contract_table, id);
+ contdata->status = FWP_CONT_NOTNEGOTIATED;
+ /* release vres - success only for local vres */
+ fwp_vres_destroy(contdata->vresd);
+ /* delete contract from contract table */
+ fwp_contract_table_delete(&participant->contract_table, contdata);
+ fwp_contract_destroy(contdata);
+
+ /* Update admission data (only necessary for demo and GUI) */
+ fwp_admctrl_test(NULL);
+
+ FWP_DEBUG("Contract id=%d to canceled\n", id);
+
+ return 0;
+}
+
+void fwp_mngr_msg_handler(fwp_msgb_t *msgb)
+{
+ fwp_msg_type_t msg_type;
+ fwp_participant_id_t participant_id;
+ int ret = 0;
+
+ fwp_msg_header_out(msgb->data, &msg_type, &participant_id);
+ fwp_msgb_pull(msgb, sizeof(struct fwp_msg_header));
+
+ switch (msg_type) {
+ case FWP_MSG_HELLO:
+ FWP_DEBUG("Message HELLO received from nodeid = %d "
+ "appid = %d\n", participant_id.node_id,
+ participant_id.app_id);
+ ret = fwp_mngr_hello(msgb, participant_id);
+ if (ret < 0) {
+ ret = fwp_mngr_bye(msgb, participant_id);
+ if (ret < 0) {
+ error(0, errno, "Cannot send bye");
+ }
+ }
+ break;
+
+ case FWP_MSG_BYE:
+ FWP_DEBUG("Message BYE received from nodeid = %d "
+ "appid = %d\n", participant_id.node_id,
+ participant_id.app_id);
+ fwp_mngr_bye(msgb, participant_id);
+ break;
+
+
+ case FWP_MSG_RESERVE:
+ FWP_DEBUG("Message RESERVE received from nodeid = %d "
+ "appid = %d\n", participant_id.node_id,
+ participant_id.app_id);
+ fwp_mngr_contract_reserve(msgb, participant_id);
+ break;
+
+ case FWP_MSG_COMMIT:
+ FWP_DEBUG("Message COMMIT received from nodeid = %d "
+ "appid = %d\n", participant_id.node_id,
+ participant_id.app_id);
+ fwp_mngr_contract_commit(msgb, participant_id);
+ break;
+
+ case FWP_MSG_CANCEL:
+ FWP_DEBUG("Message CANCEL received from nodeid = %d "
+ "appid = %d\n", participant_id.node_id,
+ participant_id.app_id);
+ fwp_mngr_contract_cancel(msgb, participant_id);
+ break;
+
+ default:
+ printf("Invalid message\n.");
+ fwp_msgb_free(msgb);
+ }
+}
+
+void fwp_mngr_main_loop()
+{
+ struct fwp_msgb *msgb;
+ int rv;
+
+ /* start admission control thread */
+ while (1 /*exit_flag*/){
+ //gui_print_status();
+ rv = fwp_mngr_input(&msgb);
+ if (rv == 0 && msgb)
+ fwp_mngr_msg_handler(msgb);
+ FWP_DEBUG("Mngr waiting for next msg.\n");
+ }
+}
+
+int main()
+{
+ if (fwp_init()) {
+ fprintf(stderr,"FWP manager initialization failed.\n");
+ exit(1);
+ }
+
+ //gui_init();
+ fwp_mngr_main_loop();
+ //gui_end();
+
+ return 0;
+}
--- /dev/null
+#include "fwp_participant_table.h"
+#include <pthread.h>
+
+typedef
+struct {
+ unsigned int nr_participants;
+ /*gavl_cust_root_field_t root;*/
+ gavl_node_t *participant_tree;
+ pthread_mutex_t lock;
+} fwp_participant_table_t;
+
+int fwp_cmp_participant_id(const void *a, const void *b)
+{
+ if (((fwp_participant_id_t*)a)->node_id > ((fwp_participant_id_t*)b)->node_id)
+ return 1;
+ if (((fwp_participant_id_t*)a)->node_id < ((fwp_participant_id_t*)b)->node_id)
+ return -1;
+
+ if (((fwp_participant_id_t*)a)->app_id > ((fwp_participant_id_t*)b)->app_id)
+ return 1;
+ if (((fwp_participant_id_t*)a)->app_id < ((fwp_participant_id_t*)b)->app_id)
+ return -1;
+
+ return 0;
+}
+
+GAVL_CUST_NODE_INT_DEC(_fwp_participant_table, fwp_participant_table_t,
+ fwp_participant_t, fwp_participant_id_t,
+ participant_tree, participant_tree_node, id,
+ fwp_cmp_participant_id);
+
+GAVL_CUST_NODE_INT_IMP(_fwp_participant_table, fwp_participant_table_t,
+ fwp_participant_t, fwp_participant_id_t,
+ participant_tree, participant_tree_node, id,
+ fwp_cmp_participant_id);
+
+fwp_participant_table_t fwp_participant_table = {
+ .nr_participants = 0,
+ .participant_tree = NULL,
+ .lock = PTHREAD_MUTEX_INITIALIZER,
+};
+
+int fwp_participant_table_nr_participants()
+{
+ return fwp_participant_table.nr_participants;
+}
+
+void fwp_participant_table_insert(fwp_participant_t *participant)
+{
+ pthread_mutex_lock(&fwp_participant_table.lock);
+ _fwp_participant_table_insert(&fwp_participant_table, participant);
+ fwp_participant_table.nr_participants++;
+ pthread_mutex_unlock(&fwp_participant_table.lock);
+}
+
+fwp_participant_t*
+fwp_participant_table_find(fwp_participant_id_t *participant_id)
+{
+ return _fwp_participant_table_find(&fwp_participant_table,
+ participant_id);
+}
+
+int fwp_participant_table_delete(fwp_participant_t *participant)
+{
+ int rv;
+
+ pthread_mutex_lock(&fwp_participant_table.lock);
+ rv = _fwp_participant_table_delete(&fwp_participant_table, participant);
+ fwp_participant_table.nr_participants--;
+ pthread_mutex_unlock(&fwp_participant_table.lock);
+
+ return rv;
+}
+
+fwp_participant_t* fwp_participant_table_foreach_begin(void)
+{
+ pthread_mutex_lock(&fwp_participant_table.lock);
+ return _fwp_participant_table_first(&fwp_participant_table);
+}
+
+void fwp_participant_table_foreach_end(void)
+{
+ pthread_mutex_unlock(&fwp_participant_table.lock);
+}
+
+fwp_participant_t* fwp_participant_table_foreach_next(fwp_participant_t *current)
+{
+ return _fwp_participant_table_next(&fwp_participant_table, current);
+}
+
--- /dev/null
+#ifndef _FWP_PARTICIPANT_TABLE_H
+#define _FWP_PARTICIPANT_TABLE_H
+
+#include "fwp_participant.h"
+
+void fwp_participant_table_insert(fwp_participant_t *participant);
+fwp_participant_t* fwp_participant_table_find(fwp_participant_id_t *participant_id);
+int fwp_participant_table_delete(fwp_participant_t *participant);
+
+fwp_participant_t* fwp_participant_table_foreach_begin(void);
+fwp_participant_t* fwp_participant_table_foreach_next(fwp_participant_t *current);
+void fwp_participant_table_foreach_end(void);
+
+int fwp_participant_table_nr_participants();
+
+#endif /*_FWP_PARTICIPANT_TABLE_H */
--- /dev/null
+#include "gui.h"
+#include "fwp_foreach.h"
+#include <ncurses.h>
+#include <fwp_contract.h>
+#include "fwp_admctrl.h"
+
+void gui_init(void)
+{
+ initscr();
+ cbreak();
+ noecho();
+}
+
+static char *num_with_unit(char *buf, unsigned num, const char *units[])
+{
+ const int div[] = {100,10,1};
+ unsigned order = 0;
+ int d;
+
+ while (num > 999 && units[(order+3)/3] != NULL) {
+ num /= 10;
+ order++;
+ }
+
+ d = div[(order+2)%3];
+ if (d == 1)
+ sprintf(buf, "%4d %s", num, units[(order+2)/3]);
+ else
+ sprintf(buf, "%d.%.*d %s", num/d, (d==10) ? 1 : 2, num%d, units[(order+2)/3]);
+ return buf;
+}
+
+char *bandwidth_to_text(char *buf, unsigned bandwidth_bps)
+{
+ const char *unit[] = {"bps", "kbps", "Mbps", NULL};
+ return num_with_unit(buf, bandwidth_bps, unit);
+}
+
+char *usec_to_text(char *buf, unsigned usec)
+{
+ const char *unit[] = {"us", "ms", "s", NULL};
+ return num_with_unit(buf, usec, unit);
+}
+
+#define addfield(width, title, format, ...) \
+ move(y, x); \
+ x+=width; \
+ if (cd == NULL) addstr(title); \
+ else { \
+ snprintf(str, sizeof(str), format, __VA_ARGS__); \
+ addstr(str); \
+ }
+
+static void print_contract(int y, fwp_contract_data_t *cd)
+{
+ const char *ac_ids[] = { [FWP_AC_VO]="VO", [FWP_AC_VI]="VI", [FWP_AC_BE]="BE", [FWP_AC_BK]="BK" };
+ struct fwp_contract *c = &cd->contract;
+ char str[200], s1[20];
+ int x = 0;
+
+ addfield(4, "ID", "%d", cd->id);
+ addfield(11, "BW", "%s", bandwidth_to_text(s1, (long long)1000*1000*8*c->budget/c->period_usec));
+ addfield(11, "Budget", "%d bytes", c->budget);
+ addfield(11, "Period", "%s", usec_to_text(s1, c->period_usec));
+ addfield(11, "Deadline", "%s", usec_to_text(s1, c->deadline_usec));
+ addfield(3, "AC", "%s", ac_ids[cd->vres_params.ac_id]);
+ addfield(11, "Num partics", "%d", fwp_participant_table_nr_participants());
+}
+
+void gui_print_status()
+{
+ fwp_contract_data_t *cd;
+ struct foreach_contract fec;
+ int y;
+ char str[200];
+
+ clear(); /* Repaint the screen completely to
+ * delete error messages */
+ mvaddstr(0, 0, "FWP Manager");
+ sprintf(str, "Reserved utilization: %d%%", fwp_reserved_utilization/100);
+ mvaddstr(2, 0, str);
+
+ /* Print header */
+ y=4;
+ print_contract(y, NULL);
+ y++;
+
+ /* Print contracts */
+ fec.contdata_new = NULL;
+ for (cd=foreach_contract_begin(&fec);
+ cd;
+ cd=foreach_contract_next(&fec)) {
+ print_contract(y, cd);
+ y++;
+ }
+ refresh();
+}
+
+void gui_end(void)
+{
+ endwin();
+}
--- /dev/null
+#ifndef GUI_H
+#define GUI_H
+
+/* FIXME: Conditionally define these functions as empty macros (to
+ * disable GUI). */
+
+void gui_init(void);
+void gui_print_status(void);
+void gui_end(void);
+
+#endif
--- /dev/null
+12 17.5 17.5
+20 28.1 28.1
+30 40.2 40.2
+40 50.4 50.4
+50 60.0 60.0
+60 69.1 69.1
+70 77.2 77.2
+80 83.1 83.1
+90 89.8 89.8
+100 94.8 94.8
+110 102 102
+120 107 107
+130 111 111
+140 116 116
+150 119 119
+160 125 125
+170 126 126
+180 131 131
+190 132 132
+200 136 136
+250 151 151
+300 161 161
+350 168 168
+400 174 174
+450 179 179
+500 186 186
+550 187 187
+600 192 192
+650 194 194
+700 199 199
+750 200 200
+800 203 203
+850 204 204
+900 204 204
+950 205 205
+1000 208 208
+1050 207 207
+1100 210 210
+1150 210 210
+1200 212 212
+1250 214 214
+1300 212 212
+1350 217 217
+1400 215 215
+1450 217 217
+1460 212 212
+1470 217 217
+1480 199 199
+1490 200 200
+1500 199 199
+1510 199 199
+1520 198 198
+1550 200 200
+1600 201 201
+1650 204 204
+1700 205 205
+1750 207 207
+1800 207 207
+1850 206 206
+1900 209 209
+1950 211 211
+2000 210 210
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+test_PROGRAMS = adm_utilization
+
+adm_utilization_SOURCES = adm_utilization.c ../admtest_utilization.c
+adm_utilization_LIBS = fwp
+
+CFLAGS=-Wall -O0 -g
--- /dev/null
+12 64.6 0.511
+20 45.6 2.04
+30 64.1 2.56
+40 80.5 1.66
+50 94.8 3.45
+60 98.0 28.1
+70 98.4 53.1
+80 98.9 73.9
+90 98.4 89.1
+100 98.9 102
+110 98.9 108
+120 98.8 119
+130 98.7 128
+140 98.9 130
+150 99.7 137
+160 99.4 141
+170 100 145
+180 98.1 153
+190 101 151
+200 99.6 152
+250 99.5 165
+300 100 176
+350 98.7 180
+400 99.8 187
+450 100 189
+500 100 191
+550 98.9 194
+600 100 193
+650 100 198
+700 99.8 199
+750 100 199
+800 99.9 200
+850 98.6 205
+900 99.1 207
+950 99.3 204
+1000 99.8 203
+1050 102 198
+1100 100 204
+1150 98.6 207
+1200 102 204
+1250 99.4 206
+1300 97.8 208
+1350 99.0 207
+1400 97.4 209
+1450 99.7 208
+1460 98.7 210
+1470 100 208
+1480 99.5 198
+1490 100 197
+1500 101 198
+1510 100 201
+1520 100 198
+1550 99.7 198
+1600 103 195
+1650 98.4 203
+1700 99.2 200
+1750 101 201
+1800 101 200
+1850 100 203
+1900 101 199
+1950 99.5 201
+2000 99.8 208
--- /dev/null
+12 70.5 0.64
+20 63.1 2.81
+30 87.3 2.56
+40 98.2 0.896
+50 98.3 2.56
+60 98.5 27.9
+70 98.3 53.0
+80 99.4 71.0
+90 98.6 87.6
+100 99.6 97.1
+110 98.8 110
+120 99.2 118
+130 99.0 125
+140 99.1 134
+150 99.3 135
+160 99.7 141
+170 99.1 144
+180 99.0 150
+190 100 154
+200 100 154
+250 99.4 164
+300 99.4 178
+350 99.1 183
+400 99.3 187
+450 99.5 190
+500 100 193
+550 99.2 193
+600 99.5 194
+650 99.2 195
+700 100 198
+750 100 197
+800 99.8 199
+850 99.3 201
+900 100 204
+950 100 202
+1000 99.8 204
+1050 100 204
+1100 100 205
+1150 99.0 206
+1200 100 207
+1250 99.3 207
+1300 97.9 208
+1350 100 206
+1400 96.3 211
+1450 99.6 205
+1460 98.3 206
+1470 97.4 212
+1480 98.8 199
+1490 99.9 195
+1500 101 197
+1510 100 197
+1520 96.7 203
+1550 100 198
+1600 100 200
+1650 99.3 200
+1700 101 200
+1750 97.8 202
+1800 99.0 203
+1850 96.8 205
+1900 98.4 205
+1950 102 203
+2000 99.5 203
--- /dev/null
+/**
+ * @file adm_utilization.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ *
+ * @brief Test for utilization based admition control.
+ *
+ * This test tries to simulate results of the following test whose
+ * results are available at:
+ * http://rtime.felk.cvut.cz/frescor/images/b/bb/Packet_sizes_sat_comp.pdf
+ * (http://rtime.felk.cvut.cz/frescor/index.php/Experiments#Experiments_2008.2F01)
+ *
+ * Brief description of the test: Measuring of saturation bandwidth of
+ * AC_BE with respect to the size of packets in AC_VO, AC_VI and AC_BE
+ * itself. In this test we have generated the following streams AC_VO:
+ * 100 kbps, AC_VI: 100 kbps and AC_BE: 500 kbps (saturation). The
+ * streams, where the packet size was not changed was formed by
+ * packets of 800 bytes (UDP). The real bandwidth of AC_BE was
+ * measured.
+ */
+
+#include "../admtest.h"
+#include <fwp_ctable.h>
+#include <fwp_ac.h>
+#include <string.h>
+#include <fwp_utils.h>
+
+void insert_contract(struct fwp_ctable *ctable, enum ac_id_t ac, int bandwidth_bps, int packet_size)
+{
+ struct fwp_ctable_entry entry;
+ int period_usec;
+
+ if (bandwidth_bps == 0) return;
+
+ period_usec = SEC_TO_USEC*packet_size*8/bandwidth_bps;
+
+ memset(&entry, 0, sizeof(entry));
+ entry.contract.budget = packet_size;
+ entry.contract.period_usec = period_usec;
+ entry.contract.ac_id = ac;
+
+ fwp_ctable_put(ctable, &entry);
+}
+
+int main()
+{
+ int ac, size;
+ struct fwp_ctable ctable;
+
+ for (ac=FWP_AC_VO; ac <= FWP_AC_BE; ac++) {
+ for (size=10; size < 2000; size+=10) {
+ /* Find maximum BE badwidth by binary
+ * chopping. */
+ int min=0, max=500000, bw;
+ int packet_size[] = {[FWP_AC_VO] = (ac == FWP_AC_VO) ? size : 800,
+ [FWP_AC_VI] = (ac == FWP_AC_VI) ? size : 800,
+ [FWP_AC_BE] = (ac == FWP_AC_BE) ? size : 800};
+ enum contract_status_t cs;
+ bw=(max+min+1)/2;
+ while (min < max) {
+ fwp_ctable_init(&ctable);
+
+ /* Two equal contracts, one for each direction */
+ insert_contract(&ctable, FWP_AC_VO, 100*Kbit, packet_size[FWP_AC_VO]);
+ insert_contract(&ctable, FWP_AC_VO, 100*Kbit, packet_size[FWP_AC_VO]);
+
+ insert_contract(&ctable, FWP_AC_VI, 100*Kbit, packet_size[FWP_AC_VI]);
+ insert_contract(&ctable, FWP_AC_VI, 100*Kbit, packet_size[FWP_AC_VI]);
+
+ insert_contract(&ctable, FWP_AC_BE, bw, packet_size[FWP_AC_BE]);
+ insert_contract(&ctable, FWP_AC_BE, bw, packet_size[FWP_AC_BE]);
+ cs = fwp_adm_test(&ctable);
+ if (cs == FWP_CNT_REJECTED) {
+ max = bw-1;
+ } else {
+ min = bw;
+ }
+ bw=(max+min+1)/2;
+ }
+ printf("%d %f\n", size, bw/1000.0);
+ }
+ printf("\n\n");
+ }
+ return 0;
+}
--- /dev/null
+../../_compiled/bin-tests/adm_utilization > data && gnuplot plot_sat | ps2pdf - admutil_comp.pdf
--- /dev/null
+# Usage: adm_utilization > data; gnuplot plot_sat|ps2pdf admutil_comp.pdf
+
+set terminal postscript color landscape
+#set output "admutil_comp.eps"
+
+set style line 1 lt 1 lc rgb "red"
+set style line 2 lt 1 lc rgb "green"
+set style line 3 lt 1 lc rgb "blue"
+
+set style data lines
+set grid
+set key right bottom nobox
+set title "Comparsion of utilization based test and reality"
+set xlabel "Packet sizes [bytes]"
+set ylabel "AC_BE bandwidth [kbps]"
+
+plot "data" index 0 with lines lt 1 lw 3 lc rgb "red" title "utilization test: AC_VO changed",\
+ "data" index 1 with lines lt 1 lw 3 lc rgb "green" title "utilization test: AC_VI changed",\
+ "data" index 2 with lines lt 1 lw 3 lc rgb "blue" title "utilization test: AC_BE changed",\
+ "VO_packet_size_graph" using 1:3 with points lc rgb "red" title "reality: AC_VO changed",\
+ "VI_packet_size_graph" using 1:3 with points lc rgb "green" title "reality: AC_VI changed",\
+ "BE_packet_size_graph" using 1:3 with points lc rgb "blue" title "reality: AC_BE changed"
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+#SUBDIRS= fwp_msgtest fwp_vrestest
+#fwp_prototest fwp_mngrtest
+#CFLAGS += -Wall -D_REENTRANT -g
+#SUBDIRS= fwp_msgtest fwp_vrestest fwp_prototest fwp_mngrtest
+#fwp_mngrtest unixsocktest
+
+SUBDIRS+=timing
--- /dev/null
+fwp_msgtest - test of modules: fwp_msgb, fwp_msgq, fwp_msg
+#fwp_vrestest - test of modules: fwp_ac, fwp_vres
+fwp_prototest - test of modules: fwp_proto - sending and receiving data
+ through vres
+fwp_fnatest - TODO: test of modules: fwp_fna
+
+unixsocktest - just for simple testing of unix socket behavioural
+hashtest- test for fwp_hashtable implemented in the future(maybe)
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+CFLAGS += -g
+
+test_PROGRAMS = fwp_mngrtest
+fwp_mngrtest_SOURCES+= fwp_mngrtest.c
+lib_LOADLIBES += fwp pthread rt ulut
--- /dev/null
+/**
+ * \file fwp_mngrtest.c
+ *
+ * This is a test application that:
+ * - connects to manager
+ * - negotiates contract
+ * - creates send endpoint and binds it to vres
+ * - sends and receives two messages Hello1 and Hello2
+ * - cancels contract
+ * - disconnects from manager
+ */
+
+#define CONFIGURE_MNGR_ADDR 127.0.0.1
+#include "fwp_confdefs.h"
+#include "fwp.h"
+
+#include <errno.h>
+#include <stdio.h>
+
+fwp_endpoint_attr_t attr;
+
+void* receiver(void *arg)
+{
+ fwp_endpoint_d_t repoint_d1;
+ int i,len;
+ char buffer[30];
+
+ FWP_DEBUG("Creating receive endpoint\n");
+ if (fwp_receive_endpoint_create(7777, &attr,&repoint_d1) < 0){
+ perror("Error while creating receive endpoint\n");
+ return NULL;
+ }
+
+ FWP_DEBUG("Receive endpoint created \n");
+ for (i = 0; i < 3; i++) {
+ if ((len = fwp_recv(repoint_d1, buffer, sizeof(buffer), 0)) < 0) {
+ perror("Error while receiving data::");
+ return NULL;
+ } else {
+ printf("Received %s\n",buffer);
+ //for (j = 0 ; j < 10; i++)
+ // printf("%c", buffer[i]);
+
+ }
+ printf("END\n");
+ }
+
+ return NULL;
+}
+
+int main()
+{
+ int i,rc,len;
+ fwp_vres_d_t vres_d1, vres_d2, vres_d3;
+ fwp_contract_d_t cnt1d, cnt2d, cnt3d;
+ fwp_endpoint_d_t sepoint_d1, sepoint_d2, repoint_d1, repoint_d2;
+ char msg1[] = "Hello1";
+ char msg2[] = "Hello2";
+ fwp_contract_t cnt1;
+ fwp_contract_t cnt2;
+ fwp_contract_t cnt3;
+ pthread_t id;
+
+ cnt1.budget = 100;
+ cnt1.period_usec = 10000;
+
+ cnt2.budget = 120;
+ cnt2.period_usec = 1000;
+
+ cnt3.budget = 130;
+ cnt3.period_usec = 2000;
+
+ printf("Start\n");
+ if (fwp_init() != 0) {
+ printf("fwp_init failed!\n");
+ return EXIT_FAILURE;
+ }
+
+ fwp_endpoint_attr_init(&attr);
+ fwp_endpoint_attr_setreliability(&attr, FWP_EPOINT_RELIABLE);
+ pthread_create(&id, NULL, &receiver, (void*) NULL);
+
+ cnt1d = fwp_contract_create(&cnt1);
+ fwp_contract_negotiate(cnt1d, &vres_d1);
+ if (fwp_contract_is_negotiated(cnt1d)) {
+ printf("CONTRACT1 NEGOTIATED.\n");
+ }else
+ printf("CONTRACT1 NOT NEGOTIATED.\n");
+
+/* cnt2d = fwp_contract_create(&cnt2);
+ fwp_contract_negotiate(cnt2d, &vres_d2);
+ if (fwp_contract_is_negotiated(cnt2d)) {
+ printf("Contract2 negotiated.\n");
+ }else
+ printf("Contract2 not negotiated.\n");
+
+ cnt3d = fwp_contract_create(&cnt3);
+ fwp_contract_negotiate(cnt3d, &vres_d3);
+ if (fwp_contract_is_negotiated(cnt3d)) {
+ printf("Contract3 negotiated.\n");
+ }else
+ printf("Contract3 not negotiated.\n");
+*/
+ if (fwp_send_endpoint_create(inet_addr("127.0.0.1"), 7777,
+ &attr, &sepoint_d1) < 0) {
+ return EXIT_FAILURE;
+ }
+ printf("Send endpoint 1 created\n");
+
+ if ((fwp_send_endpoint_bind(sepoint_d1, vres_d1)) != 0){
+ printf("Bind error\n");
+ return EXIT_FAILURE;
+ }
+
+ fwp_send(sepoint_d1, msg1, sizeof(msg1), 0);
+ printf("Sent msg 1\n");
+ fwp_send(sepoint_d1, msg2, sizeof(msg2), 0);
+ printf("Sent msg 2\n");
+
+ sleep(1);
+ fwp_contract_cancel(cnt1d);
+ printf("Contract 1 is CANCELED\n");
+
+ if (fwp_send(sepoint_d1, msg2, sizeof(msg2), 0) < 0 ) {
+ printf("Failed to send message.\n");
+ }
+
+ if (fwp_contract_destroy(cnt1d) == 0) {
+ printf("Contract 1 is DESTROYED.\n");
+ }
+
+ fwp_mngt_disconnect();
+
+ printf("Test PASSED!\n");
+ scanf("Press key");
+
+ return EXIT_SUCCESS;
+}
--- /dev/null
+#ifndef _HASHTABLE_H
+#define _HASHTABLE_H
+
+/* Zbyva nadefinovat iteraci pres zretazeny seznam
+ *
+ *mozno vyheldavat zaznamu dle label
+ *
+ */
+
+#include "list.h"
+//#include "ul_list.h"
+#include <stdlib.h>
+
+/* Hash table with linked list per each entry*/
+struct hash_table {
+ struct list_head *entries;
+ unsigned int size;
+};
+
+static inline int htable_init(struct hash_table *htable, int size)
+{
+ int i;
+
+ void *entries = malloc(sizeof(struct list_head) * size);
+ if (!entries)
+ return -1;
+
+ htable->entries = (struct list_head*) entries;
+ htable->size = size;
+ for ( i = 0; i < size; i++)
+ INIT_LIST_HEAD(&htable->entries[i]);
+
+ return 0;
+}
+
+static inline void htable_free(struct hash_table *htable)
+{
+ free(htable->entries);
+ htable->entries = NULL;
+ htable->size = 0;
+}
+
+
+static inline void htable_add(struct hash_table *htable, unsigned int hash,
+ struct list_head *new)
+{
+ __list_add(new, htable->entries[hash].prev, &htable->entries[hash]);
+}
+
+
+static inline void htable_del(struct hash_table *htable, unsigned int hash,
+ struct list_head *new)
+{
+ __list_add(new, htable->entries[hash].prev, &htable->entries[hash]);
+}
+
+
+#endif /* _HASHTABLE_H */
--- /dev/null
+#include <stdio.h>
+#include "list.h"
+#include "hashtable.h"
+#include <string.h>
+
+
+#define MAX_CHARS 48
+
+struct item {
+ struct list_head node;
+ int value;
+ char label[MAX_CHARS];
+};
+
+unsigned int hash_func(char *key, unsigned int modulus)
+{
+ unsigned int hash = 0;
+ int i;
+
+ // loop while max_chars is not reached and a null character is not found
+ for (i=0; i < MAX_CHARS && key[i]!=0; i++) {
+ hash = (hash*37+ key[i]);
+ }
+
+ return (hash % modulus);
+}
+
+
+int main()
+{
+ struct hash_table htable;
+ struct item a,c;
+ //struct item a = {{NULL, NULL}, 5, "FRESCOR"};
+ //struct item c = {{NULL, NULL}, 100, "FRSH"};
+
+ unsigned int hash;
+
+ INIT_LIST_HEAD(&a.node);
+ a.value = 5;
+ strcpy(a.label,"FRESCOR");
+
+ INIT_LIST_HEAD(&c.node);
+ c.value = 100;
+ strcpy(c.label,"FRSH");
+
+ htable_init(&htable, 5);
+
+ hash = hash_func(a.label, htable.size);
+ printf("hash(a) = %d\n", hash);
+ htable_add(&htable, hash, &a.node);
+
+ hash = hash_func(c.label, htable.size);
+ printf("hash(b) = %d\n", hash);
+ htable_add(&htable, hash, &c.node);
+
+ htable_free(&htable);
+
+ return 0;
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+test_PROGRAMS = fwp-timing
+fwp-timing_SOURCES = fwp-timing.c
+lib_LOADLIBES = frsh
--- /dev/null
+/*
+ * A tool for measuring FWP latency. This program aims to be simpler
+ * than wme_test and is intended to be run on a single machine with
+ * multiple wifi interfaces and send-to-self kernel patch applied.
+ *
+ * This program creates both sides of communication and measures the
+ * communication delays.
+ */
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <frsh.h>
+#include <getopt.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <fwp_res.h>
+#include <error.h>
+#include <sys/mman.h>
+#include <semaphore.h>
+#include <ul_logreg.h>
+
+bool opt_verbose = false;
+bool opt_quiet = false;
+
+#define HIST_MAX_US 10000000
+#define HIST_RES_US 10
+
+struct histogram {
+ unsigned cnt[(HIST_MAX_US+1)/HIST_RES_US];
+ unsigned max;
+};
+
+/* static void hist_init(struct histogram *h) */
+/* { */
+/* memset(h, 0, sizeof(*h)); */
+/* } */
+
+static void hist_add(struct histogram *h, int us)
+{
+ assert(us > 0);
+ if (us > HIST_MAX_US)
+ us = HIST_MAX_US;
+ __sync_fetch_and_add(&h->cnt[us/HIST_RES_US], 1);
+
+ unsigned max;
+ do {
+ max = h->max;
+ } while (us > max && ! __sync_bool_compare_and_swap(&h->max, max, us));
+
+}
+
+static unsigned hist_get_percentile(struct histogram *h, unsigned p)
+{
+ uint64_t sum = 0, psum;
+ int i;
+ for (i=0; i<(HIST_MAX_US+1)/HIST_RES_US; i++)
+ sum += h->cnt[i];
+
+ psum = sum * p / 100;
+ sum = 0;
+ for (i=0; i<(HIST_MAX_US+1)/HIST_RES_US; i++) {
+ sum += h->cnt[i];
+ if (sum >= psum)
+ break;
+ }
+ return i*HIST_RES_US;
+}
+
+struct stats {
+ uint32_t sent;
+ uint32_t received;
+ uint32_t lost;
+} stats;
+
+struct histogram hist;
+
+void set_rt_prio(int priority)
+{
+ int maxpri, minpri;
+ static struct sched_param param;
+
+ if ((maxpri = sched_get_priority_max(SCHED_FIFO)) == -1) {
+ fprintf(stderr, "warning: sched_get_priority_max failed\n");
+ }
+
+ if ((minpri = sched_get_priority_min(SCHED_FIFO)) == -1) {
+ fprintf(stderr, "warning: sched_get_priority_min failed\n");
+ }
+
+ if (priority > maxpri) {
+ fprintf(stderr, "warning: maximum priority allowed is %d.\n", maxpri);
+ }
+ if (priority < minpri) {
+ fprintf(stderr, "warning: minimum priority allowed is %d.\n", minpri);
+ }
+
+ param.sched_priority = priority;
+
+ if (sched_setscheduler(0, SCHED_FIFO, ¶m) == -1) {
+ fprintf(stderr, "warning: sched_setscheduler failed\n");
+ }
+
+ mlockall(MCL_CURRENT | MCL_FUTURE);
+}
+
+struct stream_params {
+ int budget;
+ int period_ms;
+ bool async;
+ struct in_addr src, dst;
+ int number;
+ int id;
+ int count;
+ frsh_vres_id_t vres;
+ pthread_t thread;
+ int jitter;
+};
+
+
+int negotiate_contract(struct stream_params *p)
+{
+ frsh_contract_t contract;
+ int ret;
+ frsh_rel_time_t period;
+ frsh_rel_time_t budget;
+ frsh_rel_time_t deadline;
+ fres_block_fwp *fwp;
+
+ ret = frsh_contract_init(&contract);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
+
+ ret = frsh_contract_set_resource_and_label(
+ &contract,
+ FRSH_RT_NETWORK, FRSH_NETPF_FWP,
+ NULL);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ frsh_network_bytes_to_budget(FRSH_NETPF_FWP, p->budget, &budget);
+ period = fosa_msec_to_rel_time(p->period_ms);
+ ret = frsh_contract_set_basic_params(&contract,
+ &budget,
+ &period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+
+
+ /* FWP doesn't accept smaller deadlines than 30 ms. */
+ if (frsh_rel_time_smaller(period, frsh_msec_to_rel_time(30)))
+ deadline = frsh_msec_to_rel_time(30);
+ else
+ deadline = period;
+ ret = frsh_contract_set_timing_reqs(&contract, false, &deadline);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_timing_reqs");
+
+ fwp = malloc(sizeof(*fwp));
+ if (!fwp) PERROR_AND_EXIT(errno, "malloc");
+ fwp->src = p->src.s_addr;
+ ret = fres_contract_add_fwp(contract, fwp);
+ if (ret) PERROR_AND_EXIT(ret, "fres_contract_add_fwp");
+
+ ret = frsh_contract_negotiate(&contract, &p->vres);
+
+ frsh_contract_destroy(&contract);
+
+ return ret;
+}
+
+void create_endpoints(struct stream_params *p,
+ frsh_send_endpoint_t *epsrc,
+ frsh_receive_endpoint_t *epdst)
+{
+ int ret;
+ frsh_send_endpoint_protocol_info_t spi = { NULL, 0 };
+ frsh_receive_endpoint_protocol_info_t rpi = { NULL, 0 };
+ frsh_endpoint_queueing_info_t qi = { .queue_size=0,
+ .queue_policy=FRSH_QRP_OLDEST };
+
+ ret = frsh_receive_endpoint_create(FRSH_NETPF_FWP, 0, qi, rpi,
+ epdst);
+ if (ret != 0) error(1, errno, "fwp_receive_endpoint_create");
+
+ unsigned int port;
+ frsh_receive_endpoint_get_params(*epdst, NULL, &port, NULL, NULL);
+
+ ret = frsh_send_endpoint_create(FRSH_NETPF_FWP,
+ p->dst.s_addr, port, spi,
+ epsrc);
+ if (ret < 0) error(1, errno, "frsh_send_endpoint_create()");
+
+ ret = frsh_send_endpoint_bind(p->vres, *epsrc);
+ if (ret != 0) error(1, errno, "frsh_send_endpoint_bind");
+}
+
+
+static struct option long_opts[] = {
+ { "loglevel",required_argument, 0, 'l' },
+ { "period", required_argument, 0, 'p' },
+ { "budget", required_argument, 0, 'b' },
+ { "source", required_argument, 0, 's' },
+ { "dest", required_argument, 0, 'd' },
+ { "async", no_argument, 0, 'a' },
+ { "number", required_argument, 0, 'n' },
+ { "count", required_argument, 0, 'c' },
+ { "verbose",no_argument, 0, 'v' },
+ { "quiet", no_argument, 0, 'q' },
+ { "jitter", required_argument, 0, 'j' },
+ { 0, 0, 0, 0}
+};
+
+static void
+usage(void)
+{
+ printf("usage: fwp-timing [ options ]\n");
+ printf(" -l, --loglevel <number>|<domain>=<number>,...\n");
+ printf(" -p, --period <ms> period in miliseconds\n");
+ printf(" -b, --budget <bytes> how many bytes is sent in each period\n");
+ printf(" -s, --source <ip> source IP address\n");
+ printf(" -d, --dest <ip:port> destination IP address and port\n");
+ printf(" -a, --async Send packets asynchronously\n");
+ printf(" -n, --number Number of streams with the same parameters\n");
+ printf(" -c, --count Number of messages to send [infinity]\n");
+ printf(" -q, --quiet Print only final statistics\n");
+ printf(" -/, --stream New stream separator\n");
+ printf(" -v, --verbose Be more verbose\n");
+ printf(" -j, --jitter <percent> Sent jitter given as percentage of period\n");
+}
+
+int parse_opts(int *argc, char **argv[], struct stream_params *p)
+{
+ int opt;
+ int ret;
+ bool options_found = false;
+
+ while ((opt = getopt_long(*argc, *argv, "/ab:c:d:j:l:n:p:qs:v", long_opts, NULL)) != -1) {
+ options_found = true;
+ switch (opt) {
+ case 'a':
+ p->async = true;
+ break;
+ case 'b':
+ p->budget = atoi(optarg);
+ break;
+ case 'c':
+ p->count = atoi(optarg);
+ break;
+ case 'd':
+ ret = inet_aton(optarg, &p->dst);
+ if (!ret) {
+ fprintf(stderr, "Destination IP address not recognized: %s\n",
+ optarg);
+ usage();
+ exit(1);
+ }
+ break;
+ case 'j':
+ p->jitter = atoi(optarg);
+ break;
+ case 'l':
+ ul_log_domain_arg2levels(optarg);
+ break;
+ case 'n':
+ p->number = atoi(optarg);
+ break;
+ case 'p':
+ p->period_ms = atoi(optarg);
+ break;
+ case 's':
+ ret = inet_aton(optarg, &p->src);
+ if (!ret) {
+ fprintf(stderr, "Source IP address not recognized: %s\n",
+ optarg);
+ usage();
+ exit(1);
+ }
+ break;
+ case 'v':
+ opt_verbose = true;
+ break;
+ case 'q':
+ opt_quiet = true;
+ break;
+ case '/':
+ break;
+ default:
+ usage();
+ exit(1);
+ }
+ if (opt == '/')
+ break;
+ }
+ return (options_found) ? 0 : -1;
+}
+
+volatile bool exit_flag = false;
+
+void stopper()
+{
+ exit_flag = true;
+}
+
+int
+timespec_subtract (result, x, y)
+ struct timespec *result, *x, *y;
+{
+ /* Perform the carry for the later subtraction by updating Y. */
+ if (x->tv_nsec < y->tv_nsec) {
+ int nsec = (y->tv_nsec - x->tv_nsec) / 1000000000 + 1;
+ y->tv_nsec -= 1000000000 * nsec;
+ y->tv_sec += nsec;
+ }
+ if (x->tv_nsec - y->tv_nsec > 1000000000) {
+ int nsec = (x->tv_nsec - y->tv_nsec) / 1000000000;
+ y->tv_nsec += 1000000000 * nsec;
+ y->tv_sec -= nsec;
+ }
+
+ /* Compute the time remaining to wait.
+ `tv_nsec' is certainly positive. */
+ result->tv_sec = x->tv_sec - y->tv_sec;
+ result->tv_nsec = x->tv_nsec - y->tv_nsec;
+
+ /* Return 1 if result is negative. */
+ return x->tv_sec < y->tv_sec;
+}
+
+static inline double ts2d(struct timespec *ts)
+{
+ return ts->tv_sec + 1e-9*ts->tv_nsec;
+}
+
+static inline double tsdiff2d(struct timespec *x,
+ struct timespec *y)
+{
+ struct timespec r;
+ timespec_subtract(&r, x, y);
+ return ts2d(&r);
+}
+
+static inline int tsdiff2us(struct timespec *x,
+ struct timespec *y)
+{
+ struct timespec r;
+ timespec_subtract(&r, x, y);
+ return r.tv_sec*1000000 + r.tv_nsec/1000;
+}
+
+struct msg {
+ int cnt;
+ struct timespec ts;
+};
+
+struct receiver_params {
+ int budget;
+ frsh_receive_endpoint_t epdst;
+ int id;
+};
+
+void *receiver(void *arg)
+{
+ struct receiver_params *rp = arg;
+ frsh_receive_endpoint_t epdst = rp->epdst;
+ size_t mlen;
+ int ret;
+ int last_cnt = -1;
+ struct timespec tss, tsr;
+ struct msg *msg;
+ msg = malloc(rp->budget);
+ if (!msg) error(1, errno, "malloc msg");
+
+ while (!exit_flag) {
+ ret = frsh_receive_sync(epdst, msg, rp->budget, &mlen, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &tsr);
+ tss = msg->ts;
+ if (msg->cnt != last_cnt+1) {
+ if (!opt_quiet)
+ printf("%3d: packet(s) lost!\n", rp->id);
+ __sync_fetch_and_add(&stats.lost, msg->cnt - last_cnt+1);
+ } else {
+ hist_add(&hist, tsdiff2us(&tsr, &tss));
+ __sync_fetch_and_add(&stats.received, 1);
+ }
+ if (opt_verbose)
+ printf("%3d: %10d: %10.3lf ms\n",
+ rp->id, msg->cnt, tsdiff2d(&tsr, &tss)*1000);
+ last_cnt = msg->cnt;
+ }
+ free(rp);
+ return NULL;
+}
+
+sem_t finished;
+
+void *sender(void *arg)
+{
+ struct stream_params *p = arg;
+ frsh_send_endpoint_t epsrc;
+ struct receiver_params *rp;
+ int ret;
+ struct msg *msg;
+ long int cnt=0;
+ pthread_t receiver_id;
+
+ msg = malloc(p->budget);
+ if (!msg) error(1, errno, "malloc msg");
+
+ rp = malloc(sizeof(*rp));
+ rp->budget = p->budget;
+ rp->id = p->id;
+
+ create_endpoints(p, &epsrc, &rp->epdst);
+
+ set_rt_prio(50);
+
+ ret = pthread_create(&receiver_id, NULL, receiver, rp);
+
+ struct timespec next_period;
+ struct timespec tss;
+ clock_gettime(CLOCK_MONOTONIC, &next_period);
+ while (!exit_flag && (p->count == -1 || p->count--)) {
+ clock_gettime(CLOCK_MONOTONIC, &tss);
+ msg->cnt = cnt++;
+ msg->ts = tss;
+ if (p->async)
+ ret = frsh_send_async(epsrc, msg, p->budget);
+ else {
+ ret = frsh_send_sync(epsrc, msg, p->budget);
+ clock_gettime(CLOCK_MONOTONIC, &next_period);
+ }
+ __sync_fetch_and_add(&stats.sent, 1);
+
+ int delay_ms;
+ if (p->jitter)
+ delay_ms = p->period_ms*(100-p->jitter)/100
+ + rand() % (2*p->period_ms*p->jitter/100);
+ else
+ delay_ms = p->period_ms;
+
+ next_period.tv_sec += (delay_ms/1000);
+ next_period.tv_nsec += (delay_ms%1000) * 1000000;
+ if (next_period.tv_nsec >= 1000000000) {
+ next_period.tv_nsec -= 1000000000;
+ next_period.tv_sec++;
+ }
+ clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME,
+ &next_period, NULL);
+ }
+
+
+ sem_post(&finished);
+ return NULL;
+}
+
+void print_stat(bool final)
+{
+ printf("Sent: %5d Received: %5d Lost: %5d Max: %8.3f ms",
+ stats.sent, stats.received, stats.lost, hist.max/1000.0);
+ if (final) {
+ printf(" Packetloss: %7.3f %% 95%%: %8.3f ms 99%%: %8.3f ms\n",
+ 100.0*stats.lost/stats.sent,
+ hist_get_percentile(&hist, 95)/1000.0,
+ hist_get_percentile(&hist, 99)/1000.0);
+ }
+ else
+ printf("\r");
+ fflush(stdout);
+}
+
+int main(int argc, char *argv[])
+{
+ int ret;
+ int i;
+ int num = 0;
+ bool negotiation_failure = false;
+
+ struct stream_params sp = {
+ .budget = 1024,
+ .period_ms = 20,
+ .async = false,
+ .src.s_addr = htonl(INADDR_LOOPBACK),
+ .dst.s_addr = htonl(INADDR_LOOPBACK),
+ .number = 1,
+ .count = -1,
+ };
+ struct stream_params *p[100];
+
+ memset(p, 0, sizeof(p));
+
+ if (signal(SIGTERM, stopper) == SIG_ERR)
+ error(1, errno, "Error in signal registration");
+ if (signal(SIGINT, stopper) == SIG_ERR)
+ error(1, errno, "Signal handler registration error");
+
+ sem_init(&finished, 0, 0);
+
+ ret = frsh_init();
+ if (ret) PERROR_AND_EXIT(ret, "frsh_init");
+
+ do {
+ ret = parse_opts(&argc, &argv, &sp);
+ if (num == 0 || ret == 0) {
+ for (i=0; i<sp.number; i++) {
+ p[num] = malloc(sizeof(*p[0]));
+ if (!p[num]) error(1, errno, "malloc");
+ *p[num] = sp;
+ p[num]->id = num;
+ ret = negotiate_contract(p[num]);
+ if (!ret)
+ num++;
+ else {
+ PERROR_FRESCOR(ret, "frsh_contract_negotiate");
+ free(p[num]);
+ negotiation_failure = true;
+ break;
+ }
+ }
+ }
+ } while(ret == 0);
+
+ if (negotiation_failure) {
+ goto destroy;
+ }
+
+ for (i=0; i<num; i++)
+ pthread_create(&p[i]->thread, NULL, sender, p[i]);
+
+ while (!exit_flag && !opt_quiet) {
+ int v;
+ print_stat(false);
+ sem_getvalue(&finished, &v);
+ if (v == num)
+ break;
+ usleep(100000);
+ }
+
+ for (i=0; i<num; i++)
+ pthread_join(p[i]->thread, NULL);
+destroy:
+ for (i=0; i<num; i++) {
+ frsh_contract_cancel(p[i]->vres);
+ free(p[i]);
+ }
+
+ stats.lost = stats.sent - stats.received;
+ print_stat(true);
+
+ return negotiation_failure ? 1 : 0;
+}
--- /dev/null
+set key top left
+set xlabel "Number of simultaneous streams"
+set ylabel "Time [ms]
+set yrange [0:]
+set y2range [0:100]
+set y2label "Packet loss [%]
+set y2tics
+set grid
+
+plot "./fwp-timing.dat" using 1:2 title "Maximal delay [ms]" with lp,\
+ "./fwp-timing.dat" using 1:4 title "95th percentile [ms]" with lp,\
+ "./fwp-timing.dat" using 1:5 title "99th percentile [ms]" with lp,\
+ "./fwp-timing.dat" using 1:3 title "Packet loss [%]" with lp axis x1y2
--- /dev/null
+#!/usr/bin/perl -w
+
+$omk_rules_dir=qx'
+old_pwd=""
+while [ ! -e Makefile.rules ]; do
+ if [ "$old_pwd" = `pwd` ]; then
+ echo "Makefile.rules has not been found in this or parent directory" >&2; exit 1;
+ else
+ old_pwd=`pwd`;
+ cd -L .. 2>/dev/null;
+ fi;
+done;
+pwd';
+chomp $omk_rules_dir;
+
+sub catch_zap {
+ my $signame = shift;
+ die "Somebody sent me a SIG$signame";
+}
+$SIG{INT} = \&catch_zap;
+$SIG{TERM} = \&catch_zap;
+
+@srcdst = (
+ "-s 192.168.1.10 -d 192.168.1.11",
+ "-s 192.168.1.11 -d 192.168.1.12",
+ "-s 192.168.1.12 -d 192.168.1.13",
+ "-s 192.168.1.13 -d 192.168.1.10",
+);
+
+$max=10;
+$max=$ARGV[0] if (scalar(@ARGV));
+my @results=();
+for($i=1; $i<=$max; $i++) {
+ $|++; # Autoflush
+ printf "%3d: ", $i;
+ $|--;
+ my @streams = ();
+ for ($j=0; $j<@srcdst; $j++) {
+ use integer;
+ my $n = ($i-1) / @srcdst + ((($j % @srcdst) <= (($i-1) % @srcdst)) ? 1 : 0);
+ $streams[$j] = $srcdst[$j]." -n $n" if ($n);
+ }
+ $cmd="$omk_rules_dir/_compiled/bin-tests/fwp-timing -l 2 -q -c 1000 ".join(" -/ ", @streams);
+ #print "$cmd\n";
+ $out=`$cmd`;
+ print $out;
+ my @result;
+ if ($? == 0) {
+ @result = $out =~ /Max: *([0-9.]+).*Packetloss: *([0-9.]+).*95%: *([0-9.]+).*99%: *([0-9.]+)/;
+ } else {
+ @result = ();
+ }
+ $results[$i] = \@result;
+}
+
+# Print data for gnuplot
+open(DAT, ">", "fwp-timing.dat");
+for($i=1; $i<=$max; $i++) {
+ my $line = "$i ".join(" ", @{$results[$i]})."\n";
+ print DAT $line;
+}
+close DAT;
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+CFLAGS += -Wall -D_REENTRANT -g
+
+test_PROGRAMS = unixclient unixclient_thread unixclient_thread_dgram unixserver\
+ unixserver_dgram
+
+unixclient_SOURCES+= unixclient.c
+unixclient_thread_SOURCES+= unixclient_thread.c
+unixclient_thread_dgram_SOURCES+= unixclient_thread_dgram.c
+unixserver_SOURCES+= unixserver.c
+unixserver_dgram_SOURCES+= unixserver_dgram.c
+lib_LOADLIBES += fwp pthread
+
+#utils_PROGRAMS = hashtest
+
+#lib_LIBRARIES =
+
+#include_HEADERS = ../libfwp/include/list.h ../libfwp/include/hashtable.h
+
--- /dev/null
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define SOCKET_PATH_SERVER "server_socket"
+
+int main(int argc, char *argv[])
+{
+ int sockfd;
+ struct sockaddr_un server_addr;
+ int result;
+ char msg[20];
+ char buf[20];
+ unsigned int msglen;
+
+ if (argc < 2) {
+ printf("%s: Missing string parameter\n",argv[0]);
+ return -1;
+ }
+
+ msglen = strlen(argv[1]) + 1;
+ //printf("msg= %lu \n", sizeof(msg));
+
+ if (msglen > sizeof(msg))
+ msglen = sizeof(msg);
+
+ strncpy(msg, argv[1], msglen);
+
+ /* Create a socket for the client. */
+
+ sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
+
+ /* Name the socket, as agreed with the server. */
+
+ server_addr.sun_family = AF_UNIX;
+ strcpy(server_addr.sun_path, SOCKET_PATH_SERVER);
+
+ /* Now connect our socket to the server's socket. */
+
+ result = connect(sockfd, (struct sockaddr *)&server_addr,
+ sizeof(server_addr));
+
+ if(result == -1) {
+ return -1;
+ }
+
+ while (1) {
+ while (send(sockfd, msg, msglen, 0) == -1){
+ if (errno == EINTR) continue;
+ goto out_err;
+ }
+
+ while (recv(sockfd, buf, sizeof(buf),0) == -1){
+ if (errno == EINTR) continue;
+ goto out_err;
+ }
+
+ printf("sent=%s received=%s\n", msg,buf);
+ }
+
+ unlink(SOCKET_PATH_SERVER);
+ close(sockfd);
+ return 0;
+out_err:
+ unlink(SOCKET_PATH_SERVER);
+ close(sockfd);
+ return -1;
+}
--- /dev/null
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+
+void* messenger(void* arg)
+{
+ struct sockaddr_un server_addr;
+ int result;
+ char buf[20];
+ char *msg;
+ int sockfd;
+ unsigned int msglen;
+
+ msg = (char*) arg;
+ msglen = strlen(msg) + 1;
+ //printf("msg=%lu \n", sizeof(msg));
+
+ /* Create a socket for the client. */
+
+ sockfd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+
+ /* Name the socket, as agreed with the server. */
+
+ server_addr.sun_family = AF_UNIX;
+ strcpy(server_addr.sun_path, "server_socket");
+
+ /* Now connect our socket to the server's socket. */
+
+ result = connect(sockfd, (struct sockaddr *)&server_addr,
+ sizeof(server_addr));
+
+ if(result == -1) {
+ return NULL;
+ }
+
+ /* We can now read/write via sockfd. */
+ while (1) {
+ while (send(sockfd, msg, msglen, 0) == -1){
+ if (errno == EINTR) continue;
+ goto out_err;
+ }
+
+ while (recv(sockfd, buf, sizeof(buf),0) == -1){
+ if (errno == EINTR) continue;
+ goto out_err;
+ }
+
+ printf("sent=%s received=%s", msg,buf);
+ if (!strcmp(msg,buf))
+ printf(" -- OK\n");
+ else
+ printf(" -- FAILED!!!\n");
+ }
+
+ close(sockfd);
+ return NULL;
+out_err:
+ close(sockfd);
+ return NULL;
+}
+
+
+
+int main(int argc, char *argv[])
+{
+ char msg1[20]="Thread1";
+ char msg2[20]="Thread2";
+ pthread_attr_t attr;
+ pthread_t thread;
+
+ pthread_attr_init(&attr);
+ pthread_create(&thread, &attr, messenger, (void*) msg1);
+ pthread_create(&thread, &attr, messenger, (void*) msg2);
+
+ while (1) { /* primitive wait but enough ;-) */
+ sleep(100000);
+ }
+}
--- /dev/null
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+
+#define SOCKET_PATH_CLIENT "client_socket"
+#define SOCKET_PATH_SERVER "server_socket"
+
+void* messenger(void* arg)
+{
+ struct sockaddr_un server_addr;
+ struct sockaddr_un client_addr;
+ char buf[20];
+ char *msg;
+ int sockfd;
+ unsigned int msglen;
+ socklen_t server_addr_len;
+
+ msg = (char*) arg;
+ msglen = strlen(msg) + 1;
+ //printf("msg=%lu \n", sizeof(msg));
+
+ sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
+
+ bzero(&client_addr, sizeof(client_addr));
+ client_addr.sun_family = AF_UNIX;
+ strcpy(client_addr.sun_path, SOCKET_PATH_CLIENT);
+
+// unlink(SOCKET_PATH_CLIENT);
+
+ if (bind(sockfd,(struct sockaddr*)&client_addr,
+ sizeof(client_addr)) < 0) {
+ fprintf(stderr,"Client--bind");
+ goto out_err;
+ }
+
+ bzero(&server_addr, sizeof(server_addr));
+ server_addr.sun_family = AF_UNIX;
+ strcpy(server_addr.sun_path, SOCKET_PATH_SERVER);
+
+ while (1) {
+ while (sendto(sockfd, msg, msglen, 0,
+ (struct sockaddr*)&server_addr,
+ sizeof(server_addr)) == -1){
+ if (errno == EINTR) continue;
+ fprintf(stderr,"Sendto ");
+ goto out_err;
+ }
+
+ server_addr_len = sizeof(server_addr);
+ while (recvfrom(sockfd, buf, sizeof(buf), 0,
+ (struct sockaddr*)&server_addr,
+ &server_addr_len) == -1){
+ if (errno == EINTR) continue;
+ fprintf(stderr,"Recvfrom ");
+ goto out_err;
+ }
+
+ printf("sent=%s received=%s", msg,buf);
+ if (!strcmp(msg,buf))
+ printf(" -- OK\n");
+ else
+ printf(" -- FAILED!!!\n");
+ }
+
+ unlink(SOCKET_PATH_CLIENT);
+ close(sockfd);
+ return NULL;
+out_err:
+ unlink(SOCKET_PATH_CLIENT);
+ perror("- client");
+ close(sockfd);
+ return NULL;
+}
+
+int main(int argc, char *argv[])
+{
+ char msg1[20]="Thread1";
+ /*char msg2[20]="Thread2";*/
+ pthread_attr_t attr;
+ pthread_t thread;
+
+ pthread_attr_init(&attr);
+ pthread_create(&thread, &attr, messenger, (void*) msg1);
+ /*pthread_create(&thread, &attr, messenger, (void*) msg2);*/
+
+ while (1) { /* primitive wait but enough ;-) */
+ sleep(100000);
+ }
+}
--- /dev/null
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+
+int main()
+{
+ int server_sockfd, client_sockfd;
+ socklen_t client_len;
+ struct sockaddr_un server_addr;
+ struct sockaddr_un client_addr;
+ int mlen;
+
+ char buf[20];
+
+ /* Remove any old socket and create
+ * an unnamed socket for the server. */
+
+ unlink("server_socket");
+ server_sockfd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+
+ /* Name the socket. */
+
+ server_addr.sun_family = AF_UNIX;
+ strcpy(server_addr.sun_path, "server_socket");
+ bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
+
+ /* Create a connection queue and wait for clients. */
+
+ listen(server_sockfd, 5);
+ while(1) {
+ client_sockfd = accept(server_sockfd,
+ (struct sockaddr *)&client_addr,
+ &client_len);
+/* if (client_sockfd < 0) {
+ if (errno==EINTR) continue;
+ printf("Accept error \n");
+ goto out_err;
+ }
+*/
+
+ switch (fork())
+ {
+ case 0:
+ close(server_sockfd);
+ while (1) {
+ while ((mlen = recv(client_sockfd, buf, sizeof(buf),
+ 0)) == -1){
+ if (errno == EINTR) continue;
+ goto out_err;
+ }
+
+ while (send(client_sockfd, buf, mlen, 0) == -1){
+ if (errno == EINTR) continue;
+ goto out_err;
+ }
+ }
+
+ case -1:
+ return -1;
+ default:
+ close(client_sockfd);
+ }
+ }
+
+ close(server_sockfd);
+ close(client_sockfd);
+ return 0;
+
+out_err:
+ perror("\n");
+ close(server_sockfd);
+ close(client_sockfd);
+ return -1;
+}
+
--- /dev/null
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define SOCKET_PATH_SERVER "server_socket"
+
+int main()
+{
+ int server_sockfd;
+ socklen_t addr_len;
+ struct sockaddr_un server_addr;
+ struct sockaddr_un client_addr;
+ int mlen;
+
+ char buf[100];
+
+ server_sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
+
+ unlink(SOCKET_PATH_SERVER);
+ server_addr.sun_family = AF_UNIX;
+ strcpy(server_addr.sun_path, SOCKET_PATH_SERVER);
+
+ if (bind(server_sockfd, (struct sockaddr *)&server_addr,
+ sizeof(server_addr)) < 0){
+ fprintf(stderr,"Bind ");
+ goto out_err;
+ }
+
+
+ while (1) {
+ addr_len = sizeof(client_addr);
+ while ((mlen = recvfrom(server_sockfd, buf, sizeof(buf), 0,
+ (struct sockaddr*)&client_addr,
+ &addr_len)) == -1){
+ if (errno == EINTR) continue;
+ fprintf(stderr,"Recvfrom ");
+ goto out_err;
+ }
+
+ printf("Prijate z %s\n",client_addr.sun_path);
+ while (sendto(server_sockfd, buf, mlen, 0,
+ (struct sockaddr*)&client_addr,
+ addr_len) == -1){
+ if (errno == EINTR) continue;
+ fprintf(stderr,"Sendto ");
+ goto out_err;
+ }
+ }
+
+ close(server_sockfd);
+ unlink(SOCKET_PATH_SERVER);
+ return 0;
+
+out_err:
+ unlink(SOCKET_PATH_SERVER);
+ perror("-server error");
+ close(server_sockfd);
+ return -1;
+}
+
--- /dev/null
+../wme_test
\ No newline at end of file
--- /dev/null
+Index: linux2.6-devel/drivers/net/wireless/rt2x00/rt61pci.c
+===================================================================
+--- linux2.6-devel.orig/drivers/net/wireless/rt2x00/rt61pci.c 2007-11-26 19:40:10.000000000 +0100
++++ linux2.6-devel/drivers/net/wireless/rt2x00/rt61pci.c 2007-11-26 19:46:18.000000000 +0100
+@@ -1573,6 +1573,10 @@
+ {
+ u32 word;
+
++ printk(KERN_DEBUG "write_tx_desc: sent TX ring %d - CWmin: %d,"
++ " CWmax: %d, AIFSN: %d.\n",
++ desc->queue, desc->cw_min, desc->cw_max, desc->aifs);
++
+ /*
+ * Start writing the descriptor words.
+ */
--- /dev/null
+Index: linux2.6-devel/drivers/net/wireless/rt2x00/rt2x00mac.c
+===================================================================
+--- linux2.6-devel.orig/drivers/net/wireless/rt2x00/rt2x00mac.c 2007-11-14 15:16:34.000000000 +0100
++++ linux2.6-devel/drivers/net/wireless/rt2x00/rt2x00mac.c 2007-11-14 17:09:44.000000000 +0100
+@@ -421,6 +421,7 @@
+ * The passed variables are stored as real value ((2^n)-1).
+ * Ralink registers require to know the bit number 'n'.
+ */
++#if 0
+ if (params->cw_min)
+ ring->tx_params.cw_min = fls(params->cw_min);
+ else
+@@ -435,6 +436,35 @@
+ ring->tx_params.aifs = params->aifs;
+ else
+ ring->tx_params.aifs = 2;
++#endif
++
++ switch (queue) {
++ case 0:
++ ring->tx_params.aifs = 2;
++ ring->tx_params.cw_max = 4;
++ ring->tx_params.cw_min = 3;
++ break;
++ case 1:
++ ring->tx_params.aifs = 2;
++ ring->tx_params.cw_max = 5;
++ ring->tx_params.cw_min = 4;
++ break;
++ case 2:
++ ring->tx_params.aifs = 3;
++ ring->tx_params.cw_max = 10;
++ ring->tx_params.cw_min = 5;
++ break;
++ case 3:
++ ring->tx_params.aifs = 7;
++ ring->tx_params.cw_max = 10;
++ ring->tx_params.cw_min = 5;
++ break;
++ default:
++ ring->tx_params.aifs = 15;
++ ring->tx_params.cw_max = 15;
++ ring->tx_params.cw_min = 10;
++ break;
++ }
+
+ INFO(rt2x00dev,
+ "Configured TX ring %d - CWmin: %d, CWmax: %d, Aifs: %d.\n",
+Index: linux2.6-devel/net/mac80211/wme.c
+===================================================================
+--- linux2.6-devel.orig/net/mac80211/wme.c 2007-11-14 15:16:34.000000000 +0100
++++ linux2.6-devel/net/mac80211/wme.c 2007-11-14 15:17:58.000000000 +0100
+@@ -112,12 +112,12 @@
+
+ /* is this a QoS frame? */
+ qos = fc & IEEE80211_STYPE_QOS_DATA;
+-
++#if 0
+ if (!qos) {
+ skb->priority = 0; /* required for correct WPA/11i MIC */
+ return ieee802_1d_to_ac[skb->priority];
+ }
+-
++#endif
+ /* use the data classifier to determine what 802.1d tag the
+ * data frame has */
+ skb->priority = classify_1d(skb, qd);
--- /dev/null
+Index: linux2.6-devel/drivers/net/wireless/rt2x00/rt2x00mac.c
+===================================================================
+--- linux2.6-devel.orig/drivers/net/wireless/rt2x00/rt2x00mac.c 2007-12-04 10:47:32.000000000 +0100
++++ linux2.6-devel/drivers/net/wireless/rt2x00/rt2x00mac.c 2007-12-04 10:47:57.000000000 +0100
+@@ -421,6 +421,7 @@
+ * The passed variables are stored as real value ((2^n)-1).
+ * Ralink registers require to know the bit number 'n'.
+ */
++#if 0
+ if (params->cw_min)
+ ring->tx_params.cw_min = fls(params->cw_min);
+ else
+@@ -435,6 +436,35 @@
+ ring->tx_params.aifs = params->aifs;
+ else
+ ring->tx_params.aifs = 2;
++#endif
++
++ switch (queue) {
++ case 0:
++ ring->tx_params.aifs = 2;
++ ring->tx_params.cw_max = 4;
++ ring->tx_params.cw_min = 3;
++ break;
++ case 1:
++ ring->tx_params.aifs = 2;
++ ring->tx_params.cw_max = 5;
++ ring->tx_params.cw_min = 4;
++ break;
++ case 2:
++ ring->tx_params.aifs = 3;
++ ring->tx_params.cw_max = 10;
++ ring->tx_params.cw_min = 5;
++ break;
++ case 3:
++ ring->tx_params.aifs = 7;
++ ring->tx_params.cw_max = 10;
++ ring->tx_params.cw_min = 5;
++ break;
++ default:
++ ring->tx_params.aifs = 7;
++ ring->tx_params.cw_max = 10;
++ ring->tx_params.cw_min = 5;
++ break;
++ }
+
+ INFO(rt2x00dev,
+ "Configured TX ring %d - CWmin: %d, CWmax: %d, Aifs: %d.\n",
--- /dev/null
+Index: linux2.6-devel/net/mac80211/wme.c
+===================================================================
+--- linux2.6-devel.orig/net/mac80211/wme.c 2007-12-04 10:59:30.000000000 +0100
++++ linux2.6-devel/net/mac80211/wme.c 2007-12-04 11:01:11.000000000 +0100
+@@ -112,12 +112,12 @@
+
+ /* is this a QoS frame? */
+ qos = fc & IEEE80211_STYPE_QOS_DATA;
+-
++#if 0
+ if (!qos) {
+ skb->priority = 0; /* required for correct WPA/11i MIC */
+ return ieee802_1d_to_ac[skb->priority];
+ }
+-
++#endif
+ /* use the data classifier to determine what 802.1d tag the
+ * data frame has */
+ skb->priority = classify_1d(skb, qd);
--- /dev/null
+ac_param_setup_24-rc3.patch
--- /dev/null
+????-??-??_??:??:??
+*.dat
+*.pdf
+TAGS
+*~
+*.o
+wclient
+wserver
--- /dev/null
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+include Makefile.std
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
--- /dev/null
+bin_PROGRAMS = fwptester fwptesterserver
+
+CFLAGS += -D_REENTRANT -g -DWITH_FWP
+lib_LOADLIBES = pthread rt frsh ulut ncurses
+
+fwptester_SOURCES = wclient.c common.c
+fwptesterserver_SOURCES = wserver.c common.c
--- /dev/null
+# Non-OMK Makefile
+
+PROGS = wserver wclient schedlat
+
+all: $(PROGS)
+.PHONY:all
+
+LDFLAGS = -lpthread -lrt -lncurses
+CFLAGS += -Wall -D_REENTRANT -g -O2
+ifdef DEBUG
+CFLAGS += -DDEBUG=1
+endif
+
+wserver: wserver.o common.o
+wclient: wclient.o common.o
+schedlat: schedlat.o common.o
+
+clean:
+ rm -rf ./*.o
+ rm -f $(PROGS)
--- /dev/null
+#!/bin/sh
+
+for i in BE BK; do
+ ./plot2 -d 150 -P -o ${i}_influence_queue_comp.pdf `cat prefixes_$i`
+done
--- /dev/null
+#!/bin/sh
+
+SET_TERM_TEMPLATE='set term push; set term x11 enhanced; set term wxt enhanced; set term pop'
+
+DELAY_BOUND="[]"
+
+while getopts d:enso:pP opt
+do
+ case $opt in
+ d) DELAY_BOUND="[0:$OPTARG]";;
+ e) SET_TERM_TEMPLATE='set term postscript color eps enhanced; set output "${FILE}.eps"';;
+ n) SET_TERM_TEMPLATE='set term png enhanced; set output "${FILE}.png"';;
+ s) SET_TERM_TEMPLATE='set term svg enhanced; set output "${FILE}.svg"';;
+ o) MULTIPDF_FILENAME=$OPTARG;;
+ p)
+ SET_TERM_TEMPLATE='set term postscript color landscape enhanced'
+ PDF_OUTPUT=1
+ ;;
+ P)
+ SET_TERM_TEMPLATE='set term postscript color portrait enhanced'
+ MULTIPLE_GRAPHS_IN_PDF=1
+ GNUPLOT_CMD_FILE=plot_commands.$$
+ rm -f ${GNUPLOT_CMD_FILE}
+ ;;
+ esac
+done
+
+shift $(($OPTIND - 1))
+
+[ $# -eq 0 -a -r delay_stats.dat ] && set delay_stats.dat
+
+for i in `seq 0 20 340`; do
+ FILE1=`printf $1_%03d $i`
+ FILE2=`printf $2_%03d $i`
+ FILE3=`printf $3_%03d $i`
+# FILE1=`printf 2008-01-22_10:41:16_%03d $i`
+# FILE2=`printf 2008-01-22_11:28:12_%03d $i`
+# FILE3=`printf 2008-01-22_13:40:17_%03d $i`
+
+ COMMAND1="Results of: $(grep 'Invoked as' ${FILE1}.dat|grep -o 'wclient.*'|sed -e 's/ -o [^ ]*//' -e 's/ [^ ]* ?$//')"
+ COMMAND2="Results of: $(grep 'Invoked as' ${FILE2}.dat|grep -o 'wclient.*'|sed -e 's/ -o [^ ]*//' -e 's/ [^ ]* ?$//')"
+ COMMAND3="Results of: $(grep 'Invoked as' ${FILE3}.dat|grep -o 'wclient.*'|sed -e 's/ -o [^ ]*//' -e 's/ [^ ]* ?$//')"
+ STREAMS1="$(grep '^#' ${FILE1}.dat|sed -ne '2,$ s/^# //p'|while read LINE; do echo $LINE\\n; done|tr -d '\n')"
+ STREAMS2="$(grep '^#' ${FILE2}.dat|sed -ne '2,$ s/^# //p'|while read LINE; do echo $LINE\\n; done|tr -d '\n')"
+ STREAMS3="$(grep '^#' ${FILE3}.dat|sed -ne '2,$ s/^# //p'|while read LINE; do echo $LINE\\n; done|tr -d '\n')"
+
+ SET_TERM=$(echo $SET_TERM_TEMPLATE|sed -e s/\${FILE1}/$FILE1/)
+ if [ -n "$MULTIPLE_GRAPHS_IN_PDF" ]; then
+ CMD="cat >>$GNUPLOT_CMD_FILE"
+ elif [ -n "$PDF_OUTPUT" ]; then
+ CMD="cat | gnuplot | ps2pdf - ${FILE}.pdf"
+ else
+ CMD="cat | gnuplot -persist"
+ fi
+ eval $CMD <<EOF
+${SET_TERM}
+unset label
+set xlabel "Response-Time [ms]"
+set ylabel "Cumulative % of packets"
+set key right bottom nobox
+set style data lines
+set style line 1 lw 5 lt 1 lc rgb "red"
+set style line 2 lw 5 lt 1 lc rgb "green"
+set style line 3 lw 5 lt 1 lc rgb "blue"
+set style line 4 lw 5 lt 1 lc rgb "magenta"
+set ytics 10
+set size 1,0.8
+set grid
+set multiplot layout 3,1
+set title "${COMMAND1}" noenhanced offset 0,1.5
+unset label
+set label "${STREAMS1}" noenhanced at graph 0,1.22 font "Helvetica,7"
+plot $DELAY_BOUND [0.01:100]\
+ "${FILE1}.dat" index 0 with lines ls 1 title "AC\\\\_VO",\
+ "${FILE1}.dat" index 1 with lines ls 2 title "AC\\\\_VI",\
+ "${FILE1}.dat" index 2 with lines ls 3 title "AC\\\\_BE",\
+ "${FILE1}.dat" index 3 with lines ls 4 title "AC\\\\_BK"
+set title "${COMMAND2}" noenhanced
+unset label
+set label "${STREAMS2}" noenhanced at graph 0,1.22 font "Helvetica,7"
+plot $DELAY_BOUND [0.01:100]\
+ "${FILE2}.dat" index 0 with lines ls 1 title "AC\\\\_VO with queue",\
+ "${FILE2}.dat" index 1 with lines ls 2 title "AC\\\\_VI with queue",\
+ "${FILE2}.dat" index 2 with lines ls 3 title "AC\\\\_BE with queue",\
+ "${FILE2}.dat" index 3 with lines ls 4 title "AC\\\\_BK with queue"
+set title "${COMMAND3}" noenhanced
+unset label
+set label "${STREAMS3}" noenhanced at graph 0,1.22 font "Helvetica,7"
+plot $DELAY_BOUND [0.01:100]\
+ "${FILE3}.dat" index 0 with lines ls 1 title "AC\\\\_VO with bigger queue",\
+ "${FILE3}.dat" index 1 with lines ls 2 title "AC\\\\_VI with bigger queue",\
+ "${FILE3}.dat" index 2 with lines ls 3 title "AC\\\\_BE with bigger queue",\
+ "${FILE3}.dat" index 3 with lines ls 4 title "AC\\\\_BK with bigger queue"
+unset multiplot
+EOF
+done
+
+if [ -n "$MULTIPLE_GRAPHS_IN_PDF" ]; then
+ gnuplot $GNUPLOT_CMD_FILE|ps2pdf - $MULTIPDF_FILENAME
+ rm -f $GNUPLOT_CMD_FILE
+fi
--- /dev/null
+#!/bin/sh
+
+PREFIX=$(date +%F_%T)
+
+for i in `seq 0 20 340`; do
+ ../wclient -Q 10000 -q -B 100 -b VO,VI,BE:$i -j 50 -s 800 -c 60 -o `printf ${PREFIX}_%03d $i` 192.168.1.100
+done
+
+../plot -d 150 -P -o be_influence_${PREFIX}.pdf ${PREFIX}_*.dat
--- /dev/null
+#!/bin/sh
+
+for queue in BE BK; do
+ for Qsize in 0 3000 6000; do
+ PREFIX=$(date +%F_%T)_${queue}
+ echo $PREFIX >> prefixes_$queue
+ for i in `seq 0 20 340`; do
+ ../wclient -Q $Qsize -q -B 100 -b VO,VI,$queue:$i -j 50 -s 800 -c 60 -o `printf ${PREFIX}_%03d $i` 192.168.1.100
+ done
+
+ ../plot -d 150 -P -o be_influence_${PREFIX}.pdf ${PREFIX}_*.dat
+ done
+done
--- /dev/null
+#include "common.h"
+#include <sched.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <error.h>
+#include <errno.h>
+
+const int prio_to_ac[8] = {2,3,3,2,1,1,0,0};
+const unsigned int ac_to_tos[4] = {224,160,96,64};
+const char *ac_to_text[4] = {[AC_VO] = "AC_VO", [AC_VI] = "AC_VI", [AC_BE] = "AC_BE", [AC_BK] = "AC_BK", };
+
+void set_rt_prio(int priority)
+{
+ int maxpri, minpri;
+ static struct sched_param param;
+
+ if ((maxpri = sched_get_priority_max(SCHED_FIFO)) == -1) {
+ error(8, errno, "sched_get_priority_max fails");
+ }
+
+ if ((minpri = sched_get_priority_min(SCHED_FIFO)) == -1) {
+ error(10, errno, "sched_get_priority_min fails");
+ }
+
+ if (priority > maxpri) {
+ error(9, 0, "maximum priority allowed is %d.\n", maxpri);
+ }
+ if (priority < minpri) {
+ error(11, 0, "minimum priority allowed is %d.\n", minpri);
+ }
+
+ param.sched_priority = priority;
+
+ if (sched_setscheduler(0, SCHED_FIFO, ¶m) == -1) {
+ error(0, errno, "sched_setscheduler fails");
+#ifndef WITH_FWP
+ exit(13);
+#endif
+ }
+}
+
+void block_signals(void)
+{
+ sigset_t sigset;
+ int ret;
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGINT);
+ sigaddset(&sigset, SIGTERM);
+ ret = pthread_sigmask(SIG_BLOCK, &sigset, NULL);
+ if (ret != 0) {
+ perror("pthread_sigmask failed");
+ exit(1);
+ }
+}
+
+static char *num_with_unit(char *buf, unsigned num, const char *units[])
+{
+ const int div[] = {100,10,1};
+ unsigned order = 0;
+ int d;
+
+ while (num > 999 && units[(order+3)/3] != NULL) {
+ num /= 10;
+ order++;
+ }
+
+ d = div[(order+2)%3];
+ if (d == 1)
+ sprintf(buf, "%4d %s", num, units[(order+2)/3]);
+ else
+ sprintf(buf, "%d.%.*d %s", num/d, (d==10) ? 1 : 2, num%d, units[(order+2)/3]);
+ return buf;
+}
+
+char *bandwidth_to_text(char *buf, unsigned bandwidth_bps)
+{
+ const char *unit[] = {"bps", "kbps", "Mbps", NULL};
+ return num_with_unit(buf, bandwidth_bps, unit);
+}
+
+char *usec_to_text(char *buf, unsigned usec)
+{
+ const char *unit[] = {"us", "ms", "s", NULL};
+ return num_with_unit(buf, usec, unit);
+}
+
+
+static void test_usec_to_text() __attribute__((unused));
+static void test_usec_to_text()
+{
+ int num=0;
+ char buf[1000];
+ int i;
+ for (i=1; i<11; i++) {
+ num = num*10 + i;
+ printf("%s = %d\n", usec_to_text(buf, num), num);
+ }
+}
+
--- /dev/null
+#ifndef COMMON_H
+#define COMMON_H
+
+#include <time.h>
+#include <stdint.h>
+
+#define BASE_PORT 5100
+#define AC_NUM 4
+#define MTU 800
+#define BUFFSIZE 65536
+
+#define Kbit 1000
+#define Mbit (Kbit*Kbit)
+
+#define SEC_TO_USEC 1000000LL
+#define MSEC_TO_USEC 1000LL
+#define USEC_TO_NSEC 1000LL
+
+enum ac {
+ AC_VO = 0,
+ AC_VI = 1,
+ AC_BE = 2,
+ AC_BK = 3
+};
+
+struct msg_t {
+/* unsigned int tos; */
+ uint64_t send_timestamp; /* [nsec] */
+ uint64_t sendback_timestamp; /* [nsec] */
+/* unsigned long int seqn; */
+ uint32_t stream;
+#ifdef WITH_FWP
+ uint16_t resp_port;
+#endif
+} __attribute__((packed));
+
+union msg_buff {
+ struct msg_t msg;
+ char nonsense[BUFFSIZE];
+};
+
+
+extern const int prio_to_ac[8];
+extern const unsigned int ac_to_tos[4];
+extern const char *ac_to_text[4];
+
+void block_signals(void);
+void set_rt_prio(int priority);
+char *bandwidth_to_text(char *buf, unsigned bandwidth_bps);
+char *usec_to_text(char *buf, unsigned usec);
+
+static inline
+void timespec_add (struct timespec *sum, const struct timespec *left,
+ const struct timespec *right)
+{
+ sum->tv_sec = left->tv_sec + right->tv_sec;
+ sum->tv_nsec = left->tv_nsec + right->tv_nsec;
+
+ if (sum->tv_nsec >= 1000000000){
+ ++sum->tv_sec;
+ sum->tv_nsec -= 1000000000;
+ }
+}
+
+static inline
+void timespec_sub (struct timespec *diff, const struct timespec *left,
+ const struct timespec *right)
+{
+ diff->tv_sec = left->tv_sec - right->tv_sec;
+ diff->tv_nsec = left->tv_nsec - right->tv_nsec;
+
+ if (diff->tv_nsec < 0){
+ --diff->tv_sec;
+ diff->tv_nsec += 1000000000;
+ }
+}
+
+static inline long long timespec_sub_usec(const struct timespec *left,
+ const struct timespec *right)
+{
+ struct timespec result;
+ timespec_sub(&result, left, right);
+ return (long long)result.tv_sec * SEC_TO_USEC +
+ result.tv_nsec / USEC_TO_NSEC;
+}
+
+static inline long long timespec2usec(const struct timespec *ts)
+{
+ return ts->tv_sec * SEC_TO_USEC + ts->tv_nsec / USEC_TO_NSEC;
+}
+
+#endif
--- /dev/null
+#!/usr/bin/perl -w
+use Getopt::Std;
+
+my %opt;
+getopts('d:', \%opt);
+
+$DELAY_BOUND="[]";
+$DELAY_BOUND="[0:".$opt{'d'}."]" if $opt{'d'};
+
+foreach $prefix (split(' ', `ls *.dat|grep -o '^[0-9]\\+-..'|sort -u`)) {
+ print "$prefix\n";
+ open CMD, "| gnuplot | ps2pdf - ${prefix}.pdf";
+ print CMD qq/
+set term postscript color landscape
+set xlabel "Response-Time [ms]"
+set ylabel "Cumulative % of packets"
+set key right bottom nobox
+set style data linespoints
+#set logscale x
+set grid
+# set size 1,0.8
+# unset label
+# set label "\${COMMAND}" noenhanced at graph 0,1.3
+# set label "\${STREAMS}" noenhanced at graph 0,1.2 font "Helvetica,9"
+/;
+ print CMD "plot $DELAY_BOUND [0.01:100] ";
+ @files=glob "${prefix}*.dat";
+ @plots=map qq/"$_" using 1:2/, @files;
+ print CMD join ',', @plots;
+ close CMD;
+}
--- /dev/null
+#!/bin/sh
+
+EXPERIMENTS=`ls -1 *.dat|egrep -o '^[0-9]+-..'|sort -u`
+
+
+for e in $EXPERIMENTS; do
+ echo "Plotting $e..."
+ ../plot -P -m -t "1 STA;2 STAs;3 STAs;4 STAs" -o $e.pdf $e-?-stas.dat
+done
--- /dev/null
+#!/bin/sh
+export RUNAT="192.168.1.103 localhost/wlan0 localhost/wlan1"
+dest=192.168.1.2
+
+num_sta=$(echo $RUNAT|wc -w)
+
+for tbw in `seq 210 -10 100`; do
+ bw=$((tbw/$num_sta))
+ for ac in VO VI BE BK; do
+ params="-B $bw -b $ac -j 50 -s 100 -q -c 15"
+ for i in $(seq $num_sta); do
+ wclient -I wlan1 $params -o $tbw-$ac-onesta-wlan1-$i $dest &
+ done
+ wait
+ sleep 1
+
+ for i in $(seq $num_sta); do
+ wclient -I wlan0 $params -o $tbw-$ac-onesta-wlan0-$i $dest &
+ done
+ wait
+ sleep 1
+
+ echo "____________________"
+ ./wclientpar $params -o $tbw-$ac-paralel $dest
+ sleep 1
+ echo "===================="
+ done
+done
--- /dev/null
+#!/usr/bin/perl -w
+@run_at = qw|localhost/wlan0 localhost/wlan1 localhost/wlan2 localhost/wlan3|;
+$dest = "192.168.1.2";
+
+sub run {
+ my $at = shift;
+ my @args = @_;
+
+ my ($host, $iface) = split(/\//, $run_at[$at], 2);
+ unshift @args, ('-I', $iface) if (defined $iface);
+ unshift @args, ('wclient');
+ unshift @args, ('ssh', $host) if ($host ne 'localhost');
+ print "running ", join(' ', @args), "\n";
+ if (fork() == 0) {
+ exec(@args);
+ exit();
+ }
+}
+
+
+for ($tbw=10; $tbw<=30; $tbw+=5) {
+ foreach $ac(qw/VO VI BE BK/) {
+ for ($i=1; $i <= @run_at; $i++) {
+ $at = 0;
+
+ @args = (split(/ +/,"-B $tbw -b $ac -j 50 -s 100 -c 60 $dest"), ("-C", "$i STAs"));
+ run($at, (@args, ('-o', "$tbw-$ac-$i-stas")));
+ # Run first tasks at [0] and the remaining in
+ for ($j=1; $j<@run_at; $j++) {
+ if ($j > @run_at - $i) { $at++; }
+ run($at, (@args, ('-o', "$tbw-$ac-$i-stas-$j")));
+ }
+ print "==================\n";
+
+ for ($j=1; $j <= @run_at; $j++) {
+ wait();
+ }
+ sleep(1);
+ }
+ }
+}
+
--- /dev/null
+#!/usr/bin/perl -w
+
+# Runs wclient with given parameters on the host (and interface) given
+# by RUNAT environment variable.
+
+sub get_output {
+ my @a=@ARGV;
+ my $output = "delay_stats";
+ while ($#a >= 0) {
+ if ($a[0] eq "-o") {
+ $output = $a[1];
+ };
+ shift @a;
+ }
+ return $output;
+}
+
+@run_at = qw!localhost localhost localhost/wlan1!;
+@run_at = split(/ +/, $ENV{'RUNAT'}) if $ENV{'RUNAT'};
+
+$i = 0;
+my %outputs;
+foreach $run (@run_at) {
+ ($host, $iface) = split(/\//, $run, 2);
+ @args = ();
+ push @args, ('ssh', $host) if ($host ne 'localhost');
+ push @args, ('wclient');
+ push @args, ('-I', $iface) if (defined $iface);
+ push @args, @ARGV;
+ $output = get_output();
+ $output .= sprintf("-%s%s", $host, defined $iface ? "-$iface":"");
+ if ($outputs{$output}) { $output .= sprintf("-%02d", $i); }
+ $outputs{$output} = 1;
+ push(@args, ('-o', $output));
+ if (fork() == 0) {
+ print "running ", join(' ', @args), "\n";
+ exec(@args);
+ exit();
+ }
+ $i++;
+}
+foreach $run (@run_at) {
+ wait();
+}
--- /dev/null
+#!/usr/bin/perl -w
+use Getopt::Std;
+use File::Basename;
+
+# Default values
+$SET_TERM_TEMPLATE='set term push; set term x11 enhanced; set term wxt enhanced; set term pop';
+$DELAY_BOUND="[]";
+$MULTIPDF_FILENAME="all.pdf";
+
+# Process command line options
+my %opt;
+getopts('bd:emnso:pPt:', \%opt);
+$PLOT_SINGLE_EXPERIMENT = $opt{'m'} ? 0 : 1;
+$EXPERIMENT_TITLES = $opt{'t'};
+$PLOT_BOTH_DIRECTIONS=1 if $opt{'b'};
+$DELAY_BOUND="[0:".$opt{'d'}."]" if $opt{'d'};
+$SET_TERM_TEMPLATE='set term postscript color eps enhanced; set output "${FILE}.eps"' if $opt{'e'};
+$SET_TERM_TEMPLATE='set term png enhanced; set output "${FILE}.png"' if $opt{'n'};
+$SET_TERM_TEMPLATE='set term svg enhanced; set output "${FILE}.svg"' if $opt{'s'};
+$MULTIPDF_FILENAME=$opt{'o'} if $opt{'o'};
+if ($opt{'p'}) {
+ $SET_TERM_TEMPLATE='set term postscript color landscape enhanced';
+ $PDF_OUTPUT=1;
+}
+if ($opt{'P'}) {
+ $SET_TERM_TEMPLATE='set term postscript color landscape enhanced';
+ $MULTIPLE_GRAPHS_IN_PDF=1;
+ $GNUPLOT_CMD_FILE="plot_commands.$$";
+ unlink ${GNUPLOT_CMD_FILE};
+}
+
+if ($#ARGV < 0 && -r "delay_stats.dat") {$ARGV[0]="delay_stats.dat";}
+
+# Process the data files and plot graph(s)
+foreach $dat_file (@ARGV) {
+ ($FILE, , ) = fileparse($dat_file, (".dat"));
+
+ # Get labels from data file
+ $COMMAND="";
+ $STREAMS="";
+ open F, $dat_file;
+ while (<F>) {
+ if (/wclient.*/) {
+ $_=$&;
+ s/ -o [^ ]*//g;
+ $COMMAND="Results of: $_";
+ #$COMMAND="Results of: grep -o 'wclient.*'|sed -e 's/ -o [^ ]*//' -e 's/ [^ ]* ?$//')"
+ } elsif (/^#[^#] */) {
+ $STREAMS .= "$'";
+ }
+
+
+ }
+ close F;
+ $STREAMS =~ s/\n/\\n/g;
+
+ if ($MULTIPLE_GRAPHS_IN_PDF) {
+ open CMD, ">>$GNUPLOT_CMD_FILE";
+ } elsif ($PDF_OUTPUT) {
+ open CMD, "| gnuplot | ps2pdf - ${FILE}.pdf";
+ } else {
+ open CMD, "| gnuplot -persist";
+ }
+# close CMD;
+# open CMD, ">&STDOUT";
+ $SET_TERM = $SET_TERM_TEMPLATE;
+ $SET_TERM =~ s/\${FILE}/$FILE/;
+
+ print CMD qq/
+${SET_TERM}
+set xlabel "Response-Time [ms]"
+set ylabel "Cumulative % of packets"
+set key right bottom nobox
+set style data linespoints
+#set logscale x
+set grid
+set size 1,0.8
+unset label
+set label "${COMMAND}" noenhanced at graph 0,1.3
+set label "${STREAMS}" noenhanced at graph 0,1.2 font "Helvetica,9"
+/;
+ if ($PLOT_SINGLE_EXPERIMENT) {
+ print CMD qq/
+set style line 1 lt 1 lc rgb "red"
+set style line 2 lt 1 lc rgb "green"
+set style line 3 lt 1 lc rgb "blue"
+set style line 4 lt 1 lc rgb "magenta"
+set style line 5 lt 2 lc rgb "red" lw 2
+set style line 6 lt 2 lc rgb "green" lw 2
+set style line 7 lt 2 lc rgb "blue" lw 2
+set style line 8 lt 2 lc rgb "magenta" lw 2
+set style line 9 lt 3 lc rgb "red" lw 2
+set style line 10 lt 3 lc rgb "green" lw 2
+set style line 11 lt 3 lc rgb "blue" lw 2
+set style line 12 lt 3 lc rgb "magenta" lw 2
+/;
+ print CMD qq/plot $DELAY_BOUND [0.01:100]\\
+ "${FILE}.dat" index 0 using 1:2 with linespoints ls 1 title "AC\\\\_VO",\\
+ "${FILE}.dat" index 1 using 1:2 with linespoints ls 2 title "AC\\\\_VI",\\
+ "${FILE}.dat" index 2 using 1:2 with linespoints ls 3 title "AC\\\\_BE",\\
+ "${FILE}.dat" index 3 using 1:2 with linespoints ls 4 title "AC\\\\_BK"/;
+
+ if ($PLOT_BOTH_DIRECTIONS) {
+ print CMD qq/,\\
+ "${FILE}.dat" index 0 using 1:3 with lines ls 5 title "AC\\\\_VO cs",\\
+ "${FILE}.dat" index 1 using 1:3 with lines ls 6 title "AC\\\\_VI cs",\\
+ "${FILE}.dat" index 2 using 1:3 with lines ls 7 title "AC\\\\_BE cs",\\
+ "${FILE}.dat" index 3 using 1:3 with lines ls 8 title "AC\\\\_BK cs",\\
+ "${FILE}.dat" index 0 using 1:4 with lines ls 9 title "AC\\\\_VO sc",\\
+ "${FILE}.dat" index 1 using 1:4 with lines ls 10 title "AC\\\\_VI sc",\\
+ "${FILE}.dat" index 2 using 1:4 with lines ls 11 title "AC\\\\_BE sc",\\
+ "${FILE}.dat" index 3 using 1:4 with lines ls 12 title "AC\\\\_BK sc"
+/;
+ } else {
+ print CMD "\n";
+ }
+ } else {
+ # Multiple experiments in a single plot
+ print CMD qq/
+set style line 1 lt 1 lc rgb "red" lw 2
+set style line 2 lt 1 lc rgb "green" lw 2
+set style line 3 lt 1 lc rgb "blue" lw 2
+set style line 4 lt 1 lc rgb "magenta" lw 2
+set style line 5 lt 2 lc rgb "red" lw 2
+set style line 6 lt 2 lc rgb "green" lw 2
+set style line 7 lt 2 lc rgb "blue" lw 2
+set style line 8 lt 2 lc rgb "magenta" lw 2
+set style line 9 lt 3 lc rgb "red" lw 2
+set style line 10 lt 3 lc rgb "green" lw 2
+set style line 11 lt 3 lc rgb "blue" lw 2
+set style line 12 lt 3 lc rgb "magenta" lw 2
+/;
+ my ($ls1, $ls2, $ls3, $ls4) = (1,2,3,4);
+ my @titles = split(/;/, $EXPERIMENT_TITLES);
+ my $experiment = 0;
+ my $t=$titles[$experiment];
+ $t = '' unless $t;
+ print CMD qq/plot $DELAY_BOUND [0.01:100]\\
+ "${FILE}.dat" index 0 using 1:2 with lines ls $ls1 title "AC\\\\_VO $t",\\
+ "${FILE}.dat" index 1 using 1:2 with lines ls $ls2 title "AC\\\\_VI $t",\\
+ "${FILE}.dat" index 2 using 1:2 with lines ls $ls3 title "AC\\\\_BE $t",\\
+ "${FILE}.dat" index 3 using 1:2 with lines ls $ls4 title "AC\\\\_BK $t"/;
+ foreach $dat_file (@ARGV[1,2]) {
+ last if (!defined $dat_file);
+ $experiment++;
+ $t=$titles[$experiment];
+ $t = '' unless $t;
+ ($FILE, , ) = fileparse($dat_file, (".dat"));
+ ($ls1, $ls2, $ls3, $ls4) = map($_+4, ($ls1, $ls2, $ls3, $ls4));
+ print CMD qq/,\\
+ "${FILE}.dat" index 0 using 1:2 with lines ls $ls1 title "AC\\\\_VO $t",\\
+ "${FILE}.dat" index 1 using 1:2 with lines ls $ls2 title "AC\\\\_VI $t",\\
+ "${FILE}.dat" index 2 using 1:2 with lines ls $ls3 title "AC\\\\_BE $t",\\
+ "${FILE}.dat" index 3 using 1:2 with lines ls $ls4 title "AC\\\\_BK $t"/;
+ }
+ print CMD "\n";
+ last;
+ }
+
+ close CMD;
+}
+
+if ($MULTIPLE_GRAPHS_IN_PDF) {
+ system("gnuplot $GNUPLOT_CMD_FILE|ps2pdf - $MULTIPDF_FILENAME");
+ unlink ${GNUPLOT_CMD_FILE};
+}
--- /dev/null
+set term postscript color
+set output 'delay_stats.eps'
+#set term x11
+#set title "TITLE"
+set xlabel "Delay (ms)"
+set ylabel "Packet percentage"
+set key right top nobox
+set grid
+plot [0:*] [0.01:*] "delay_stats.dat" using 1:2 smooth csplines title "AC_VO",\
+ "delay_stats.dat" using 1:3 smooth csplines title "AC_VI",\
+ "delay_stats.dat" using 1:4 smooth csplines title "AC_BE",\
+ "delay_stats.dat" using 1:5 smooth csplines title "AC_BK"
+#set term postscript color eps size 12cm,9cm
+#set output '${FILE}.eps'
+#replot
--- /dev/null
+#!/bin/sh
+set -e
+
+FILE=delay_stats
+
+ARGV="$@"
+
+while [ $# -gt 0 ]
+do
+ case $1 in
+ -o) FILE="$2";;
+ esac
+ shift
+done
+
+`dirname $0`/wclient $ARGV
+
+`dirname $0`/plot $FILE.dat
--- /dev/null
+#!/bin/sh
+
+for q in BE VI VO; do
+ ../plot -d 300 -o ${q}_packet_size_300.pdf -P ${q}_packet_size_*.dat
+# ../plot -d 2000 -o ${q}_packet_size_2000.pdf -P ${q}_packet_size_*.dat
+done
+./sat-graph
+./sat-graph -m
+
+
+
--- /dev/null
+#!/bin/sh
+
+for i in 12 `seq 20 10 200` `seq 250 50 1400` `seq 1450 10 1520` `seq 1550 50 2000`
+do
+ ../wclient -q -Q 3000 -B 100 -b VO/$i,VI,BE:500 -j 50 -s 800 -c 50 -o `printf VO_packet_size_%04d $i` 192.168.1.100
+ ../wclient -q -Q 3000 -B 100 -b VO,VI/$i,BE:500 -j 50 -s 800 -c 50 -o `printf VI_packet_size_%04d $i` 192.168.1.100
+ ../wclient -q -Q 3000 -B 100 -b VO,VI,BE:500/$i -j 50 -s 800 -c 50 -o `printf BE_packet_size_%04d $i` 192.168.1.100
+done
--- /dev/null
+#!/usr/bin/perl -w
+
+$pdf_output=1;
+$multiple_graphs=1 if ($#ARGV >= 0 && $ARGV[0] eq "-m");
+
+#$Q=$ARGV[0] || "VI";
+
+foreach $Q (("VO", "VI", "BE")) {
+
+ $base_name="${Q}_packet_size_";
+ $graph_data_name = "${base_name}graph";
+
+ open G, ">$graph_data_name" || die "error opening $graph_data_name";
+ foreach $f (glob "${base_name}*.dat") {
+ open F, $f;
+ while (<F>) {
+ if (/AC_${Q}/) {
+ ($a) = /([0-9]*) bytes/;
+ ($b)=/real: +([0-9.]+) kbps/;
+ }
+ if (/AC_BE/) {
+ ($c) = /real: +([0-9.]+) kbps/;
+ if (!$c) {
+ ($c) = /real: +([0-9.]+) bps/;
+ $c/=1000.0;
+ }
+ print G "$a $b $c\n";
+ }
+ }
+ close F;
+ }
+ close G;
+}
+if ($pdf_output) {
+ if ($multiple_graphs) {
+ $pdf = "packet_sizes_sat.pdf";
+ } else {
+ $pdf = "packet_sizes_sat_comp.pdf";
+ }
+ open GNUPLOT, "|gnuplot|ps2pdf - $pdf";
+ print GNUPLOT "set term postscript color landscape\n";
+} else {
+ open GNUPLOT, "|gnuplot -persist";
+}
+
+print GNUPLOT <<EOF;
+#set key off
+set key right bottom nobox
+set style data linespoints
+set grid
+EOF
+
+if ($multiple_graphs) {
+ foreach $Q (("VO", "VI", "BE")) {
+ $base_name="${Q}_packet_size_";
+ $graph_data_name = "${base_name}graph";
+
+ print GNUPLOT qq/set title "Influence of AC_$Q packet sizes to saturation bandwidth of AC_BE"\n/;
+ print GNUPLOT qq/set xlabel "AC_$Q packet sizes [bytes]"\n/;
+ print GNUPLOT qq/set ylabel "Bandwidth [kbps]"\n/;
+ print GNUPLOT qq/plot /;
+ if ($Q ne "BE") {
+ print GNUPLOT qq/"$graph_data_name" using 1:3 title "AC_BE", /;
+ }
+ print GNUPLOT qq/"$graph_data_name" using 1:2 title "AC_${Q}"\n/;
+ }
+} else {
+ print GNUPLOT qq/set title "Influence of different packet sizes to saturation bandwidth of AC_BE"\n/;
+ print GNUPLOT qq/set xlabel "Packet sizes [bytes]"\n/;
+ print GNUPLOT qq/set ylabel "AC_BE bandwidth [kbps]"\n/;
+ @plots=();
+ foreach $Q (("VO", "VI", "BE")) {
+ $base_name="${Q}_packet_size_";
+ $graph_data_name = "${base_name}graph";
+
+ push @plots, qq/"$graph_data_name" using 1:3 title "packet size of AC_${Q} was being changed"/;
+ }
+ print GNUPLOT "plot ", join(", ", @plots), "\n";
+}
+
+close GNUPLOT;
--- /dev/null
+#include <stdio.h>
+#include <signal.h>
+#include <stdint.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sched.h>
+#include <string.h>
+#include "common.h"
+
+static inline uint64_t rdtsc(void) {
+ uint32_t hi, lo;
+ asm volatile ("rdtsc" : "=a" (lo), "=d" (hi));
+ return ((uint64_t)hi << 32) | lo;
+}
+
+void int_handler(int sig)
+{
+ exit(0);
+}
+
+static double cpu_mhz;
+
+void find_cpu_clock()
+{
+ FILE *f;
+ char line[100];
+ f = fopen("/proc/cpuinfo", "r");
+ if (!f) {
+ perror("/proc/cpuinfo");
+ exit(1);
+ }
+ while (fgets(line, sizeof(line), f)) {
+ if (strncmp(line, "cpu MHz", 7) == 0) {
+ double mhz;
+ int ret = sscanf(line, "cpu MHz : %lf", &mhz);
+ if (ret != 1) {
+ fprintf(stderr, "Can't read cpu Mhz\n");
+ exit(1);
+ }
+ cpu_mhz = mhz;
+ printf("CPU frequency: %.0lf MHz\n", cpu_mhz);
+ break;
+ }
+ }
+ fclose(f);
+}
+
+#define CLOCK_TO_SEC(clock) ((double)(clock)/(cpu_mhz*1000.0*1000.0))
+
+void measure()
+{
+ struct timespec ts = { .tv_sec = 0, .tv_nsec = 10*1000*1000 };
+ /* uint64_t start, end; */
+ long long duration;
+ long long difference, max_difference = 0;
+ struct timespec start, end;
+ while (1) {
+ clock_gettime(CLOCK_MONOTONIC, &start);
+ nanosleep(&ts, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &end);
+ duration = timespec_sub_usec(&end, &start);
+ difference = duration - ts.tv_nsec/1000;
+ if (difference > max_difference) {
+ max_difference = difference;
+ printf("%lld usec\n", max_difference);
+ }
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ struct sigaction act = {
+ .sa_handler = int_handler
+ };
+
+ find_cpu_clock();
+ sigaction(SIGINT, &act, NULL);
+ set_rt_prio(50);
+ measure();
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+
+TEST_DIR=tests
+OUTPUT_PREFIX=$(date +%F_%T)/
+
+while getopts t:o: opt
+do
+ case $opt in
+ t) TEST_DIR="$OPTARG";;
+ o) OUTPUT_PREFIX="$OPTARG"
+ esac
+done
+
+shift $(($OPTIND - 1))
+SERVER="$1"
+
+if [ -z "$SERVER" ]
+then
+ echo "Server address argument missing"
+ exit 1
+fi
+
+if echo $OUTPUT_PREFIX|grep -q "/$"
+then
+ mkdir -p $OUTPUT_PREFIX
+ [ -n "$SUDO_USER" ] && chown $SUDO_USER $OUTPUT_PREFIX
+fi
+
+find -L $TEST_DIR -type f|sort|while read F
+do
+ CMD_LINE=$(echo $F|sed -e "s/${TEST_DIR}//"|tr '/' ' ')
+ OUTPUT=$(echo $CMD_LINE|tr -s '/ -' '_')
+ echo "=== Running ./wclient $CMD_LINE"
+ ./wclient $CMD_LINE -o "${OUTPUT_PREFIX}${OUTPUT}" $SERVER
+ echo
+ sleep 1
+done
--- /dev/null
+#include <errno.h>
+#include <error.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <string.h>
+#include <pthread.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include "common.h"
+#include <semaphore.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <inttypes.h>
+#include <ncurses.h>
+
+#ifdef WITH_FWP
+#include <ul_logreg.h>
+#endif
+
+#ifdef WITH_FWP
+#include <frsh.h>
+#include <fwp_res.h>
+
+/* static UL_LOG_CUST(ulogd); */
+/* static ul_log_domain_t ulogd = {UL_LOGL_MSG, "wclient"}; */
+/* UL_LOGREG_SINGLE_DOMAIN_INIT_FUNCTION(init_ulogd_wclient, ulogd); */
+
+#endif
+
+#define MAX_STREAMS 10
+#define MIN_GRANULARITY 100
+
+unsigned opt_packet_size = 800;
+int opt_send_buf_size = -1;
+unsigned opt_period_usec = 10*MSEC_TO_USEC;
+char *opt_interface;
+unsigned opt_jitter = 0;
+char *opt_output = "delay_stats";
+unsigned opt_count_sec = 0;
+unsigned opt_def_bandwidth = 50;
+unsigned opt_def_period_msec = 0;
+int opt_granularity_usec = MIN_GRANULARITY;
+bool opt_wait_for_queue_is_full; /* Don't gather any statistics until any queue is full */
+char *opt_comment = NULL;
+bool opt_gui = false;
+
+bool some_queue_is_full = false;
+uint64_t reset_timestamp; /* [nsec] */
+
+bool some_contract_not_accepted = false;
+
+/* Locked when some queue is full to prevent multiple resets of
+ statstics. */
+pthread_mutex_t queue_full_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+int ac_sockfd[AC_NUM];
+
+struct receiver {
+ bool valid;
+ pthread_t thread;
+ unsigned received, last_received;
+};
+
+struct receiver receivers[AC_NUM];
+
+FILE* logfd;
+char* server_addr;
+char logfname[100];
+
+/* maximal traffic delay in ms - 10 s*/
+#define MAX_DELAY_US 10000000
+
+struct delay_stat {
+ unsigned csc; /* Client-server-client delay divided by 2 */
+ unsigned cs; /* Client-server delay */
+ unsigned sc; /* Server-client delay */
+};
+
+struct delay_stat delay_stats[AC_NUM][MAX_DELAY_US/MIN_GRANULARITY];
+pthread_mutex_t delay_stats_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/*struct ac_stats[AC_NUM] {
+ unsigned long int min_trans_time;
+ unsigned long int sum_trans_time;
+ struct timespec recv_timestamp;
+ struct timespec send_timestamp;
+};*/
+
+struct stream {
+ /* Input parameters */
+ enum ac ac; /* */
+ int bandwidth_bps; /* bits per second */
+ int jitter; /* percent */
+ /* Mulualy exclusive input parameters */
+ int packet_size;
+ long period_usec; /* all time units are in microseconds */
+
+ /* Internal fields */
+#ifndef WITH_FWP
+ struct sockaddr_in rem_addr;
+#else
+ frsh_send_endpoint_t endpoint;
+ frsh_receive_endpoint_t resp_endpoint;
+ frsh_vres_id_t vres, vres_rcv;
+ uint16_t resp_port;
+ struct receiver receiver;
+#endif
+
+ /* Statistics */
+ pthread_mutex_t mutex;
+ unsigned long long sent, really_sent, received;
+ long wc_delay; /* worst-case delay */
+};
+
+static struct cmsg_ipi {
+ struct cmsghdr cm;
+ struct in_pktinfo ipi;
+} cmsg = { {sizeof(struct cmsg_ipi), SOL_IP, IP_PKTINFO},
+ {0, }};
+int cmsg_len = 0;
+
+/*
+struct send_endpoint sepoint[] = {
+ { .ac = AC_VO, .period_usec=200*MSEC_TO_USEC, .bandwidth_bps = 34*Kbit },
+ { .ac = AC_VI, .period_usec=25*MSEC_TO_USEC, .bandwidth_bps = 480*Kbit },
+ { .ac = AC_BE, .period_usec=40*MSEC_TO_USEC, .bandwidth_bps = 300*Kbit },
+ { .ac = AC_BK, .period_usec=40*MSEC_TO_USEC, .bandwidth_bps = 300*Kbit },
+// { .ac = AC_VI, .period_usec=17*MSEC_TO_USEC, .bandwidth_bps = 675*Kbit },
+};
+*/
+
+struct stream streams[MAX_STREAMS];
+
+unsigned int nr_streams = 0;
+
+sem_t sem_thread_finished;
+
+bool exit_flag = false;
+
+#ifdef WITH_FWP
+#define negotiate_contract_for_stream(s) negotiate_contract_for_stream_fwp(s)
+#define create_stream_endpoint(s) create_stream_endpoint_fwp(s)
+#define send_packet(s, b) send_packet_fwp(s, b)
+#define recv_packet(s, b) recv_packet_fwp(s, b)
+#define wait_for_all_threads_to_finish() wait_for_all_threads_to_finish_fwp()
+#else
+#define negotiate_contract_for_stream(s) 0
+#define create_stream_endpoint(s) create_stream_endpoint_native(s)
+#define send_packet(s, b) send_packet_native(s, b)
+#define recv_packet(s, b) recv_packet_native(s, b)
+#define wait_for_all_threads_to_finish() wait_for_all_threads_to_finish_native()
+#endif
+
+void stopper()
+{
+ int i;
+ exit_flag = true;
+
+ /* Interrupt all receivers */
+#ifdef WITH_FWP
+ for (i=0; i < nr_streams; i++) {
+ if (streams[i].receiver.valid) pthread_kill(streams[i].receiver.thread, SIGUSR1);
+ }
+#else
+ for (i=0; i < AC_NUM; i++) {
+ pthread_kill(receivers[i].thread, SIGUSR1);
+ }
+#endif
+}
+
+void stream_to_text(char *stream_desc, size_t n, struct stream *stream, long long useconds)
+{
+ char buf[3][12];
+ char real[100];
+
+ if (useconds) {
+ snprintf(real, sizeof(real), "; real: %s sent %lld (%lld/s), received %lld (%lld/s)",
+ bandwidth_to_text(buf[0], (long long)stream->really_sent*stream->packet_size*8*SEC_TO_USEC/useconds),
+ stream->sent, stream->sent*SEC_TO_USEC/useconds,
+ stream->received, stream->received*SEC_TO_USEC/useconds);
+ } else {
+ real[0]=0;
+ }
+
+ snprintf(stream_desc, n, "%"PRIdPTR": %s %s (%d bytes per %s +-%s, %d packets/s)%s",
+ stream-streams, ac_to_text[stream->ac], bandwidth_to_text(buf[0], stream->bandwidth_bps),
+ stream->packet_size, usec_to_text(buf[1], stream->period_usec),
+ usec_to_text(buf[2], stream->jitter*stream->period_usec/100),
+ (int)(SEC_TO_USEC/stream->period_usec), real);
+}
+
+void save_results(int argc, char *argv[], int useconds)
+{
+ int ac, i, maxi;
+ const int mini = 3000/opt_granularity_usec;
+ bool allzeros;
+ unsigned send_count[AC_NUM];
+
+ fprintf(stderr, "Writing data to %s... ", logfname);
+ fflush(stderr);
+
+ fprintf(logfd, "# Invoked as: ");
+ for (i=0; i<argc; i++) fprintf(logfd, "%s ", argv[i]);
+ if (opt_comment) {
+ fprintf(logfd, "(%s)", opt_comment);
+ }
+ fprintf(logfd, "\n");
+
+ if (useconds/SEC_TO_USEC != opt_count_sec) {
+ char buf[20];
+ usec_to_text(buf, useconds);
+ fprintf(logfd, "# Data gathered for %s.\n", buf);
+ }
+
+ for (i = 0; i < nr_streams; i++) {
+ char stream_desc[200];
+ stream_to_text(stream_desc, sizeof(stream_desc), &streams[i], useconds);
+ fprintf(logfd, "# Stream %s\n", stream_desc);
+ }
+
+ /* Find maximal delay */
+ allzeros = true;
+ for (maxi = MAX_DELAY_US/opt_granularity_usec - 1; maxi >= 0; maxi--) {
+ for (ac = 0; ac < AC_NUM; ac++) {
+ if ((delay_stats[ac][maxi].csc != 0) ||
+ (delay_stats[ac][maxi].cs != 0) ||
+ (delay_stats[ac][maxi].sc != 0))
+ allzeros = false;
+ }
+ if (!allzeros) break;
+ }
+ maxi++;
+ if (maxi < mini) maxi = mini;
+
+ /* Calculate total number of sent packets per AC */
+ memset(send_count, 0, sizeof(send_count));
+ for (i = 0; i < nr_streams; i++) {
+ ac = streams[i].ac;
+ send_count[ac] += streams[i].sent;
+ }
+
+#if 0
+ /* Write pdf */
+ for ( i = 0 ; i < maxi; i++) {
+ fprintf(logfd,"\n%f", i*opt_granularity_usec/1000.0);
+ for (ac = 0; ac < AC_NUM; ac++) {
+ if (sum[ac])
+ val = (double)delay_stats[ac][i]*100.0 / sum[ac];
+ else val = -1; /* Don't display this ac */
+ fprintf(logfd," %lf", val);
+ }
+ }
+
+ fprintf(logfd,"\n\n");
+#endif
+
+ fprintf(logfd,"## Format: msec csc%% cs%% sc%%\n");
+
+ /* Write PDF */
+ for (ac = 0; ac < AC_NUM; ac++) {
+ struct delay_stat integral = {0,0,0}, last = {-1,-1,-1};
+
+ fprintf(logfd,"%f %f %f %f\n", 0.0, 0.0, 0.0, 0.0);
+
+ if (send_count[ac] != 0) {
+ i=0;
+ while ((delay_stats[ac][i].csc == 0) &&
+ (delay_stats[ac][i].cs == 0) &&
+ (delay_stats[ac][i].sc == 0)) i++;
+
+ for (i++; i < maxi+1; i++) {
+ if (memcmp(&last, &integral, sizeof(last))) {
+ char buf[3][20];
+ snprintf(buf[0], sizeof(buf[0]), "%f", (double)integral.csc*100.0 / send_count[ac]);
+ snprintf(buf[1], sizeof(buf[1]), "%f", (double)integral.cs *100.0 / send_count[ac]);
+ snprintf(buf[2], sizeof(buf[2]), "%f", (double)integral.sc *100.0 / send_count[ac]);
+
+ fprintf(logfd,"%f %s %s %s\n", i*opt_granularity_usec/1000.0,
+ integral.csc != last.csc ? buf[0] : "-",
+ integral.cs != last.cs ? buf[1] : "-",
+ integral.sc != last.sc ? buf[2] : "-"
+ );
+ last = integral;
+ }
+ if (i>0) {
+ integral.csc += delay_stats[ac][i-1].csc;
+ integral.sc += delay_stats[ac][i-1].sc;
+ integral.cs += delay_stats[ac][i-1].cs;
+ }
+ }
+ }
+ fprintf(logfd,"\n\n");
+ }
+
+ fprintf(stderr, "finished.\n");
+ fclose(logfd);
+
+ exit(0);
+}
+
+int create_ac_socket(intptr_t ac)
+{
+ int sockfd;
+ unsigned int yes=1, tos;
+
+
+ if ((sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+ {
+ error(0, errno, "Unable to open socket");
+ return -1;
+ }
+ if (fcntl(sockfd, F_SETFL, O_NONBLOCK) != 0) {
+ error(0, errno, "set non-blocking socket");
+ return -1;
+ }
+ if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
+ error(0, errno, "Unable to set socket");
+ return -1;
+ }
+
+ if (opt_send_buf_size >= 0) {
+ if (setsockopt(sockfd,SOL_SOCKET,SO_SNDBUF,&opt_send_buf_size,sizeof(opt_send_buf_size)) == -1) {
+ error(0, errno, "Unable to set socket buffer size");
+ return -1;
+ }
+ }
+
+
+ //tos = ((AC_NUM - ac) *2 - 1)*32;
+ tos = ac_to_tos[ac];
+ if (setsockopt(sockfd, SOL_IP, IP_TOS, &tos, sizeof(tos))) {
+ error(0, errno, "Unable to set TOS");
+ close(sockfd);
+ return -1;
+ }
+
+ return sockfd;
+}
+
+void empty_handler()
+{
+}
+
+void reset_statistics()
+{
+ int i;
+ struct timespec ts;
+ for (i = 0; i < nr_streams; i++) {
+ pthread_mutex_lock(&streams[i].mutex);
+ streams[i].sent = 0;
+ streams[i].really_sent = 0;
+ streams[i].received = 0;
+ pthread_mutex_unlock(&streams[i].mutex);
+ }
+ pthread_mutex_lock(&delay_stats_mutex);
+ clock_gettime(CLOCK_REALTIME, &ts);
+ reset_timestamp = ts.tv_sec*1000000000LL + ts.tv_nsec;
+ memset(delay_stats, 0, sizeof(delay_stats));
+ pthread_mutex_unlock(&delay_stats_mutex);
+}
+
+#ifndef WITH_FWP
+int recv_packet_native(intptr_t ac, struct msg_t *msg)
+{
+ int mlen, ret;
+ fd_set fdset;
+ struct sockaddr_in rem_addr;
+ unsigned int rem_addr_length;
+
+ FD_ZERO(&fdset);
+ FD_SET(ac_sockfd[ac], &fdset);
+ rem_addr_length = sizeof(rem_addr);
+ mlen = -1;
+ while (!exit_flag) {
+ ret = select(ac_sockfd[ac]+1, &fdset, NULL, NULL, NULL);
+ if (ret < 0) {
+ if (errno == EINTR) continue;
+ error(0, errno, "receiver select");
+ return -1;
+ }
+ mlen = recvfrom(ac_sockfd[ac], msg, sizeof(*msg), 0,
+ (struct sockaddr*)&rem_addr, &rem_addr_length);
+ break;
+ }
+ return mlen;
+}
+#else
+int recv_packet_fwp(struct stream *stream, struct msg_t *msg)
+{
+ int ret;
+ size_t mlen;
+
+ ret = frsh_receive_sync(stream->resp_endpoint, msg, sizeof(*msg), &mlen, NULL);
+ return mlen;
+}
+#endif
+
+void* receiver(void* arg)
+{
+ struct msg_t msg;
+ long long int trans_time_usec, client_to_server_usec, server_to_client_usec;
+ long long int min_trans_time;
+ struct timespec ts;
+ uint64_t send_timestamp, server_timestamp, recv_timestamp;
+ int mlen;
+ intptr_t ac;
+
+ min_trans_time = ~0;
+
+ block_signals();
+ set_rt_prio(99);
+
+ while (!exit_flag) {
+#ifdef WITH_FWP
+ struct stream *stream = arg;
+ ac = stream->ac;
+ mlen = recv_packet_fwp(stream, &msg);
+#else
+ ac = (intptr_t)arg;
+ mlen = recv_packet_native(ac, &msg);
+#endif
+ if (mlen < 0) {
+ if (errno != EINTR)
+ error(0, errno, "receive_packet error");
+ goto out;
+ }
+ clock_gettime(CLOCK_REALTIME,&ts);
+ recv_timestamp = ts.tv_sec*1000000000LL + ts.tv_nsec;
+ send_timestamp = msg.send_timestamp;
+ server_timestamp = msg.sendback_timestamp;
+
+ /* Check whether this message was sent after reset_statistics() */
+
+ if (send_timestamp < reset_timestamp) {
+ continue; /* If so, don't count it */
+ }
+
+ trans_time_usec = (recv_timestamp - send_timestamp) / 2 / 1000;
+ client_to_server_usec = (server_timestamp - send_timestamp) / 1000;
+ server_to_client_usec = (recv_timestamp - server_timestamp) / 1000;
+
+ pthread_mutex_lock(&delay_stats_mutex);
+ if (trans_time_usec < MAX_DELAY_US && trans_time_usec >= 0) {
+ delay_stats[ac][trans_time_usec/opt_granularity_usec].csc++;
+ }
+ if (client_to_server_usec < MAX_DELAY_US && client_to_server_usec >= 0) {
+ delay_stats[ac][client_to_server_usec/opt_granularity_usec].cs++;
+ }
+ if (server_to_client_usec < MAX_DELAY_US && server_to_client_usec >= 0) {
+ delay_stats[ac][server_to_client_usec/opt_granularity_usec].sc++;
+ }
+ pthread_mutex_unlock(&delay_stats_mutex);
+
+ if (trans_time_usec > streams[msg.stream].wc_delay) {
+ streams[msg.stream].wc_delay = trans_time_usec;
+ }
+ receivers[ac].received++;
+
+ pthread_mutex_lock(&streams[msg.stream].mutex);
+ streams[msg.stream].received++;
+ pthread_mutex_unlock(&streams[msg.stream].mutex);
+
+ /*if (trans_time_nsec < min_trans_time)
+ min_trans_time = trans_time_nsec;*/
+ /*printf("seqn= %lu tos= %d start= %lu(s).%lu(ns)"\
+ "stop= %lu(s).%lu(ns)\n trans_time = %lums\n",\
+ msg.seqn, msg.tos, send_timestamp.tv_sec,\
+ send_timestamp.tv_nsec,recv_timestamp.tv_sec,\
+ recv_timestamp.tv_nsec, trans_time_msec); */
+ }
+out:
+ sem_post(&sem_thread_finished);
+ return NULL;
+}
+
+/**
+ * Send a packet.
+ *
+ * @return -1 in case of error, 1 in case of sucessfull send and 0
+ * when all buffers are full.
+ */
+#ifndef WITH_FWP
+static inline int
+send_packet_native(struct stream* stream, union msg_buff* buff)
+{
+ struct iovec iov;
+ struct msghdr msg;
+
+ iov.iov_base = buff;
+ iov.iov_len = stream->packet_size;
+ msg.msg_name = (void*)&stream->rem_addr;
+ msg.msg_namelen = sizeof(stream->rem_addr);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_flags = 0;
+ msg.msg_control = &cmsg;
+ msg.msg_controllen = cmsg_len;
+
+ int ret = 1;
+
+ while (sendmsg(ac_sockfd[stream->ac], &msg, 0) < 0) {
+ if (errno == EINTR) continue;
+ if (errno == EAGAIN) {
+ if (opt_wait_for_queue_is_full &&
+ !some_queue_is_full &&
+ /* We use mutex as atomic test and set */
+ (pthread_mutex_trylock(&queue_full_mutex) != EBUSY)) {
+ some_queue_is_full = true;
+ reset_statistics();
+ }
+ ret = 0;
+ break;
+ } else {
+ error(0, errno, "Error while sending");
+ ret = -1;
+ break;
+ }
+ }
+ return ret;
+}
+#else
+static inline int
+send_packet_fwp(struct stream* stream, union msg_buff* buff)
+{
+ int ret = 0;
+
+ buff->msg.resp_port = htons(stream->resp_port);
+ ret = frsh_send_async(stream->endpoint, buff, stream->packet_size);
+ if (ret) {
+ char msg[1024];
+ frsh_strerror(ret, msg, sizeof(msg));
+ fprintf(stderr, "frsh_send error: %s\n", msg);
+ }
+ return (ret == 0) ? 0 : -1;
+}
+#endif
+
+static inline void
+wait_for_next_send(struct stream* stream, struct timespec *last_send_time)
+{
+ struct timespec time_to_wait, current_time, period, interval;
+ unsigned delay_usec, period_usec = stream->period_usec;
+
+ /* |~~~+~~~| jitter interval (width = 2*stream->jitter percentage from period)*/
+ /* |-------------| nominal period*/
+ if (stream->jitter) {
+ delay_usec = period_usec*(100-stream->jitter)/100
+ + rand() % (2*period_usec*stream->jitter/100);
+ } else {
+ delay_usec = period_usec;
+ }
+ period.tv_nsec = USEC_TO_NSEC*(delay_usec%SEC_TO_USEC);
+ period.tv_sec = delay_usec/SEC_TO_USEC;
+
+ timespec_add(&time_to_wait, last_send_time, &period);
+ clock_gettime(CLOCK_MONOTONIC,¤t_time);
+ timespec_sub(&interval,&time_to_wait,¤t_time);
+ if (interval.tv_sec >= 0) {
+ nanosleep(&interval,NULL);
+ *last_send_time = time_to_wait;
+ } else {
+ *last_send_time = current_time;
+ }
+}
+
+
+void* sender(void* arg)
+{
+ union msg_buff buff;
+ unsigned long int seqn;
+ struct stream* stream = (struct stream*) arg;
+ struct timespec timer = { 0, 0 }, ts;
+ int ret;
+
+ if (!opt_gui) {
+ char stream_desc[100];
+ stream_to_text(stream_desc, sizeof(stream_desc), stream, 0);
+ printf("%s\n", stream_desc);
+ }
+ if (stream->bandwidth_bps == 0)
+ goto out;
+
+ seqn = 0;
+
+ block_signals();
+ set_rt_prio(90-stream->ac);
+
+ while (!exit_flag) {
+ wait_for_next_send(stream, &timer);
+
+/* buff.msg.seqn = seqn++; */
+/* buff.msg.tos = ac_to_tos[stream->ac]; */
+ buff.msg.stream = stream-streams;
+
+ clock_gettime(CLOCK_REALTIME,&ts);
+ buff.msg.send_timestamp = ts.tv_sec*1000000000LL + ts.tv_nsec;
+
+ ret = send_packet(stream, &buff);
+ if (ret < 0) {
+ stopper();
+ goto out;
+ }
+
+ pthread_mutex_lock(&stream->mutex);
+ stream->sent++;
+ if (ret > 0)
+ stream->really_sent++;
+ pthread_mutex_unlock(&stream->mutex);
+
+#ifdef DEBUG
+ printf("%d", stream->ac);
+ fflush(stdout);
+#endif
+
+ }
+out:
+ sem_post(&sem_thread_finished);
+ return NULL;
+}
+
+#ifdef WITH_FWP
+static int negotiate_contract_for_stream_fwp(struct stream *stream)
+{
+ frsh_contract_t contract;
+ int ret;
+ frsh_rel_time_t budget, period, deadline;
+
+ /* Contract for client->server stream */
+ frsh_contract_init(&contract);
+ frsh_contract_set_resource_and_label(&contract, FRSH_RT_NETWORK, FRSH_NETPF_FWP, NULL);
+ frsh_network_bytes_to_budget(FRSH_NETPF_FWP, stream->packet_size, &budget);
+ period = frsh_usec_to_rel_time(stream->period_usec);
+ frsh_contract_set_basic_params(&contract, &budget, &period, FRSH_WT_BOUNDED, FRSH_CT_REGULAR);
+ deadline = frsh_usec_to_rel_time(3*stream->period_usec);
+ frsh_contract_set_timing_reqs(&contract, false, &deadline);
+
+ ret = frsh_contract_negotiate(&contract, &stream->vres);
+ frsh_contract_destroy(&contract);
+ if (ret != 0) {
+ stream->vres = NULL;
+ fprintf(stderr, "Send contract was not accepted\n");
+ return ret;
+ }
+
+ /* Contract for server->client stream */
+ /* TODO: Use group negotiation for these two contracts */
+ frsh_contract_init(&contract);
+ frsh_contract_set_resource_and_label(&contract, FRSH_RT_NETWORK, FRSH_NETPF_FWP, NULL);
+ frsh_network_bytes_to_budget(FRSH_NETPF_FWP, stream->packet_size, &budget);
+ period = frsh_usec_to_rel_time(stream->period_usec);
+ frsh_contract_set_basic_params(&contract, &budget, &period, FRSH_WT_BOUNDED, FRSH_CT_DUMMY);
+ deadline = frsh_usec_to_rel_time(3*stream->period_usec);
+ frsh_contract_set_timing_reqs(&contract, false, &deadline);
+
+ ret = frsh_contract_negotiate(&contract, &stream->vres_rcv);
+ frsh_contract_destroy(&contract);
+ if (ret != 0) {
+ fprintf(stderr, "Receive contract was not accepted\n");
+ return ret;
+ }
+
+ /* We don't use the vres at server, since the server doesn't
+ * know the parameters. Instread, server uses plain
+ * sockets. */
+
+ return ret;
+}
+#endif
+
+#ifdef WITH_FWP
+static void create_stream_endpoint_fwp(struct stream *stream)
+{
+/* fwp_endpoint_attr_t attr; */
+ int ret;
+ struct hostent* ph;
+ frsh_contract_t c;
+ fres_block_fwp_sched *fwp_sched;
+
+ frsh_vres_get_contract(stream->vres, &c);
+ fwp_sched = fres_contract_get_fwp_sched(c);
+
+ stream->ac = fwp_sched->ac_id;
+
+/* fwp_endpoint_attr_init(&attr); */
+/* fwp_endpoint_attr_setreliability(&attr, FWP_EPOINT_BESTEFFORT); */
+
+ ph = gethostbyname(server_addr);
+ if (ph && ph->h_addr_list[0]) {
+ struct in_addr *a = (struct in_addr *)(ph->h_addr_list[0]);
+ frsh_send_endpoint_protocol_info_t spi = { NULL, 0 };
+ frsh_receive_endpoint_protocol_info_t rpi = { NULL, 0 };
+ frsh_endpoint_queueing_info_t qi = { .queue_size=0, .queue_policy=FRSH_QRP_OLDEST };
+ ret = frsh_send_endpoint_create(FRSH_NETPF_FWP, a->s_addr, BASE_PORT + stream->ac,
+ spi, &stream->endpoint);
+ if (ret < 0) error(1, errno, "frsh_send_endpoint_create()");
+
+ ret = frsh_send_endpoint_bind(stream->vres, stream->endpoint);
+ if (ret != 0) error(1, errno, "frsh_send_endpoint_bind");
+
+ ret = frsh_receive_endpoint_create(FRSH_NETPF_FWP, 0, qi, rpi,
+ &stream->resp_endpoint);
+ if (ret != 0) error(1, errno, "fwp_receive_endpoint_create");
+
+ unsigned int port;
+ frsh_receive_endpoint_get_params(stream->resp_endpoint, NULL, &port, NULL, NULL);
+ stream->resp_port = port;
+
+ ret = pthread_create(&stream->receiver.thread, NULL, receiver, (void*)stream);
+ if (ret) error(1, ret, "Error while creating receiver");
+
+ stream->receiver.valid = true;
+ }
+ else {
+ error(1, errno, "gethostbyname(%s)", server_addr);
+ }
+
+}
+#else
+static void create_stream_endpoint_native(struct stream *stream)
+{
+ struct hostent* ph;
+
+ memset(&stream->rem_addr,0, sizeof(stream->rem_addr));
+
+ stream->rem_addr.sin_family = AF_INET;
+ ph = gethostbyname(server_addr);
+ if (ph)
+ stream->rem_addr.sin_addr = *((struct in_addr *)ph->h_addr);
+ else {
+ error(1, errno, "gethostbyname(%s)", server_addr);
+ }
+ stream->rem_addr.sin_port = htons(BASE_PORT + stream->ac);
+}
+#endif
+
+static inline void
+calc_stream_params(struct stream *stream)
+{
+ int packet_size;
+ unsigned period_usec;
+ int bandwidth;
+ int ret;
+
+ /* If some parameters are not set explicitely, use default values. */
+ if (stream->bandwidth_bps < 0) stream->bandwidth_bps = opt_def_bandwidth * Kbit;
+ if (stream->packet_size < 0) stream->packet_size = opt_packet_size;
+ if (stream->period_usec < 0) stream->period_usec = opt_def_period_msec * MSEC_TO_USEC;
+
+ bandwidth = stream->bandwidth_bps;
+
+ /* Avoid arithmetic exception. Server thread will exit if
+ stream->bandwidth_bps == 0. */
+ if (bandwidth == 0) bandwidth = 1;
+
+ if (stream->packet_size) {
+ packet_size = stream->packet_size;
+ period_usec = SEC_TO_USEC*packet_size*8/bandwidth;
+ if (period_usec == 0) period_usec = 1;
+ } else if (stream->period_usec) {
+ period_usec = stream->period_usec;
+ packet_size = (long long)bandwidth/8 * period_usec/SEC_TO_USEC;
+ } else {
+ char buf[200];
+ stream_to_text(buf, sizeof(buf), stream, 0);
+ error(1, 0, "Neither packet size nor period was specified for a stream %s", buf);
+ }
+
+ if (packet_size < sizeof(struct msg_t)) {
+ error(1, 0, "Packet size too small (min %zd)", sizeof(struct msg_t));
+ }
+
+ stream->packet_size = packet_size;
+ stream->period_usec = period_usec;
+ stream->jitter = opt_jitter;
+
+ ret = negotiate_contract_for_stream(stream);
+ if (ret == 0) {
+ create_stream_endpoint(stream);
+ } else {
+ char buf[200];
+ stream_to_text(buf, sizeof(buf), stream, 0);
+ fprintf(stderr, "Contract hasn't been accepted:\n%s\n", buf);
+ stream->bandwidth_bps = 0;
+ some_contract_not_accepted = true;
+ }
+}
+
+/**
+ * Parse -b parameter.
+ *
+ * @param params String to parse
+ *
+ * @return NULL in case of success, pointer to a problematic character
+ * on error.
+ */
+char* parse_bandwidths(char *params)
+{
+ struct stream *sp = &streams[nr_streams];
+
+ while (*params && nr_streams < MAX_STREAMS) {
+ char *ac_ids[AC_NUM] = { [AC_VO]="VO", [AC_VI]="VI", [AC_BE]="BE", [AC_BK]="BK" };
+ int i;
+ char *next_char;
+
+ if (strlen(params) < 2)
+ return params;
+ for (i=0; i<AC_NUM; i++) {
+ if (strncmp(params, ac_ids[i], 2) == 0) {
+ sp->ac = i;
+ params+=strlen(ac_ids[i]);
+ break;
+ }
+ }
+ if (i==AC_NUM)
+ return params;
+
+ long bw;
+ if (*params == ':') {
+ params++;
+
+ bw = strtol(params, &next_char, 10);
+ if (next_char == params)
+ return params;
+ params = next_char;
+ } else
+ bw = -1;
+
+ sp->bandwidth_bps = bw*Kbit;
+
+ long period = 0;
+ long packet_size = 0;
+ if (*params == '@') {
+ params++;
+ period = strtol(params, &next_char, 10);
+ if (period == 0)
+ return params;
+ params = next_char;
+ }
+ else {
+ if (*params == '/') {
+ params++;
+ packet_size = strtol(params, &next_char, 10);
+ if (packet_size == 0)
+ return params;
+ params = next_char;
+ } else {
+ packet_size = -1;
+ period = -1;
+ }
+ }
+ sp->period_usec = period*MSEC_TO_USEC;
+ sp->packet_size = packet_size;
+
+
+
+ if (*params != '\0' && *params != ',')
+ return params;
+ nr_streams++;
+ sp++;
+ if (*params == ',')
+ params++;
+ }
+ return NULL;
+}
+
+#ifdef WITH_FWP
+void wait_for_all_threads_to_finish_fwp(void)
+{
+ int i;
+ /* wait for all threads to finish */
+ for (i=0; i < 2*nr_streams; i++) {
+ sem_wait(&sem_thread_finished);
+ }
+}
+#else
+void wait_for_all_threads_to_finish_native(void)
+{
+ int i;
+ /* Wait for all threads to finish */
+ for (i=0; i < nr_streams + AC_NUM; i++) {
+ sem_wait(&sem_thread_finished);
+ }
+}
+#endif
+
+WINDOW *logwin;
+
+#if 0
+struct log_params {
+ ul_log_domain_t *domain;
+ int level;
+ const char *format;
+ va_list ap;
+};
+
+
+int locked_log(WINDOW *logwin, void *arg)
+{
+ struct log_params *p = arg;
+ if(!(p->level&UL_LOGL_CONT)) {
+ p->level&=UL_LOGL_MASK;
+ if(p->level)
+ wprintw(logwin,"<%d>", p->level);
+ if(p->domain && p->domain->name)
+ wprintw(logwin,"%s: ",p->domain->name);
+ }
+ vwprintw(logwin, p->format, p->ap);
+ wnoutrefresh(logwin);
+ return 0;
+}
+
+void
+wclient_log_fnc(ul_log_domain_t *domain, int level,
+ const char *format, va_list ap)
+{
+ struct log_params p = {
+ .domain = domain,
+ .level = level,
+ .format = format,
+ };
+ va_copy(p.ap, ap);
+ va_end(ap);
+
+ use_window(logwin, locked_log, (void*)&p);
+}
+#endif
+
+
+void init_gui()
+{
+ if (opt_gui) {
+ initscr();
+ cbreak();
+ noecho();
+/* nonl(); */
+/* intrflush(stdscr, FALSE); */
+/* keypad(stdscr, TRUE); */
+
+ logwin = newwin(0, 0, LINES/2, 0);
+ if (logwin) {
+ scrollok(logwin, TRUE);
+/* ul_log_redir(wclient_log_fnc, 0); */
+ }
+ }
+}
+
+void end_gui()
+{
+ if (opt_gui) {
+ endwin();
+ if (logwin) {
+/* ul_log_redir(NULL, 0); */
+ }
+ }
+}
+
+
+#define addfield(title, format, ...) \
+ move(y, x); \
+ x+=strlen(title)+1; \
+ if (i == 0) addstr(title); \
+ else { \
+ snprintf(str, sizeof(str), format, __VA_ARGS__); \
+ addstr(str); \
+ }
+
+void print_status_gui(int seconds)
+{
+ int i;
+ char str[200], s1[20];
+ int x = 0, y;
+ struct stream *s = NULL;
+
+ for (i = 0; i <= nr_streams; i++) {
+ if (i>0) s = &streams[i-1];
+ y=i;
+ x=0;
+ addfield("Stream", "%d", i);
+ addfield("Bandwidth", "%s", bandwidth_to_text(s1, s->bandwidth_bps));
+ addfield("Packet size", "%d bytes", s->packet_size);
+ addfield("Period ", "%s", usec_to_text(s1, s->period_usec));
+ addfield("AC ", "%s", ac_to_text[s->ac]);
+ addfield("Worst-case delay", "%s", usec_to_text(s1, s->wc_delay));
+ addfield("Received responses", "%lld", s->received);
+ }
+ wnoutrefresh(stdscr);
+ doupdate();
+}
+
+void print_status_nogui(int seconds)
+{
+ int ac;
+ fprintf(stderr, "\r%3ds", seconds);
+ for (ac = 0; ac < AC_NUM; ac++) {
+ int delta = receivers[ac].received - receivers[ac].last_received;
+ receivers[ac].last_received = receivers[ac].received;
+ fprintf(stderr, " %s %5d %4d/s", ac_to_text[ac], receivers[ac].received, delta);
+ }
+ fflush(stderr);
+}
+
+#ifdef WITH_FWP
+int print_log_domain(ul_log_domain_t *domain, void *context)
+{
+ printf("%s = %d\n", domain->name, domain->level);
+ return 0;
+}
+#endif
+int main(int argc, char *argv[])
+{
+ int i, rc, frames, seconds;
+ pthread_attr_t attr;
+ pthread_t thread;
+ char opt;
+
+
+ while ((opt = getopt(argc, argv, "B:b:C:c:Gg:I:j:l:o:qQ:s:T:")) != -1) {
+ switch (opt) {
+ case 'B':
+ opt_def_bandwidth = atoi(optarg);
+ break;
+ case 'b': {
+ char *errpos;
+ errpos = parse_bandwidths(optarg);
+ if (errpos != NULL) {
+ if (*errpos == '\0')
+ error(1, 0, "Bandwidth parse error - string to short");
+ else
+ error(1, 0, "Bandwidth parse error at '%s'", errpos);
+ }
+ break;
+ }
+ case 'C':
+ opt_comment = optarg;
+ break;
+ case 'c':
+ opt_count_sec = atoi(optarg);
+ break;
+ case 'G':
+ opt_gui = true;
+ break;
+ case 'g':
+ opt_granularity_usec = atoi(optarg);
+ if (opt_granularity_usec < MIN_GRANULARITY) {
+ error(1, 0, "Granulatiry too small (min %d)", MIN_GRANULARITY);
+ }
+ break;
+ case 'I':
+ opt_interface = optarg;
+ break;
+ case 'j':
+ opt_jitter = atoi(optarg);
+ break;
+#ifdef WITH_FWP
+ case 'l':
+ if (*optarg == '?') {
+ ul_logreg_for_each_domain(print_log_domain, NULL);
+ exit(0);
+ }
+ {
+ int ret;
+ ret = ul_log_domain_arg2levels(optarg);
+ if (ret)
+ error(1, EINVAL, "Error parsing -l argument at char %d\n", ret);
+ }
+ break;
+#endif
+ case 'o':
+ opt_output = optarg;
+ break;
+ case 'Q':
+ opt_send_buf_size = atoi(optarg);
+ break;
+ case 'q':
+ opt_wait_for_queue_is_full = true;
+ break;
+ case 's':
+ opt_packet_size = atoi(optarg);
+ break;
+ case 'T':
+ opt_def_period_msec = atoi(optarg);
+ break;
+ default:
+ fprintf(stderr, "Usage: %s [ options ] server_addr\n\n", argv[0]);
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, " -B default bandwidth for -b option [kbit]\n");
+ fprintf(stderr, " -b bandwidth of streams (VO|VI|BE|BK)[:<kbit>][@<msec> or /<bytes>][,...]\n");
+ fprintf(stderr, " -C comment (added to header)\n");
+ fprintf(stderr, " -c count (number of seconds to run)\n");
+ fprintf(stderr, " -g histogram granularity [usec]\n");
+ fprintf(stderr, " -G show status in textual GUI\n");
+ fprintf(stderr, " -I <interface> send packets from this interface\n");
+#ifdef WITH_FWP
+ fprintf(stderr, " -l <loglevel> uLUt logging levels\n");
+#endif
+ fprintf(stderr, " -j send jitter (0-100) [%%]\n");
+ fprintf(stderr, " -o output filename (.dat will be appended)\n");
+ fprintf(stderr, " -q gather statistics only after some queue becomes full\n");
+ fprintf(stderr, " -Q <bytes> set size for socket send buffers\n");
+ fprintf(stderr, " -s size of data payload in packets [bytes] (default: %d)\n", opt_packet_size);
+ fprintf(stderr, " -T default period for -b option [msec]\n");
+ exit(1);
+ }
+ }
+ if (opt_packet_size && opt_def_period_msec) {
+ error(1, 0, "Error: Nonzero -T and -s can't be used together!");
+ }
+
+ if (optind < argc) {
+ server_addr = argv[optind];
+ } else {
+ error(1, 0, "Expected server address argument");
+ }
+
+ if (nr_streams == 0)
+ parse_bandwidths("BE");
+
+ pthread_attr_init(&attr);
+
+ snprintf(logfname, sizeof(logfname), "%s.dat", opt_output);
+
+ if ((logfd = fopen(logfname,"w+")) == NULL) {
+ error(1, errno ,"Can not open %s", logfname);
+ }
+ if (signal(SIGTERM, stopper) == SIG_ERR) {
+ error(1, errno, "Error in signal registration");
+ }
+
+ if (signal(SIGINT, stopper) == SIG_ERR) {
+ error(1, errno, "Signal handler registration error");
+ }
+
+ struct sigaction sa;
+ sa.sa_handler = empty_handler;
+ sa.sa_flags = 0; /* don't restart syscalls */
+
+ if (sigaction(SIGUSR1, &sa, NULL) < 0) {
+ error(1, errno, "sigaction error");
+ }
+
+ sem_init(&sem_thread_finished, 0, 0);
+
+ reset_statistics();
+
+#ifdef WITH_FWP
+ //ul_log_domain_arg2levels("6");
+ rc = frsh_init();
+ if (rc != 0) {
+ error(1, errno, "FWP initialization failed");
+ }
+#else
+ intptr_t ac;
+ /* create four receivers each per AC */
+ for (ac = AC_NUM - 1; ac >= 0; ac--) {
+ ac_sockfd[ac] = create_ac_socket(ac);
+ if (ac_sockfd[ac] < 0) {
+ return 1;
+ }
+ rc = pthread_create(&receivers[ac].thread, &attr, receiver, (void*) ac);
+ if (rc) {
+ error(1, rc, "Error while creating receiver");
+ }
+ receivers[ac].valid = true;
+ }
+#endif
+
+
+ if (opt_interface) {
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, opt_interface, IFNAMSIZ-1);
+ if (ioctl(ac_sockfd[AC_VO], SIOCGIFINDEX, &ifr) < 0) {
+ error(1, 0, "unknown iface %s", opt_interface);
+ }
+ cmsg.ipi.ipi_ifindex = ifr.ifr_ifindex;
+ cmsg_len = sizeof(cmsg);
+ }
+ /* create sendpoints */
+ for (i = 0; i < nr_streams; i++) {
+ struct stream *s = &streams[i];
+ pthread_mutex_init(&s->mutex, NULL);
+ calc_stream_params(s);
+ rc = pthread_create(&thread, &attr, sender, (void*) s);
+ if (rc) error(1, rc, "Error while creating sender");
+ }
+
+ if (some_contract_not_accepted) {
+ stopper();
+ } else {
+ init_gui();
+
+ seconds = 1;
+ frames=0;
+ while (!exit_flag) {
+ if (opt_gui) {
+ usleep(40000);
+ frames++;
+ if (frames>=25) {
+ seconds++;
+ frames = 0;
+ }
+ print_status_gui(seconds);
+ } else {
+ sleep(1);
+ seconds++;
+ print_status_nogui(seconds);
+ }
+
+ if (seconds == opt_count_sec)
+ stopper();
+ }
+ }
+
+ end_gui();
+
+ fprintf(stderr, "\nWaiting for threads to finish\n");
+ wait_for_all_threads_to_finish();
+
+#ifdef WITH_FWP
+ for (i=0; i < nr_streams; i++) {
+ if (streams[i].vres)
+ frsh_contract_cancel(streams[i].vres);
+ if (streams[i].vres_rcv)
+ frsh_contract_cancel(streams[i].vres_rcv);
+ }
+#endif
+
+ struct timespec ts;
+ uint64_t end_timestamp, measure_length;
+ clock_gettime(CLOCK_REALTIME,&ts);
+ end_timestamp = ts.tv_sec*1000000000LL+ts.tv_nsec;
+ measure_length = end_timestamp - reset_timestamp;
+
+ save_results(argc, argv, measure_length/1000);
+
+ return 0;
+}
--- /dev/null
+#include <stdlib.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <signal.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <string.h>
+#include <pthread.h>
+#include "common.h"
+#include <stdbool.h>
+
+bool opt_same_interface = false;
+
+static int ac_sockfd[AC_NUM];
+
+struct receiver {
+ unsigned received, last_received;
+} receivers[AC_NUM];
+
+
+void stopper()
+{
+ int i;
+
+ for (i = 0; i < AC_NUM; i++)
+ close(ac_sockfd[i]);
+
+ exit(0);
+}
+
+int create_ac_socket(unsigned int ac)
+{
+ struct sockaddr_in my_addr;
+ int sockfd;
+ unsigned int yes=1, tos;
+
+
+ if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ perror("Socket nelze otevrit");
+ return -1;
+ }
+
+ if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
+ perror("Chyba v nastaveni soketu");
+ return -1;
+ }
+
+ if (opt_same_interface) {
+ int receive = 1;
+ if (setsockopt(sockfd, SOL_IP, IP_PKTINFO, &receive, sizeof(receive)) == -1) {
+ perror("setsockopt: IP_PKTINFO");
+ exit(1);
+ }
+ }
+
+
+ // bzero(&my_addr, sizeof(my_addr));
+ memset(&my_addr,0, sizeof(my_addr));
+ my_addr.sin_family = AF_INET;
+ my_addr.sin_addr.s_addr = INADDR_ANY;
+ my_addr.sin_port = htons(BASE_PORT + ac);
+
+ if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr)) == -1) {
+ perror("Chyba v bind");
+ close(sockfd);
+ return -1;
+ }
+
+ //tos = ((AC_NUM - ac) *2 - 1)*32;
+ tos = ac_to_tos[ac];
+ if (setsockopt(sockfd, SOL_IP, IP_TOS, &tos, sizeof(tos))) {
+ perror("Unable to set TOS");
+ close(sockfd);
+ return -1;
+ }
+
+ return sockfd;
+}
+
+void* qhandler(void* queue)
+{
+ union msg_buff buff;
+ struct sockaddr_in rem_addr;
+ int mlen;
+ unsigned int rem_addr_length;
+ intptr_t ac;
+ char cbufrec[512], cbufsend[512];
+ struct iovec iov;
+ struct msghdr msg;
+ struct in_pktinfo *ipi = NULL;
+ struct timespec ts;
+
+ ac = (intptr_t) queue;
+ rem_addr_length=sizeof(rem_addr);
+
+ block_signals();
+ set_rt_prio(90-ac);
+
+ while (1) {
+ struct cmsghdr *cmsg;
+
+ iov.iov_base = &buff;
+ iov.iov_len = sizeof(buff);
+ msg.msg_name = (void*)&rem_addr;
+ msg.msg_namelen = sizeof(rem_addr);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_flags = 0;
+ msg.msg_control = cbufrec;
+ msg.msg_controllen = sizeof(cbufrec);
+
+ while ((mlen = recvmsg(ac_sockfd[ac], &msg, 0)) < 0) {
+ if (errno == EINTR) continue;
+ perror("recvmsg");
+ return NULL;
+ }
+ clock_gettime(CLOCK_REALTIME, &ts);
+ buff.msg.sendback_timestamp = ts.tv_sec*1000000000 + ts.tv_nsec;
+
+
+ if (opt_same_interface) {
+ /* determine receiving interface */
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_level == SOL_IP) {
+ if (cmsg->cmsg_type == IP_PKTINFO) {
+/* char spec_dst[20], addr[20]; */
+ ipi = (struct in_pktinfo*)CMSG_DATA(cmsg);
+ if (cmsg->cmsg_len <= sizeof(cbufsend)) {
+ struct in_pktinfo *ipi2;
+ msg.msg_control = cbufsend;
+ msg.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = SOL_IP;
+ cmsg->cmsg_type = IP_PKTINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+ /* Initialize the payload: */
+ ipi2 = (struct in_pktinfo*)CMSG_DATA(cmsg);
+ memset(ipi2, 0, sizeof(*ipi2));
+ ipi2->ipi_ifindex = ipi->ipi_ifindex;
+
+ } else {
+ fprintf(stderr, "cbufsend too small\n");
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ }
+/* strncpy(spec_dst, inet_ntoa(ipi->ipi_spec_dst), sizeof(spec_dst)-1); */
+/* strncpy(addr, inet_ntoa(ipi->ipi_addr), sizeof(addr)-1); */
+/* printf("pktinfo if=%d %s %s\n", ipi->ipi_ifindex, spec_dst, addr); */
+ }
+ }
+ }
+ } else {
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ }
+#ifdef DEBUG
+ printf("%d",ac);
+ fflush(stdout);
+#endif
+ receivers[ac].received++;
+ msg.msg_iov->iov_len = mlen;
+#ifdef WITH_FWP
+ /* resp_port is already stored in network order */
+ rem_addr.sin_port = buff.msg.resp_port;
+#endif
+ while (sendmsg(ac_sockfd[ac], &msg, 0) < 0) {
+ if (errno == EINTR) continue;
+ perror("sendmsg");
+ return NULL;
+ }
+ }
+}
+
+
+int main(int argc, char *argv[])
+{
+ int rc;
+ intptr_t ac;
+ pthread_attr_t attr;
+ pthread_t thread;
+
+ char opt;
+
+
+ while ((opt = getopt(argc, argv, "I")) != -1) {
+ switch (opt) {
+ case 'I':
+ opt_same_interface = true;
+ break;
+ default:
+ fprintf(stderr, "Usage: %s [ options ]\n\n", argv[0]);
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, " -I send back through the same interface (bypass routing tables)\n");
+ exit(1);
+ }
+ }
+ pthread_attr_init(&attr);
+
+ if (signal(SIGTERM, stopper) == SIG_ERR) {
+ perror("Signal handler registration error");
+ exit(1);
+ }
+
+ if (signal(SIGINT, stopper) == SIG_ERR) {
+ perror("Signal handler registration error");
+ exit(1);
+ }
+
+ for (ac = 0; ac < AC_NUM; ac++) {
+ ac_sockfd[ac] = create_ac_socket(ac);
+ rc = pthread_create(&thread, &attr, qhandler, (void*) ac);
+
+ }
+
+ while (1) {
+ printf("\r");
+ for (ac = 0; ac < AC_NUM; ac++) {
+ int delta = receivers[ac].received - receivers[ac].last_received;
+ receivers[ac].last_received = receivers[ac].received;
+ fprintf(stderr, "%s %5d %4d/s ", ac_to_text[ac], receivers[ac].received, delta);
+ }
+ fflush(stdout);
+ sleep(1);
+ }
+ printf("\n");
+
+ return 0;
+
+}
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+#!/bin/sh
+
+ARRAY_NAME=ul_log_domains_array
+
+DIRS=""
+
+while [ $# -gt 0 ] ; do
+ case "x${1}x" in
+ "x--helpx" | "x-hx" )
+ echo -e Usage: `basename ${0}`" [options] <srcdir> .."
+ echo -e " -h --help help"
+ echo -e " -a --array identifier of log domain array variable"
+ exit 0
+ ;;
+ "x--arrayx" | "x-ax" )
+ shift 1
+ ARRAY_NAME="${1}"
+ ;;
+ "x--"* )
+ echo "Unknown option"
+ exit 2
+ ;;
+ * )
+ DIRS="$DIRS ${1}"
+ ;;
+ esac
+ shift 1
+done
+
+DOMAINS=$( for d in $DIRS ; do find -L $d '(' -name '*.c' -o -name '*.cc' ')' -exec grep UL_LOG_CUST '{}' ';' | \
+ sed -n -e 's/^.*UL_LOG_CUST(\([^)]*\)).*$/\1/p' ; done | sort -u )
+
+#echo $DOMAINS
+
+#echo -e "#define UL_LOGL_DEF UL_LOGL_DEB\n"
+
+echo "/*"
+echo " * This is generated file, do not edit it directly."
+echo " * Take it from standard output of \"ul_log_domains\""
+echo " * script called in the top level project directory"
+echo " */"
+
+for i in $DOMAINS ; do
+ echo "ul_log_domain_t $i = {UL_LOGL_DEF, \"$(echo -n $i | sed -n -e 's/ulogd_\(.*\)/\1/pg' )\"};"
+done
+
+echo
+echo "ul_log_domain_t *$ARRAY_NAME[] = {"
+
+for i in $DOMAINS ; do
+ echo " &$i,"
+done
+
+echo "};"
--- /dev/null
+#!/bin/sh
+
+# Script to track FRESCOR SVN repositories. We do this in order not to
+# diverge to much from the original code so that it can be easily
+# joined in future if it will be necessary.
+
+set -e
+
+update() {
+ local dir=$1
+ local svnrepo=$2
+ cd $dir
+ echo "Updating $dir"
+ if ! git config --get svn-remote.svn.url > /dev/null; then
+ git svn init $svnrepo
+ fi
+
+ git svn fetch
+ local gitbranch=`git show-ref --verify --hash refs/heads/frescor-svn`
+ local svnbranch=`git show-ref --verify --hash refs/remotes/git-svn`
+
+ if [ -z "$gitbranch" ]; then
+ echo " Creating frescor-svn branch"
+ git branch frescor-svn git-svn
+ else
+ if [ "$gitbranch" != "$svnbranch" ]; then
+ echo " Merging SVN to branch frescor-svn"
+ git merge git-svn
+ git checkout master
+ else
+ echo " Already up-to-date"
+ fi
+ fi
+ cd ..
+}
+
+update frsh-include http://www.frescor.org/private/svn/frescor/frsh/trunk/include
+update fosa http://www.frescor.org/private/svn/frescor/fosa/trunk
+update fna http://www.frescor.org/private/svn/frescor/fna/trunk
--- /dev/null
+#!/bin/sh
+
+find -type d -name .git -print \
+ -execdir git checkout master \; \
+ -execdir git pull \;
--- /dev/null
+#
+# Include this file in your shell script by using:
+# #!/bin/sh
+# . ./wvtest.sh
+#
+
+# we don't quote $TEXT in case it contains newlines; newlines
+# aren't allowed in test output. However, we set -f so that
+# at least shell glob characters aren't processed.
+_wvtextclean()
+{
+ ( set -f; echo $* )
+}
+
+
+if [ -n "$BASH_VERSION" ]; then
+ _wvfind_caller()
+ {
+ LVL=$1
+ WVCALLER_FILE=${BASH_SOURCE[2]}
+ WVCALLER_LINE=${BASH_LINENO[1]}
+ }
+else
+ _wvfind_caller()
+ {
+ LVL=$1
+ WVCALLER_FILE="unknown"
+ WVCALLER_LINE=0
+ }
+fi
+
+
+_wvcheck()
+{
+ CODE="$1"
+ TEXT=$(_wvtextclean "$2")
+ OK=ok
+ if [ "$CODE" -ne 0 ]; then
+ OK=FAILED
+ fi
+ echo "! $WVCALLER_FILE:$WVCALLER_LINE $TEXT $OK" >&2
+ if [ "$CODE" -ne 0 ]; then
+ exit $CODE
+ else
+ return 0
+ fi
+}
+
+
+WVPASS()
+{
+ TEXT="$*"
+
+ _wvfind_caller
+ if "$@"; then
+ _wvcheck 0 "$TEXT"
+ return 0
+ else
+ _wvcheck 1 "$TEXT"
+ # NOTREACHED
+ return 1
+ fi
+}
+
+
+WVFAIL()
+{
+ TEXT="$*"
+
+ _wvfind_caller
+ if "$@"; then
+ _wvcheck 1 "NOT($TEXT)"
+ # NOTREACHED
+ return 1
+ else
+ _wvcheck 0 "NOT($TEXT)"
+ return 0
+ fi
+}
+
+
+_wvgetrv()
+{
+ ( "$@" >&2 )
+ echo -n $?
+}
+
+
+WVPASSEQ()
+{
+ _wvfind_caller
+ _wvcheck $(_wvgetrv [ "$#" -eq 2 ]) "exactly 2 arguments"
+ echo "Comparing:" >&2
+ echo "$1" >&2
+ echo "--" >&2
+ echo "$2" >&2
+ _wvcheck $(_wvgetrv [ "$1" = "$2" ]) "'$1' = '$2'"
+}
+
+
+WVPASSNE()
+{
+ _wvfind_caller
+ _wvcheck $(_wvgetrv [ "$#" -eq 2 ]) "exactly 2 arguments"
+ echo "Comparing:" >&2
+ echo "$1" >&2
+ echo "--" >&2
+ echo "$2" >&2
+ _wvcheck $(_wvgetrv [ "$1" != "$2" ]) "'$1' != '$2'"
+}
+
+
+WVPASSRC()
+{
+ RC=$?
+ _wvfind_caller
+ _wvcheck $(_wvgetrv [ $RC -eq 0 ]) "return code($RC) == 0"
+}
+
+
+WVFAILRC()
+{
+ RC=$?
+ _wvfind_caller
+ _wvcheck $(_wvgetrv [ $RC -ne 0 ]) "return code($RC) != 0"
+}
+
+
+WVSTART()
+{
+ echo >&2
+ _wvfind_caller
+ echo "Testing \"$*\" in $WVCALLER_FILE:" >&2
+}
+
+
+root=$(
+old_pwd=""
+while [ ! -e Makefile.rules ]; do
+ if [ "$old_pwd" = `pwd` ]; then
+ echo "Makefile.rules has not been found in this or parent directory" >&2; exit 1;
+ else
+ old_pwd=`pwd`;
+ cd -L .. 2>/dev/null;
+ fi;
+done;
+pwd
+)
+
+if [ "$root" ]; then
+ PATH="$root/_compiled/bin:$root/_compiled/bin-tests:$PATH"
+else
+ exit 1
+fi