1// vim:set ft=cpp: -*- Mode: C++ -*-
2/**
3 * \file
4 * Shared_cap / Shared_del_cap
5 */
6/*
7 * (c) 2017 Alexander Warg <alexander.warg@kernkonzept.com>
8 *
9 * This file is part of TUD:OS and distributed under the terms of the
10 * GNU General Public License 2.
11 * Please see the COPYING-GPL-2 file for details.
12 *
13 * As a special exception, you may use this file as part of a free software
14 * library without restriction.  Specifically, if other files instantiate
15 * templates or use macros or inline functions from this file, or you compile
16 * this file and link it with other files to produce an executable, this
17 * file does not by itself cause the resulting executable to be covered by
18 * the GNU General Public License.  This exception does not however
19 * invalidate any other reasons why the executable file might be covered by
20 * the GNU General Public License.
21 */
22
23#pragma once
24
25#include <l4/re/util/cap_alloc>
26#include <l4/sys/cxx/smart_capability_1x>
27
28namespace L4Re { namespace Util {
29
30/**
31 * Shared capability that implements automatic free and unmap of the capability
32 * selector.
33 *
34 * \tparam T  Type of the object the capability refers to.
35 *
36 * This shared capability implements a counted reference to a capability
37 * selector. The capability shall be unmapped and freed when the reference
38 * count in the allocator goes to zero.
39 *
40 * Usage:
41 *
42 *     L4Re::Util::Shared_cap<L4Re::Dataspace> global_ds_cap;
43 *
44 *     {
45 *       L4Re::Util::Shared_cap<L4Re::Dataspace>
46 *         ds_cap = make_shared_cap<L4Re::Dataspace>();
47 *       // reference count for the allocated cap selector is now 1
48 *
49 *       // use the dataspace cap
50 *       L4Re::chksys(mem_alloc->alloc(4096, ds_cap.get()));
51 *
52 *       global_ds_cap = ds_cap;
53 *       // reference count is now 2
54 *       ...
55 *     }
56 *     // reference count dropped to 1 (ds_cap is no longer existing).
57 */
58template< typename T >
59using Shared_cap = L4::Detail::Shared_cap_impl<T, Smart_count_cap<L4_FP_ALL_SPACES>>;
60/// \copydoc Shared_cap
61template< typename T >
62using shared_cap = L4::Detail::Shared_cap_impl<T, Smart_count_cap<L4_FP_ALL_SPACES>>;
63
64/**
65 * Allocate a capability slot and wrap it in a Shared_cap.
66 *
67 * \tparam T  Type of the object the capability refers to.
68 */
69template< typename T >
70Shared_cap<T>
71make_shared_cap()
72{ return Shared_cap<T>(cap_alloc.alloc<T>()); }
73
74/**
75 * Shared capability that implements automatic free and unmap+delete of the
76 * capability selector.
77 *
78 * \tparam T  Type of the object the capability refers to.
79 *
80 * This shared capability implements a counted reference to a capability
81 * selector. The capability shall be unmapped and freed when the reference
82 * count in the allocator goes to zero.
83 * The main difference to Shared_cap is that the unmap is done with the
84 * deletion flag enabled and this leads to the deletion of the object
85 * if the current task holds appropriate deletion rights.
86 *
87 * Usage:
88 *
89 *     L4Re::Util::Shared_del_cap<L4Re::Dataspace> global_ds_cap;
90 *
91 *     {
92 *       L4Re::Util::Shared_del_cap<L4Re::Dataspace>
93 *         ds_cap = make_shared_del_cap<L4Re::Dataspace>();
94 *       // reference count for the allocated cap selector is now 1
95 *
96 *       // use the dataspace cap
97 *       L4Re::chksys(mem_alloc->alloc(4096, ds_cap.get()));
98 *
99 *       global_ds_cap = ds_cap;
100 *       // reference count is now 2
101 *       ...
102 *     }
103 *     // reference count dropped to 1 (ds_cap is no longer existing).
104 *     ...
105 *     global_ds_cap = L4_INVALID_CAP;
106 *     // reference count dropped to 0 (data space shall be deleted).
107 */
108template< typename T >
109using Shared_del_cap = L4::Detail::Shared_cap_impl<T, Smart_count_cap<L4_FP_DELETE_OBJ>>;
110/// \copydoc Shared_del_cap
111template< typename T >
112using shared_del_cap = L4::Detail::Shared_cap_impl<T, Smart_count_cap<L4_FP_DELETE_OBJ>>;
113
114/**
115 * Allocate a capability slot and wrap it in a Shared_del_cap.
116 *
117 * \tparam T  Type of the object the capability refers to.
118 */
119template< typename T >
120Shared_del_cap<T>
121make_shared_del_cap()
122{ return Shared_del_cap<T>(cap_alloc.alloc<T>()); }
123
124}} // namespace L4Re::Util
125
126