]> rtime.felk.cvut.cz Git - frescor/frsh.git/commitdiff
Shared Objects.
authorDario Faggioli <faggioli@gandalf.sssup.it>
Wed, 25 Feb 2009 08:42:59 +0000 (09:42 +0100)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Sun, 1 Mar 2009 18:53:33 +0000 (19:53 +0100)
This commit introduces shared objects. The implementation is fully
resource manager independent, and thus can be used with dummy, AQuoSA,
CGroups, or whatever else.

A small uncompliance with the FRSH API semantic is present, since we
need the user not to create an external mutex that will be associated
with the shared object. Instead, we create the mutex along with the
shared object and return it to the user together with the shared object
handle.
This issue will be further analyzed to find out if it would be possible
to remove it...

Moreover, this commit does not fully implemente serialization and
deserialization for the critical sections contract block, since more
discussion is needed to address the issue. Thus, we only provide some
stubs here, just to make the framework compile and run some simple
tests.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
16 files changed:
fres/Makefile.omk
fres/contract/fres_blocks.idl
fres/contract/fres_container.c
fres/contract/fres_container.h
fres/contract/fres_contract.h
fres/contract/idl_native.h
fres/sharedobj/Makefile [new file with mode: 0644]
fres/sharedobj/Makefile.omk [new file with mode: 0644]
fres/sharedobj/fres_sharedobj.c [new file with mode: 0644]
fres/sharedobj/fres_sharedobj.h [new file with mode: 0644]
fres/sharedobj/fres_sharedobj_idl.idl [new file with mode: 0644]
fres/sharedobj/tests/Makefile [new file with mode: 0644]
fres/sharedobj/tests/Makefile.omk [new file with mode: 0644]
frsh_api/Makefile.omk
frsh_api/frsh_opaque_types.h
frsh_api/frsh_sharedobj.c

index 42d9645b375f3a2d1d43227fbfbe1f248da85924..b9e543d4d536a204d2a6fe0c522618204b6b0e43 100644 (file)
@@ -1,4 +1,4 @@
-SUBDIRS=contract synchobj cbroker resmng resalloc
+SUBDIRS=contract synchobj sharedobj cbroker resmng resalloc
 
 ifneq ($(QTDIR),)
 SUBDIRS += frm_gui
