1 // Copyright 2017-2019 VMware, Inc.
2 // SPDX-License-Identifier: BSD-2-Clause
3 //
4 // The BSD-2 license (the License) set forth below applies to all parts of the
5 // Cascade project. You may not use this file except in compliance with the
6 // License.
7 //
8 // BSD-2 License
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are met:
12 //
13 // 1. Redistributions of source code must retain the above copyright notice, this
14 // list of conditions and the following disclaimer.
15 //
16 // 2. Redistributions in binary form must reproduce the above copyright notice,
17 // this list of conditions and the following disclaimer in the documentation
18 // and/or other materials provided with the distribution.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND
21 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 #include "runtime/data_plane.h"
32
33 #include <algorithm>
34 #include <cassert>
35 #include "runtime/runtime.h"
36 #include "target/engine.h"
37
38 using namespace std;
39
40 namespace cascade {
41
register_id(const VId id)42 void DataPlane::register_id(const VId id) {
43 if (id >= readers_.size()) {
44 readers_.resize(id+1);
45 }
46 if (id >= writers_.size()) {
47 writers_.resize(id+1);
48 }
49 if (id >= write_buf_.size()) {
50 write_buf_.resize(id+1);
51 }
52 }
53
register_reader(Engine * e,VId id)54 void DataPlane::register_reader(Engine* e, VId id) {
55 assert(id < readers_.size());
56 if (reader_find(e, id) == reader_end(id)) {
57 readers_[id].push_back(e);
58 }
59 }
60
unregister_reader(Engine * e,VId id)61 void DataPlane::unregister_reader(Engine* e, VId id) {
62 assert(id < readers_.size());
63 if (reader_find(e, id) != reader_end(id)) {
64 readers_[id].erase(reader_find(e, id));
65 }
66 }
67
reader_find(Engine * e,VId id) const68 DataPlane::reader_iterator DataPlane::reader_find(Engine* e, VId id) const {
69 assert(id < readers_.size());
70 return find(readers_[id].begin(), readers_[id].end(), e);
71 }
72
reader_begin(VId id) const73 DataPlane::reader_iterator DataPlane::reader_begin(VId id) const {
74 assert(id < readers_.size());
75 return readers_[id].begin();
76 }
77
reader_end(VId id) const78 DataPlane::reader_iterator DataPlane::reader_end(VId id) const {
79 assert(id < readers_.size());
80 return readers_[id].end();
81 }
82
register_writer(Engine * e,VId id)83 void DataPlane::register_writer(Engine* e, VId id) {
84 assert(id < writers_.size());
85 if (writer_find(e, id) == writer_end(id)) {
86 writers_[id].push_back(e);
87 }
88 }
89
unregister_writer(Engine * e,VId id)90 void DataPlane::unregister_writer(Engine* e, VId id) {
91 assert(id < writers_.size());
92 if (writer_find(e, id) != writer_end(id)) {
93 writers_[id].erase(writer_find(e, id));
94 }
95 }
96
writer_find(Engine * e,VId id) const97 DataPlane::writer_iterator DataPlane::writer_find(Engine* e, VId id) const {
98 assert(id < writers_.size());
99 return find(writers_[id].begin(), writers_[id].end(), e);
100 }
101
writer_begin(VId id) const102 DataPlane::writer_iterator DataPlane::writer_begin(VId id) const {
103 assert(id < writers_.size());
104 return writers_[id].begin();
105 }
106
writer_end(VId id) const107 DataPlane::writer_iterator DataPlane::writer_end(VId id) const {
108 assert(id < writers_.size());
109 return writers_[id].end();
110 }
111
write(VId id,const Bits * bits)112 void DataPlane::write(VId id, const Bits* bits) {
113 assert(id < readers_.size());
114 assert(id < write_buf_.size());
115
116 // We want to check two things here:
117 // 1. Are the sizes the same (we're inserting things into the dataplane with
118 // default constructed values).
119 // 2. Assuming the sizes are the same, meaning something was written here, is
120 // the value the same?
121 if ((write_buf_[id].size() == bits->size()) && (write_buf_[id] == *bits)) {
122 return;
123 }
124 write_buf_[id] = *bits;
125 for (auto* e : readers_[id]) {
126 e->read(id, &write_buf_[id]);
127 }
128 }
129
write(VId id,bool b)130 void DataPlane::write(VId id, bool b) {
131 assert(id < readers_.size());
132 assert(id < write_buf_.size());
133
134 if (write_buf_[id].to_bool() == b) {
135 return;
136 }
137 write_buf_[id].flip(0);
138 for (auto* e : readers_[id]) {
139 e->read(id, &write_buf_[id]);
140 }
141 }
142
143 } // namespace cascade
144