]> rtime.felk.cvut.cz Git - l4.git/blobdiff - l4/pkg/l4re/util/include/cap_alloc
Inital import
[l4.git] / l4 / pkg / l4re / util / include / cap_alloc
diff --git a/l4/pkg/l4re/util/include/cap_alloc b/l4/pkg/l4re/util/include/cap_alloc
new file mode 100644 (file)
index 0000000..a96f82a
--- /dev/null
@@ -0,0 +1,271 @@
+// -*- Mode: C++ -*-
+// vim:ft=cpp
+/**
+ * \file
+ * \brief  Capability allocator
+ */
+/*
+ * (c) 2008-2009 Technische Universität Dresden
+ * This file is part of TUD:OS and distributed under the terms of the
+ * GNU General Public License 2.
+ * Please see the COPYING-GPL-2 file for details.
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction.  Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * 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.
+ */
+
+#pragma once
+
+#include <l4/re/util/cap_alloc_impl.h>
+#include <l4/sys/smart_capability>
+#include <l4/sys/task>
+#include <l4/re/consts>
+
+namespace L4Re { namespace Util {
+
+/**
+ * \defgroup l4re_cap_api L4Re Capability API
+ */
+/*@{*/
+/**
+ * \brief Capability allocator.
+ *
+ * This is the instance of the capability allocator that is used
+ * by usual applications.  The actual implementation of the allocator
+ * depends on the configuration of the system.
+ *
+ * Per default we use a reference count capability allocator, that
+ * keeps a reference counter for each managed capability selector.
+ *
+ * \note This capability allocator is not thread-safe.
+ */
+extern _Cap_alloc &cap_alloc;
+
+/**
+ * \brief Helper for Auto_cap and Auto_del_cap.
+ */
+template< unsigned long Unmap_flags = L4_FP_ALL_SPACES >
+class Smart_cap_auto
+{
+public:
+  /**
+   * \brief free operation for L4::Smart_cap.
+   */
+  static void free(L4::Cap_base &c)
+  {
+    if (c.is_valid())
+      {
+        cap_alloc.free(L4::Cap<void>(c.cap()), This_task, Unmap_flags);
+        c.invalidate();
+      }
+  }
+
+  /**
+   * \brief invalidate operation for L4::Smart_cap.
+   */
+  static void invalidate(L4::Cap_base &c)
+  {
+    if (c.is_valid())
+      c.invalidate();
+  }
+
+  /**
+   * \brief copy operation for L4::Smart_cap.
+   */
+  static L4::Cap_base copy(L4::Cap_base const &src)
+  {
+    L4::Cap_base r = src;
+    invalidate(const_cast<L4::Cap_base &>(src));
+    return r;
+  }
+};
+
+
+/**
+ * \brief Helper for Ref_cap and Ref_del_cap.
+ */
+template< unsigned long Unmap_flags = L4_FP_ALL_SPACES >
+class Smart_count_cap
+{
+public:
+  /**
+   * \brief free operation for L4::Smart_cap (decrement ref count and delete
+   *        if 0).
+   */
+  static void free(L4::Cap_base &c)
+  {
+    if (c.is_valid())
+      {
+        if (cap_alloc.release(L4::Cap<void>(c.cap()), This_task, Unmap_flags))
+         c.invalidate();
+      }
+  }
+
+  /**
+   * \brief invalidate operation for L4::Smart_cap.
+   */
+  static void invalidate(L4::Cap_base &c)
+  {
+    if (c.is_valid())
+      c.invalidate();
+  }
+
+  /**
+   * \brief copy operation for L4::Smart_cap (increment ref count).
+   */
+  static L4::Cap_base copy(L4::Cap_base const &src)
+  {
+    cap_alloc.take(L4::Cap<void>(src.cap()));
+    return src;
+  }
+};
+
+
+/**
+ * \brief Automatic capability that implements automatic free and
+ *        unmap of the capability selector.
+ * \param T the type of the object that is referred by the capability.
+ *
+ * This kind of automatic capability is useful for capabilities with
+ * that shall have a lifetime that is strictly coupled to one C++ scope.
+ *
+ * Usage:
+ * \code
+ * {
+ *   L4Re::Util::Auto_cap<L4Re::Dataspace>::Cap
+ *     ds_cap(L4Re::Util::cap_alloc.alloc<L4Re::Datasapce>));
+ *
+ *   // use the dataspace cap
+ *   L4Re::chksys(mem_alloc->alloc(4096, ds_cap.get()));
+ *
+ *   ...
+ *
+ *   // At the end of the scope ds_cap is unmapped and the capability selector
+ *   // is freed.
+ * }
+ * \endcode
+ */
+template< typename T >
+struct Auto_cap
+{
+  typedef L4::Smart_cap<T, Smart_cap_auto< L4_FP_ALL_SPACES> > Cap;
+};
+
+/**
+ * \brief Automatic capability that implements automatic free and
+ *        unmap+delete of the capability selector.
+ * \param T the type of the object that is referred by the capability.
+ *
+ * This kind of automatic capability is useful for capabilities with
+ * that shall have a lifetime that is strictly coupled to one C++ scope.
+ * The main difference to Auto_cap is that the unmap is done with the
+ * deletion flag enabled and this leads to the deletion of the object
+ * if the current task holds appropriate deletion rights.
+ *
+ * Usage:
+ * \code
+ * {
+ *   L4Re::Util::Auto_del_cap<L4Re::Dataspace>::Cap
+ *     ds_cap(L4Re::Util::cap_alloc.alloc<L4Re::Datasapce>));
+ *
+ *   // use the dataspace cap
+ *   L4Re::chksys(mem_alloc->alloc(4096, ds_cap.get()));
+ *
+ *   ...
+ *
+ *   // At the end of the scope ds_cap is unmapped and the capability selector
+ *   // is freed. Because the deletion flag is set the data space shall be
+ *   // also deleted (even if there are other references to this data space).
+ * }
+ * \endcode
+ */
+template< typename T >
+struct Auto_del_cap
+{
+  typedef L4::Smart_cap<T, Smart_cap_auto<L4_FP_DELETE_OBJ> > Cap;
+};
+
+/**
+ * \brief Automatic capability that implements automatic free and
+ *        unmap of the capability selector.
+ * \param T the type of the object that is referred by the capability.
+ *
+ * This kind of automatic capability implements a counted reference to a
+ * capability selector.  The capability shall be unmapped and freed
+ * when the reference count in the allocator goes to zero.
+ *
+ * Usage:
+ * \code
+ * L4Re::Util::Ref_cap<L4Re::Dataspace>::Ca global_ds_cap;
+ *
+ * {
+ *   L4Re::Util::Ref_cap<L4Re::Dataspace>::Cap
+ *     ds_cap(L4Re::Util::cap_alloc.alloc<L4Re::Datasapce>));
+ *   // reference count for the allocated cap selector is now 1
+ * *
+ *   // use the dataspace cap
+ *   L4Re::chksys(mem_alloc->alloc(4096, ds_cap.get()));
+ *
+ *   global_ds_cap = ds_cap;
+ *   // reference count is now 2
+ *   ...
+ * }
+ * // reference count dropped to 1 (ds_cap is no longer exiting).
+ * \endcode
+ */
+template< typename T >
+struct Ref_cap
+{
+  typedef L4::Smart_cap<T, Smart_count_cap<L4_FP_ALL_SPACES> > Cap;
+};
+
+/**
+ * \brief Automatic capability that implements automatic free and
+ *        unmap+delete of the capability selector.
+ * \param T the type of the object that is referred by the capability.
+ *
+ * This kind of automatic capability implements a counted reference to a
+ * capability selector.  The capability shall be unmapped and freed
+ * when the reference count in the allocator goes to zero.
+ * The main difference to Ref_cap is that the unmap is done with the
+ * deletion flag enabled and this leads to the deletion of the object
+ * if the current task holds appropriate deletion rights.
+ *
+ * Usage:
+ * \code
+ * L4Re::Util::Ref_del_cap<L4Re::Dataspace>::Ca global_ds_cap;
+ *
+ * {
+ *   L4Re::Util::Ref_del_cap<L4Re::Dataspace>::Cap
+ *     ds_cap(L4Re::Util::cap_alloc.alloc<L4Re::Datasapce>));
+ *   // reference count for the allocated cap selector is now 1
+ *
+ *   // use the dataspace cap
+ *   L4Re::chksys(mem_alloc->alloc(4096, ds_cap.get()));
+ *
+ *   global_ds_cap = ds_cap;
+ *   // reference count is now 2
+ *   ...
+ * }
+ * // reference count dropped to 1 (ds_cap is no longer exiting).
+ * ...
+ * global_ds_cap = L4_INVALID_CAP;
+ * // reference count dropped to 0 (data space shall be deleted).
+ * \endcode
+ */
+template< typename T >
+struct Ref_del_cap
+{
+  typedef L4::Smart_cap<T, Smart_count_cap<L4_FP_DELETE_OBJ> > Cap;
+};
+
+/*@}*/
+
+}}
+