From 1f4f72013654f3b03e19f95e1612281527386256 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Tue, 28 Feb 2017 00:37:20 -0800 Subject: [PATCH] more wip --- command_line.cc | 2 +- indexer.h | 4 ++ query.h | 15 +++++++- serializer.cc | 34 +++++++++++++++++ serializer.h | 3 +- shared_memory_win.cpp | 89 +++++++++++++++++++++++++++++++++++++++++++ task.cc | 19 ++++++++- 7 files changed, 161 insertions(+), 5 deletions(-) create mode 100644 shared_memory_win.cpp diff --git a/command_line.cc b/command_line.cc index 5d967a63..8786ae99 100644 --- a/command_line.cc +++ b/command_line.cc @@ -71,7 +71,7 @@ bool HasOption(const std::unordered_map& options, cons return options.find(option) != options.end(); } -int main(int argc, char** argv) { +int main5555(int argc, char** argv) { std::unordered_map options = ParseOptions(argc, argv); if (argc == 1 || options.find("--help") != options.end()) { diff --git a/indexer.h b/indexer.h index 4b5df4a9..2b13d84b 100644 --- a/indexer.h +++ b/indexer.h @@ -88,6 +88,10 @@ struct Location { return FileId(raw_file_id); } + explicit Location(const char* encoded) { + // TODO + } + std::string ToString() { // Output looks like this: // diff --git a/query.h b/query.h index 94bbe53d..7cfc5e99 100644 --- a/query.h +++ b/query.h @@ -157,7 +157,20 @@ struct SymbolIdx { }; - +// TODO: We need to control Usr, std::vector allocation to make sure it happens on shmem. That or we +// make IndexUpdate a POD type. +// TODO: Instead of all of that work above, we pipe the IndexUpdate across processes as JSON. +// We need to verify we need multiple processes first. Maybe libclang can run in a single process... +// TODO: Compute IndexUpdates in main process, off the blocking thread. Use separate process for running +// libclang. Solves memory worries. +namespace foo2 { + using Usr = size_t; + struct UsrTable { + size_t allocated; + size_t used; + const char* usrs[]; + }; +} struct IndexUpdate { diff --git a/serializer.cc b/serializer.cc index a06e832f..d91850a7 100644 --- a/serializer.cc +++ b/serializer.cc @@ -170,3 +170,37 @@ void Serialize(Writer& writer, IndexedFile* file) { writer.EndObject(); #undef WRITE } + +void Deserialize(std::string& output, rapidjson::GenericValue>& value) { + output = value.GetString(); +} + +void Deserialize(optional& output, rapidjson::GenericValue>& value) { + if (!value.IsNull()) + output = Location(value.GetString()); // TODO: Location parsing not implemented in Location type. +} + +void Deserialize(Reader& reader, IndexedFile* file) { + auto& types = reader["types"].GetArray(); + for (auto& type : types) { + TypeId id = TypeId(type["id"].GetInt64()); + std::string usr = type["usr"].GetString(); + + IndexedTypeDef def(id, usr); + Deserialize(def.def.short_name, type["short_name"]); + Deserialize(def.def.qualified_name, type["qualified_name"]); + Deserialize(def.def.definition, type["definition"]); // TODO: What happens if entry is not present? + //SERIALIZE("short_name", def.short_name); + //SERIALIZE("qualified_name", def.qualified_name); + //SERIALIZE("definition", def.definition); + //SERIALIZE("alias_of", def.alias_of); + //SERIALIZE("parents", def.parents); + //SERIALIZE("derived", derived); + //SERIALIZE("types", def.types); + //SERIALIZE("funcs", def.funcs); + //SERIALIZE("vars", def.vars); + //SERIALIZE("uses", uses); + + file->types.push_back(def); + } +} \ No newline at end of file diff --git a/serializer.h b/serializer.h index 1703099f..8d091fe4 100644 --- a/serializer.h +++ b/serializer.h @@ -5,4 +5,5 @@ struct IndexedFile; using Writer = rapidjson::PrettyWriter; using Reader = rapidjson::Document; -void Serialize(Writer& writer, IndexedFile* file); \ No newline at end of file +void Serialize(Writer& writer, IndexedFile* file); +void Deserialize(Reader& reader, IndexedFile* file); \ No newline at end of file diff --git a/shared_memory_win.cpp b/shared_memory_win.cpp new file mode 100644 index 00000000..ec86250d --- /dev/null +++ b/shared_memory_win.cpp @@ -0,0 +1,89 @@ +#include + +#include + +const int shmem_size = 16; // 16byte + +void reader() { + HANDLE shmem = INVALID_HANDLE_VALUE; + HANDLE mutex = INVALID_HANDLE_VALUE; + + mutex = ::CreateMutex(NULL, FALSE, "mutex_sample_name"); + + shmem = ::CreateFileMapping( + INVALID_HANDLE_VALUE, + NULL, + PAGE_READWRITE, + 0, + shmem_size, + "shared_memory_name" + ); + + char *buf = (char*)MapViewOfFile(shmem, FILE_MAP_ALL_ACCESS, 0, 0, shmem_size); + + + for (unsigned int c = 0; c < 60; ++c) { + // mutex lock + WaitForSingleObject(mutex, INFINITE); + + int value = buf[0]; + std::cout << "read shared memory...c=" << value << std::endl; + + // mutex unlock + ::ReleaseMutex(mutex); + + ::Sleep(1000); + } + + // release + ::UnmapViewOfFile(buf); + ::CloseHandle(shmem); + ::ReleaseMutex(mutex); +} + +void writer() { + HANDLE shmem = INVALID_HANDLE_VALUE; + HANDLE mutex = INVALID_HANDLE_VALUE; + + mutex = ::CreateMutex(NULL, FALSE, "mutex_sample_name"); + + shmem = ::CreateFileMapping( + INVALID_HANDLE_VALUE, + NULL, + PAGE_READWRITE, + 0, + shmem_size, + "shared_memory_name" + ); + + char *buf = (char*)::MapViewOfFile(shmem, FILE_MAP_ALL_ACCESS, 0, 0, shmem_size); + + for (unsigned int c = 0; c < 60; ++c) { + // mutex lock + WaitForSingleObject(mutex, INFINITE); + + // write shared memory + memset(buf, c, shmem_size); + + std::cout << "write shared memory...c=" << c << std::endl; + + // mutex unlock + ::ReleaseMutex(mutex); + + ::Sleep(1000); + } + + // release + ::UnmapViewOfFile(buf); + ::CloseHandle(shmem); + ::ReleaseMutex(mutex); +} + +int main52525252(int argc, char** argv) { + if (argc == 2) + writer(); + else + reader(); + + return 0; +} \ No newline at end of file diff --git a/task.cc b/task.cc index e7c22c0d..6c8ae429 100644 --- a/task.cc +++ b/task.cc @@ -5,13 +5,16 @@ #include "indexer.h" #include "query.h" - +#include "optional.h" #include "third_party/tiny-process-library/process.hpp" #include #include #include +using std::experimental::optional; +using std::experimental::nullopt; + // A threadsafe-queue. http://stackoverflow.com/a/16075550 template class SafeQueue { @@ -36,6 +39,18 @@ public: return val; } + // Get the "front"-element. + // Returns empty if the queue is empty. + optional try_dequeue() { + std::unique_lock lock(mutex_); + if (queue_.empty()) + return nullopt; + + T val = queue_.front(); + queue_.pop(); + return val; + } + private: std::queue queue_; mutable std::mutex mutex_; @@ -116,7 +131,7 @@ void Pump(TaskManager* tm) { //tm->threads[0]. } -int main4(int argc, char** argv) { +int main(int argc, char** argv) { TaskManager tm(5); // TODO: looks like we will have to write shared memory support.