Line data Source code
1 : /*
2 : * (C) Copyright 2010 Xilexio
3 : *
4 : * This file is part of CoherentDB.
5 : *
6 : * CoherentDB is free software: you can redistribute it and/or modify it
7 : * under the terms of the GNU General Public License as published by
8 : * the Free Software Foundation, either version 3 of the License, or
9 : * (at your option) any later version.
10 : *
11 : * CoherentDB is distributed in the hope that it will be useful, but
12 : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public
17 : * License along with CoherentDB. If not, see
18 : * http://www.gnu.org/licenses/.
19 : */
20 :
21 : #include <sys/mman.h>
22 : #include <memory_manager/manager.h>
23 : #include <memory_manager/session.h>
24 : #include <memory_manager/sub_session.h>
25 : #include <debug/asserts.h>
26 :
27 : namespace coherent
28 : {
29 : namespace memory_manager
30 : {
31 :
32 : typedef boost::shared_lock<boost::shared_mutex> scoped_read_lock;
33 : typedef boost::unique_lock<boost::shared_mutex> scoped_write_lock;
34 : typedef boost::unique_lock<boost::mutex> scoped_lock;
35 :
36 36 : void dummy_function(memory_sub_session*) {}
37 1 : boost::thread_specific_ptr<memory_sub_session> memory_session::current_sub_session(dummy_function);
38 :
39 8 : memory_session::memory_session(bool autostart): allocated_bytes(0), default_sub_session(new memory_sub_session(this, false))
40 : {
41 8 : limit_bytes = memory_manager::instance->get_default_session_limit_bytes();
42 :
43 8 : internal_init(autostart);
44 8 : }
45 :
46 0 : memory_session::memory_session(size_t starting_limit_bytes, bool autostart) : limit_bytes(starting_limit_bytes), allocated_bytes(0), default_sub_session(new memory_sub_session(this, false))
47 : {
48 0 : internal_init(autostart);
49 0 : }
50 :
51 8 : memory_session::~memory_session()
52 : {
53 8 : end();
54 :
55 8 : delete default_sub_session;
56 :
57 8 : memory_manager::instance->free_bytes(limit_bytes);
58 :
59 : // TODO triggerable assert if there is non-released memory left
60 8 : }
61 :
62 167 : memory_session* memory_session::current()
63 : {
64 167 : if (current_sub_session.get() == 0)
65 0 : return 0;
66 :
67 168 : return current_sub_session->get_parent();
68 : }
69 :
70 36 : void memory_session::begin()
71 : {
72 36 : activate();
73 :
74 36 : default_sub_session->begin();
75 :
76 35 : scoped_lock am(active_threads_mutex);
77 34 : ++active_threads_count;
78 36 : }
79 :
80 36 : void memory_session::end()
81 : {
82 36 : deactivate();
83 :
84 72 : scoped_lock am(active_threads_mutex);
85 36 : if (active_threads_count > 0)
86 36 : --active_threads_count;
87 36 : }
88 :
89 0 : void memory_session::stop()
90 : {
91 0 : deactivate();
92 :
93 0 : scoped_read_lock ss(sub_sessions_lock);
94 :
95 0 : for (std::set<memory_sub_session*>::const_iterator i = sub_sessions.begin(); i != sub_sessions.end(); ++i)
96 : {
97 0 : (*i)->stop();
98 : }
99 :
100 0 : scoped_lock am(active_threads_mutex);
101 : d_assert(active_threads_count > 0);
102 0 : --active_threads_count;
103 0 : }
104 :
105 0 : void memory_session::resume()
106 : {
107 : {
108 0 : scoped_lock am(active_threads_mutex);
109 0 : ++active_threads_count;
110 : }
111 :
112 0 : activate();
113 0 : default_sub_session->resume();
114 0 : }
115 :
116 0 : void memory_session::set_default_current()
117 : {
118 0 : default_sub_session->set_current();
119 0 : }
120 :
121 0 : size_t memory_session::get_limit_bytes() const
122 : {
123 0 : scoped_read_lock ll(limit_lock);
124 0 : return limit_bytes;
125 : }
126 :
127 4 : void memory_session::set_limit_bytes(size_t bytes)
128 : {
129 4 : scoped_write_lock ll(limit_lock);
130 4 : limit_bytes = bytes;
131 4 : }
132 :
133 8 : size_t memory_session::get_allocated_bytes() const
134 : {
135 8 : scoped_read_lock al(alloc_lock);
136 8 : return allocated_bytes;
137 : }
138 :
139 8 : void memory_session::internal_init(bool autostart)
140 : {
141 8 : memory_manager::instance->reserve_bytes(limit_bytes);
142 :
143 8 : sub_sessions.insert(default_sub_session);
144 :
145 8 : if (autostart)
146 8 : begin();
147 8 : }
148 :
149 36 : void memory_session::activate()
150 : {
151 36 : if (current_sub_session.get() && current_sub_session->get_parent() != this)
152 0 : current_sub_session->get_parent()->stop();
153 : // TODO maybe only assert here
154 :
155 36 : default_sub_session->set_current();
156 36 : }
157 :
158 36 : void memory_session::deactivate()
159 : {
160 36 : if (current_sub_session.get() && current_sub_session->get_parent() == this)
161 36 : current_sub_session.reset();
162 36 : }
163 :
164 : }
165 3 : }
|