index 9d98b52c1555c125d524039ea152eeba94fd0931..bbe2384e11f7f27d58ebd9875cb78b37c711d5d4 100644 (file)
@@ -98,6 +98,31 @@ enum frsh_granularity_t {
 typedef long frsh_signal_t;
 typedef long frsh_signal_info_t;
 
+typedef struct frsh_memory_area_data {
+       long size;
+       long area;
+} frsh_memory_area_data_t;
+
+typedef struct frsh_memory_areas {
+    long size;
+    frsh_memory_area_data_t memory_areas[255];
+} frsh_memory_areas_t;
+
+typedef struct frsh_csect {
+       long op_kind;
+       long obj_handle;
+       fosa_rel_time_t wcet;
+       fosa_rel_time_t blocking;
+       long op;
+       frsh_memory_areas_t areas;
+       frsh_memory_areas_t storage;
+} frsh_csect_t;
+
+typedef struct frsh_csects_group {
+       long size;
+       frsh_csect_t csects[255];
+} frsh_csects_group_t;
+
 module fres {
        native container_ptr;
 
@@ -137,6 +162,11 @@ module fres {
 //                     frsh_signal_info_t      deadline_miss_siginfo;
                };
 
+               /// Critical sections (for shared objects)
+               struct csects {
+                       frsh_csects_group_t     sections;
+               };
+
                /// Spare capacity
                struct spare_capacity {
                        frsh_granularity_t      granularity;
index 31150e7f4426ac3b8d8b6fd67fd3be903c55b7d1..099b556567b13e3d21f319e44fbc133cf4792b58 100644 (file)
@@ -119,10 +119,19 @@ int fres_block_timing_reqs_to_string(char *dest, size_t size, enum fres_block_ty
                );
 }
 
+int fres_block_csects_to_string(char *dest, size_t size, enum fres_block_type type,
+                               const void *block_data)
+{
+       const fres_block_csects *c = 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 struct fres_block_desc desc_spare_capacity = {
        .size        = sizeof(fres_block_spare_capacity),
@@ -140,6 +149,7 @@ static const struct fres_block_desc *block_registry[FRES_NUM_BLOCKS] = {
        [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,
 };
 
 /** 
index d87f024440a85a19027678da1b27deaecf2622df..f41883c42967f43cc275d8fa87324f6bd8adc4a9 100644 (file)
@@ -82,6 +82,7 @@ enum fres_block_type {
        FRES_BLOCK_RESOURCE,
        FRES_BLOCK_BASIC,
        FRES_BLOCK_TIMING_REQS,
+       FRES_BLOCK_CSECTS,
        FRES_BLOCK_SPARE_CAPACITY,
        FRES_BLOCK_DUMMY_SCHED, /**< See resources/dummy/res_dummy_idl.idl */
        FRES_BLOCK_CLUSTER_TREE_TRAFFIC, /**< resources/cluster_tree/cluster_tree_idl.idl */
@@ -165,6 +166,7 @@ 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)
 
 int
index 3cbf41a2b83297d71144fa5336f1a2bf1501b96b..699ac1677f53bb3a4a58a41729cb6169475674bd 100644 (file)
@@ -192,6 +192,7 @@ 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)
 
 #ifdef __cplusplus
index 3c557254dd391344b2f73fd033f8424a5f70e303..7c6add1504e80b7716834a98965c5602ebaafa93 100644 (file)
@@ -99,6 +99,10 @@ fosa_rel_time_t_deserialize(FORB_CDR_Codec *codec, struct timespec *ts)
 #define _frsh_granularity_t_defined 1
 #define _frsh_signal_t_defined 1
 #define _frsh_signal_info_t_defined 1
+#define _frsh_memory_area_data_t_defined 1
+#define _frsh_memory_areas_t_defined 1
+#define _frsh_csect_t_defined 1
+#define _frsh_csects_group_t_defined 1
 
 #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)
@@ -115,4 +119,94 @@ fosa_rel_time_t_deserialize(FORB_CDR_Codec *codec, struct timespec *ts)
 #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_memory_area_data_t_serialize
+  (FORB_CDR_Codec *codec,
+   const frsh_memory_area_data_t *m)
+{
+       CORBA_long size, area;
+       size = m->size;
+       area = (CORBA_long) 0; //m->area;
+       if (!CORBA_long_serialize(codec, &size)) return CORBA_FALSE;
+       if (!CORBA_long_serialize(codec, &area)) return CORBA_FALSE;
+       return CORBA_TRUE;
+}
+
+static inline CORBA_boolean
+frsh_memory_area_data_t_deserialize
+  (FORB_CDR_Codec *codec,
+   frsh_memory_area_data_t *m)
+{
+       CORBA_long size, area;
+       if (!CORBA_long_deserialize(codec, &size)) return CORBA_FALSE;
+       if (!CORBA_long_deserialize(codec, &area)) return CORBA_FALSE;
+       m->size = size;
+       m->area = (void*) NULL; //area;
+       return CORBA_TRUE;
+}
+
+static inline CORBA_boolean
+frsh_memory_areas_t_serialize
+  (FORB_CDR_Codec *codec,
+   const frsh_memory_areas_t *a)
+{
+       CORBA_long i, size;
+       CORBA_boolean ret;
+       size = a->size;
+       if (!CORBA_long_serialize(codec, &size)) return CORBA_FALSE;
+       for (i = 0; i < FRSH_MAX_N_MEMORY_AREAS; i++) {
+               ret = frsh_memory_area_data_t_serialize(codec, &a->memory_areas[i]);
+               if (ret == CORBA_FALSE) return ret;
+       }
+       return CORBA_TRUE;
+}
+
+static inline CORBA_boolean
+frsh_memory_areas_t_deserialize
+  (FORB_CDR_Codec *codec,
+   frsh_memory_areas_t *a)
+{
+       CORBA_long i, size;
+       CORBA_boolean ret;
+       if (!CORBA_long_deserialize(codec, &size)) return CORBA_FALSE;
+       for (i = 0; i < FRSH_MAX_N_MEMORY_AREAS; i++) {
+               ret = frsh_memory_area_data_t_deserialize(codec, &a->memory_areas[i]);
+               if (ret == CORBA_FALSE) return ret;
+       }
+       a->size = size;
+       return CORBA_TRUE;
+}
+
+static inline CORBA_boolean
+frsh_csect_t_serialize
+  (FORB_CDR_Codec *codec,
+   const frsh_csect_t *c)
+{
+       return CORBA_TRUE;
+}
+
+static inline CORBA_boolean
+frsh_csect_t_deserialize
+  (FORB_CDR_Codec *codec,
+   frsh_csect_t *c)
+{
+       return CORBA_TRUE;
+}
+
+static inline CORBA_boolean
+frsh_csects_group_t_serialize
+  (FORB_CDR_Codec *codec,
+   const frsh_csects_group_t *g)
+{
+       return CORBA_TRUE;
+}
+
+static inline CORBA_boolean
+frsh_csects_group_t_deserialize
+  (FORB_CDR_Codec *codec,
+   frsh_csects_group_t *g)
+{
+       return CORBA_TRUE;
+}
+
 #endif
diff --git a/fres/sharedobj/Makefile b/fres/sharedobj/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# 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
+
diff --git a/fres/sharedobj/Makefile.omk b/fres/sharedobj/Makefile.omk
new file mode 100644 (file)
index 0000000..7491331
--- /dev/null
@@ -0,0 +1,13 @@
+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
diff --git a/fres/sharedobj/fres_sharedobj.c b/fres/sharedobj/fres_sharedobj.c
new file mode 100644 (file)
index 0000000..4eeb9b5
--- /dev/null
@@ -0,0 +1,133 @@
+/**
+ * @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 shm_fd;
+
+       snprintf(shm_path, sizeof(shm_path), "/tmp/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;
+
+       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)
+{
+       struct fres_sharedobj *s = NULL;
+       char shm_path[108];
+       int shm_fd;
+
+       snprintf(shm_path, sizeof(shm_path), "/tmp/sync.%s", s->label);
+
+       shm_fd = shm_open(shm_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;
+}
+
+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 = munmap((void*) s, sizeof(*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);
+}
+
diff --git a/fres/sharedobj/fres_sharedobj.h b/fres/sharedobj/fres_sharedobj.h
new file mode 100644 (file)
index 0000000..2a8c9e8
--- /dev/null
@@ -0,0 +1,62 @@
+/**
+ * @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_destroy(struct fres_sharedobj *sharedobj);
+
+void
+fres_sharedobj_print(char *prefix, const struct fres_sharedobj *c);
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif
+
diff --git a/fres/sharedobj/fres_sharedobj_idl.idl b/fres/sharedobj/fres_sharedobj_idl.idl
new file mode 100644 (file)
index 0000000..3cc4d66
--- /dev/null
@@ -0,0 +1,26 @@
+/**
+ * @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
+
diff --git a/fres/sharedobj/tests/Makefile b/fres/sharedobj/tests/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# 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
+
diff --git a/fres/sharedobj/tests/Makefile.omk b/fres/sharedobj/tests/Makefile.omk
new file mode 100644 (file)
index 0000000..3b0564a
--- /dev/null
@@ -0,0 +1,6 @@
+test_PROGRAMS:=$(basename $(notdir $(wildcard $(SOURCES_DIR)/*.c)))
+
+$(foreach t,$(test_PROGRAMS),\
+$(eval $(t)_SOURCES = $(t).c)\
+$(eval $(t)_LIBS = fosa m contract rt forb ulut)\
+)
index 85fa9099558ffe1f28091536382da41d27d50c8d..55273c0cc8ad57a3d674d12a03e69791ffe9ac43 100644 (file)
@@ -1,9 +1,9 @@
 SUBDIRS = tests
 
 shared_LIBRARIES = frsh
-frsh_SOURCES = frsh_contract.c frsh_vres.c frsh_synchobj.c frsh_distributed.c frsh_core.c frsh_error.c frsh_thread.c 
+frsh_SOURCES = frsh_contract.c frsh_vres.c frsh_synchobj.c frsh_distributed.c frsh_core.c frsh_error.c frsh_thread.c frsh_sharedobj.c
 include_HEADERS = frsh_opaque_types.h frsh_forb.h
-frsh_LIBS = fna fcb_client forb contract synchobj fra ulut fosa $(allocator-libs-y)
+frsh_LIBS = fna fcb_client forb contract synchobj sharedobj fra ulut fosa $(allocator-libs-y)
 
 config_include_HEADERS = frsh_resources.h
 frsh_resources_DEFINES = CONFIG_RESOURCE_DUMMY \
index 3cb1e8dbd2da58c7c0cde67dc237889c1fe13ca4..5c3ee8940b56d434169eae90e7e129667efbcfa0 100644 (file)
@@ -108,7 +108,7 @@ struct fres_vres;
 
 #define FRSH_SYNCHOBJ_HANDLE_T_OPAQUE struct fres_synchobj *
 
-typedef int FRSH_SHAREDOBJ_HANDLE_T_OPAQUE;
+#define FRSH_SHAREDOBJ_HANDLE_T_OPAQUE struct fres_sharedobj *
 
 typedef unsigned int FRSH_GROUP_ID_T_OPAQUE;
 
index 80a986870a309ef287dcdc46d0dbde22d1977c60..52b7bd88ab390673f867a3192f1f084f03665bb6 100644 (file)
@@ -6,8 +6,12 @@
  *
  *
  */
+#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> */
+#include <fres_sharedobj.h>
 
 int frsh_sharedobj_init
   (const char *obj_label,
@@ -15,11 +19,389 @@ int frsh_sharedobj_init
    frsh_sharedobj_handle_t *obj_handle,
    frsh_mutex_t *mutex)
 {
-       return FRSH_ERR_NOT_IMPLEMENTED;
+       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)
 {
-       return FRSH_ERR_NOT_IMPLEMENTED;
+       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;
+       csect->obj_handle = obj_handle;
+       csect->wcet = wcet;
+       csect->blocking = wcet;
+       csect->op = NULL;
+       csect->areas.size = 0;
+       csect->storage.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 = csect->obj_handle;
+
+       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, j;
+
+       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->storage.size = areas->size;
+       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];
+
+               csect->storage.memory_areas[i].size =
+                       areas->memory_areas[i].size;
+
+               /*
+                * TODO:
+                *  Who is going to free() these mallocs? Maybe something
+                *  like frsh_csect_destroy is needed and missing?
+                */
+               csect->storage.memory_areas[i].area =
+                       malloc(areas->memory_areas[i].size);
+               if (!csect->storage.memory_areas[i].area)
+                       goto free_err;
+       }
+
+       /* Account for protection and rollback overheads: NOT IMPLEMENTED! */
+       /* csect->blocking = fosa_rel_time_add(csect->wcet, ); */
+       csect->blocking = csect->wcet;
+
+       return 0;
+free_err:
+       for (j = i; j >= 0; j--)
+               free(csect->storage.memory_areas[j].area);
+
+       return FOSA_ENOMEM;
+}
+
+/**
+ * Type that contains the information necessary to implement
+ * time-protection in shared resources.
+ */
+typedef struct {
+  fosa_timer_id_t timer_id;
+  fosa_long_jump_context_t context;
+} frsh_sr_protection_t;
+
+int frsh_csect_invoke
+  (const frsh_csect_t *csect,
+   const void *input_arg,
+   void *output_arg)
+{
+       int i, jumped, ret = 0;
+       fosa_signal_t signal;
+       fosa_signal_info_t siginfo;
+       fosa_clock_id_t clockid;
+       frsh_sharedobj_handle_t obj_handle;
+       fosa_mutex_t *obj_mutex;
+
+       if (!csect) {
+               ret = FRSH_ERR_BAD_ARGUMENT;
+               goto out;
+       }
+
+       obj_handle = csect->obj_handle;
+
+       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++)
+                       if (!memcpy(csect->storage.memory_areas[i].area,
+                                   csect->areas.memory_areas[i].area,
+                                   csect->areas.memory_areas[i].size)) {
+                               ret = errno;
+                               goto out_disarm;
+                       }
+       }
+
+       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,
+                                   csect->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);
+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, 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;
+
+       c->sections.size = critical_sections->size;
+       for (i = 0; i < critical_sections->size; i++)
+               c->sections.csects[i] = critical_sections->csects[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.size;
+       for (i = 0; i < c->sections.size; i++)
+               critical_sections->csects[i] = c->sections.csects[i];
+
+       return 0;
 }