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