OmniSciDB  c1a53651b2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CodeCacheAccessor.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
19 
20 template <typename CompilationContext>
22  const CodeCacheKey& key) {
23  std::lock_guard<std::mutex> lock(code_cache_mutex_);
24  get_count_++;
25  auto it = code_cache_.find(key);
26  if (it != code_cache_.cend()) {
27  found_count_++;
28  return it->second;
29  }
30  return {};
31 }
32 
33 template <typename CompilationContext>
36  bool warn = false;
37  {
38  std::lock_guard<std::mutex> lock(code_cache_mutex_);
39  // if key is in cache, put is no-op
40  auto it = code_cache_.find(key);
41  put_count_++;
42  if (it == code_cache_.cend()) {
43  code_cache_.put(key, value);
44  } else {
45  ignore_count_++;
46  warn = true;
47  }
48  }
49  if (warn) {
50  LOG(WARNING) << *this << ": code already in cache, ignoring.\n";
51  }
52 }
53 
54 template <typename CompilationContext>
56  const CodeCacheKey& key) {
57  CodeCacheVal<CompilationContext>* cached_code = nullptr;
58  std::unique_lock<std::mutex> lk(code_cache_mutex_);
59  get_count_++;
60  cached_code = code_cache_.get(key);
61  if (cached_code) {
62  if (cached_code->get()) {
63  found_count_++;
64  return cached_code;
65  } else {
66  // Wait until compiling thread inserts code to cache. TODO: this
67  // wait also locks other unrelated get_or_wait calls on
68  // different keys. This is suboptimal as it will block in
69  // addition to others threads get_or_wait(key) calls, also
70  // independent get_or_wait(other_key) calls. To fix this, we'll
71  // need a key specific mutex or use some other approach that
72  // would allow threads with other keys to proceed.
73  compilation_cv_.wait(lk, [&] { return !!(code_cache_.get(key)->get()); });
74  cached_code = code_cache_.get(key);
75  CHECK(cached_code->get());
76  found_count_++;
77  return cached_code;
78  }
79  }
80  // This is the first time the key is used to acquire code from
81  // cache. Insert null value to cache so that other threads acquiring
82  // the same key will wait (see above) until the code is inserted to
83  // cache (by put method below):
84  CodeCacheVal<CompilationContext> not_a_code(nullptr);
85  code_cache_.put(key, std::move(not_a_code));
86  return nullptr; // caller must trigger code compilation for the given key
87 }
88 
89 template <typename CompilationContext>
91  const CodeCacheKey& key,
93  std::lock_guard<std::mutex> lock(code_cache_mutex_);
94  auto result = code_cache_.get(key);
95  CHECK(result); // get_or_wait has inserted not_a_code to code cache
96  CHECK(!result->get()); // ensure that result really contains not_a_code per get_or_wait
97  result->swap(value); // swap not_a_code with actual code
98  compilation_cv_.notify_all(); // notify waiting get_or_wait(..) calls
99 }
100 
101 template <typename CompilationContext>
103  std::lock_guard<std::mutex> lock(code_cache_mutex_);
104  code_cache_.clear();
105 }
106 
std::shared_ptr< CC > CodeCacheVal
Definition: CodeCache.h:27
CodeCacheVal< CompilationContext > get_value(const CodeCacheKey &key)
#define LOG(tag)
Definition: Logger.h:285
std::vector< std::string > CodeCacheKey
Definition: CodeCache.h:25
void swap(const CodeCacheKey &key, CodeCacheVal< CompilationContext > &&value)
#define CHECK(condition)
Definition: Logger.h:291
CodeCacheVal< CompilationContext > * get_or_wait(const CodeCacheKey &key)
void put(const CodeCacheKey &key, CodeCacheVal< CompilationContext > &value)