linux platform WIP

This commit is contained in:
Jacob Dufault 2017-03-03 17:45:20 -08:00
parent 15b5a03a08
commit 2a08552265
9 changed files with 239 additions and 92 deletions

View File

@ -25,13 +25,21 @@ string(STRIP "${LIBCLANG_LIBDIR}" LIBCLANG_LIBDIR)
find_library(LIBCLANG_LIBRARIES NAMES libclang clang find_library(LIBCLANG_LIBRARIES NAMES libclang clang
PATHS ${LIBCLANG_LIBDIR}) PATHS ${LIBCLANG_LIBDIR})
set(LIBCLANG_INCLUDEDIR "/usr/local/google/home/jdufault/super-clang-index/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04/include")
set(LIBCLANG_LIBDIR "/usr/local/google/home/jdufault/super-clang-index/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04/lib")
set(LIBCLANG_LIBRARIES "/usr/local/google/home/jdufault/super-clang-index/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04/lib/libclang.so")
# #
# Debugging # Debugging
# #
#message("SOURCE_FILES: " ${SOURCE_FILES} ) #message("SOURCE_FILES: " ${SOURCE_FILES} )
#message("LIBCLANG_INCLUDEDIR: " ${LIBCLANG_INCLUDEDIR}) message("LIBCLANG_INCLUDEDIR: " ${LIBCLANG_INCLUDEDIR})
#message("LIBCLANG_LIBDIR: " ${LIBCLANG_LIBDIR}) message("LIBCLANG_LIBDIR: " ${LIBCLANG_LIBDIR})
#message("LIBCLANG_LIBRARIES: " ${LIBCLANG_LIBRARIES}) message("LIBCLANG_LIBRARIES: " ${LIBCLANG_LIBRARIES})
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall")

View File

@ -187,7 +187,7 @@ IpcMessageId IpcMessage_DocumentSymbolsResponse::id = "IpcMessage_DocumentSymbol
void IndexerServerMain() { void IndexerServerMain() {
IpcServer ipc("language_server"); IpcServer ipc("languageserver");
while (true) { while (true) {
std::vector<std::unique_ptr<BaseIpcMessage>> messages = ipc.TakeMessages(); std::vector<std::unique_ptr<BaseIpcMessage>> messages = ipc.TakeMessages();
@ -206,8 +206,7 @@ void IndexerServerMain() {
} }
} }
using namespace std::chrono_literals; std::this_thread::sleep_for(std::chrono::milliseconds(20));
std::this_thread::sleep_for(20ms);
} }
} }
@ -243,7 +242,7 @@ void LanguageServerLoop(IpcClient& ipc) {
} }
void LanguageServerMain() { void LanguageServerMain() {
IpcClient ipc("language_server", 0); IpcClient ipc("languageserver", 0);
// Discard any left-over messages from previous runs. // Discard any left-over messages from previous runs.
ipc.TakeMessages(); ipc.TakeMessages();
@ -251,8 +250,9 @@ void LanguageServerMain() {
// Emit an alive check. Sleep so the server has time to respond. // Emit an alive check. Sleep so the server has time to respond.
IpcMessage_IsAlive check_alive; IpcMessage_IsAlive check_alive;
ipc.SendToServer(&check_alive); ipc.SendToServer(&check_alive);
using namespace std::chrono_literals;
std::this_thread::sleep_for(50ms); // TODO: Tune this value or make it configurable. // TODO: Tune this value or make it configurable.
std::this_thread::sleep_for(std::chrono::milliseconds(20));
// Check if we got an IsAlive message back. // Check if we got an IsAlive message back.
std::vector<std::unique_ptr<BaseIpcMessage>> messages = ipc.TakeMessages(); std::vector<std::unique_ptr<BaseIpcMessage>> messages = ipc.TakeMessages();

13
ipc.cc
View File

@ -6,11 +6,11 @@ namespace {
} }
std::string NameToServerName(const std::string& name) { std::string NameToServerName(const std::string& name) {
return name + "_server"; return name + "server";
} }
std::string NameToClientName(const std::string& name, int client_id) { std::string NameToClientName(const std::string& name, int client_id) {
return name + "_server_" + std::to_string(client_id); return name + "client" + std::to_string(client_id);
} }
} }
@ -49,8 +49,8 @@ std::unique_ptr<BaseIpcMessage> IpcRegistry::Allocate(int id) {
IpcDirectionalChannel::IpcDirectionalChannel(const std::string& name) { IpcDirectionalChannel::IpcDirectionalChannel(const std::string& name) {
local_block = new char[shmem_size]; local_block = new char[shmem_size];
shared = CreatePlatformSharedMemory(name + "_memory"); shared = CreatePlatformSharedMemory(name + "memory");
mutex = CreatePlatformMutex(name + "_mutex"); mutex = CreatePlatformMutex(name + "mutex");
} }
IpcDirectionalChannel::~IpcDirectionalChannel() { IpcDirectionalChannel::~IpcDirectionalChannel() {
@ -71,13 +71,12 @@ void IpcDirectionalChannel::PushMessage(BaseIpcMessage* message) {
bool first = true; bool first = true;
bool did_log = false; bool did_log = false;
while (true) { while (true) {
using namespace std::chrono_literals;
if (!first) { if (!first) {
if (!did_log) { if (!did_log) {
std::cout << "[info]: shmem full, waiting" << std::endl; // TODO: remove std::cout << "[info]: shmem full, waiting" << std::endl; // TODO: remove
did_log = true; did_log = true;
} }
std::this_thread::sleep_for(16ms); std::this_thread::sleep_for(std::chrono::milliseconds(16));
} }
first = false; first = false;
@ -143,7 +142,7 @@ void IpcServer::SendToClient(int client_id, BaseIpcMessage* message) {
// Find or create the client. // Find or create the client.
auto it = clients_.find(client_id); auto it = clients_.find(client_id);
if (it == clients_.end()) if (it == clients_.end())
clients_[client_id] = std::make_unique<IpcDirectionalChannel>(NameToClientName(name_, client_id)); clients_[client_id] = MakeUnique<IpcDirectionalChannel>(NameToClientName(name_, client_id));
clients_[client_id]->PushMessage(message); clients_[client_id]->PushMessage(message);
} }

4
ipc.h
View File

@ -84,8 +84,8 @@ struct IpcRegistry {
template<typename T> template<typename T>
void IpcRegistry::Register() { void IpcRegistry::Register() {
if (!allocators) { if (!allocators) {
allocators = std::make_unique<std::unordered_map<int, Allocator>>(); allocators = MakeUnique<std::unordered_map<int, Allocator>>();
hash_to_id = std::make_unique<std::unordered_map<int, std::string>>(); hash_to_id = MakeUnique<std::unordered_map<int, std::string>>();
} }
IpcMessageId id = T::id; IpcMessageId id = T::id;

View File

@ -101,6 +101,8 @@ namespace std{
namespace experimental{ namespace experimental{
#define TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS
// BEGIN workaround for missing is_trivially_destructible // BEGIN workaround for missing is_trivially_destructible
# if defined TR2_OPTIONAL_GCC_4_8_AND_HIGHER___ # if defined TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
// leave it: it is already there // leave it: it is already there

118
platform_linux.cc Normal file
View File

@ -0,0 +1,118 @@
#include "platform.h"
#include "utils.h"
#include <cassert>
#include <string>
#include <pthread.h>
#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <time.h>
#include <assert.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <semaphore.h>
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
struct PlatformMutexLinux : public PlatformMutex {
sem_t* sem_ = nullptr;
PlatformMutexLinux(const std::string& name) {
std::cout << "PlatformMutexLinux name=" << name << std::endl;
sem_ = sem_open(name.c_str(), O_CREAT, 0666 /*permission*/, 1 /*initial_value*/);
}
~PlatformMutexLinux() override {
sem_close(sem_);
}
};
struct PlatformScopedMutexLockLinux : public PlatformScopedMutexLock {
sem_t* sem_ = nullptr;
PlatformScopedMutexLockLinux(sem_t* sem) : sem_(sem) {
std::cout << "PlatformScopedMutexLockLinux" << std::endl;
sem_wait(sem_);
}
~PlatformScopedMutexLockLinux() override {
sem_post(sem_);
}
};
struct PlatformSharedMemoryLinux : public PlatformSharedMemory {
std::string name_;
int fd_;
void* shared_start_real_;
PlatformSharedMemoryLinux(const std::string& name) : name_(name) {
std::cout << "PlatformSharedMemoryLinux name=" << name << std::endl;
fd_ = shm_open(name_.c_str(), O_CREAT, O_RDWR);
std::cout << "shm_open errno=" << errno << std::endl;
std::cout << "1" << std::endl;
ftruncate(fd_, shmem_size);
std::cout << "ftruncate errno=" << errno << std::endl;
std::cout << "2" << std::endl;
//void *mmap(void *addr, size_t length, int prot, int flags,
// int fd, off_t offset);
//int munmap(void *addr, size_t length);
//
//shmem_size
std::cout << "3" << std::endl;
shared_start_real_ = mmap(nullptr /*kernel assigned starting address*/,
shmem_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0 /*offset*/);
std::cout << "mmap errno=" << errno << std::endl;
std::cout << "fd_ = " << fd_ << std::endl;
std::cout << "shared_start_real_ = " << shared_start_real_ << std::endl;
std::cout << "4" << std::endl;
/*
int fd = shm_open("shmname", O_CREAT, O_RDWR);
sem_t *sem = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
ftruncate(fd_, shmem_size);
sem_init(sem, 1, 1);
*/
std::cout << "4a" << std::endl;
shared_bytes_used = reinterpret_cast<size_t*>(shared_start_real_);
std::cout << "4b" << std::endl;
*shared_bytes_used = 0;
std::cout << "4c" << std::endl;
shared_start = reinterpret_cast<char*>(shared_bytes_used + 1);
std::cout << "5" << std::endl;
}
~PlatformSharedMemoryLinux() override {
munmap(shared_start_real_, shmem_size);
shm_unlink(name_.c_str());
}
};
std::unique_ptr<PlatformMutex> CreatePlatformMutex(const std::string& name) {
std::string name2 = "/" + name;
return MakeUnique<PlatformMutexLinux>(name2);
}
std::unique_ptr<PlatformScopedMutexLock> CreatePlatformScopedMutexLock(PlatformMutex* mutex) {
return MakeUnique<PlatformScopedMutexLockLinux>(static_cast<PlatformMutexLinux*>(mutex)->sem_);
}
std::unique_ptr<PlatformSharedMemory> CreatePlatformSharedMemory(const std::string& name) {
std::string name2 = "/" + name;
return MakeUnique<PlatformSharedMemoryLinux>(name2);
}

View File

@ -1,3 +1,4 @@
#if false
#include "platform.h" #include "platform.h"
#include <cassert> #include <cassert>
@ -59,13 +60,14 @@ struct PlatformSharedMemoryWin : public PlatformSharedMemory {
std::unique_ptr<PlatformMutex> CreatePlatformMutex(const std::string& name) { std::unique_ptr<PlatformMutex> CreatePlatformMutex(const std::string& name) {
return std::make_unique<PlatformMutexWin>(name); return MakeUnique<PlatformMutexWin>(name);
} }
std::unique_ptr<PlatformScopedMutexLock> CreatePlatformScopedMutexLock(PlatformMutex* mutex) { std::unique_ptr<PlatformScopedMutexLock> CreatePlatformScopedMutexLock(PlatformMutex* mutex) {
return std::make_unique<PlatformScopedMutexLockWin>(static_cast<PlatformMutexWin*>(mutex)->raw_mutex); return MakeUnique<PlatformScopedMutexLockWin>(static_cast<PlatformMutexWin*>(mutex)->raw_mutex);
} }
std::unique_ptr<PlatformSharedMemory> CreatePlatformSharedMemory(const std::string& name) { std::unique_ptr<PlatformSharedMemory> CreatePlatformSharedMemory(const std::string& name) {
return std::make_unique<PlatformSharedMemoryWin>(name); return MakeUnique<PlatformSharedMemoryWin>(name);
} }
#endif

View File

@ -2,6 +2,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <memory>
std::vector<std::string> GetFilesInFolder(std::string folder); std::vector<std::string> GetFilesInFolder(std::string folder);
std::vector<std::string> ReadLines(std::string filename); std::vector<std::string> ReadLines(std::string filename);
@ -11,3 +12,10 @@ void Fail(const std::string& message);
void WriteToFile(const std::string& filename, const std::string& content); void WriteToFile(const std::string& filename, const std::string& content);
// note: this implementation does not disable this overload for array types
// See http://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique#Possible_Implementatiog
template<typename T, typename... Args>
std::unique_ptr<T> MakeUnique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

18
wscript
View File

@ -1,12 +1,17 @@
#! /usr/bin/env python #! /usr/bin/env python
# encoding: utf-8 # encoding: utf-8
import urllib2
VERSION='0.0.1' VERSION='0.0.1'
APPNAME='indexer' APPNAME='indexer'
top = '.' top = '.'
out = 'build' out = 'build'
from waflib.Tools.compiler_cxx import cxx_compiler
cxx_compiler['linux'] = ['clang++', 'g++']
def options(opt): def options(opt):
opt.load('compiler_cxx') opt.load('compiler_cxx')
@ -15,8 +20,10 @@ def configure(conf):
conf.check(header_name='stdio.h', features='cxx cxxprogram', mandatory=True) conf.check(header_name='stdio.h', features='cxx cxxprogram', mandatory=True)
# https://github.com/Andersbakken/rtags/blob/master/scripts/getclang.sh # https://github.com/Andersbakken/rtags/blob/master/scripts/getclang.sh
def download_clang(): def download_clang(conf):
#'http://releases.llvm.org/3.9.0/clang+llvm-3.9.0-x86_64-apple-darwin.tar.xz' url = 'http://releases.llvm.org/3.9.0/clang+llvm-3.9.0-x86_64-apple-darwin.tar.xz'
response = urllib2.urlopen(url)
html = response.read()
pass pass
def build(bld): def build(bld):
@ -24,8 +31,11 @@ def build(bld):
excl=['*tests/*', 'third_party/*']) excl=['*tests/*', 'third_party/*'])
bld.program( bld.program(
source=cc_files, source=cc_files,
cxxflags=['-std=c++14'], cxxflags=['-std=c++11'],
includes=['third_party/rapidjson/include'], includes=['third_party/rapidjson/include',
'/usr/local/google/home/jdufault/super-clang-index/clang+llvm-3.9.0-x86_64-linux-gnu-ubuntu-14.04/include'],
lib=['clang', 'rt', 'pthread'],
libpath=['/usr/local/google/home/jdufault/super-clang-index/clang+llvm-3.9.0-x86_64-linux-gnu-ubuntu-14.04/lib'],
target='app') target='app')
#bld.shlib(source='a.cpp', target='mylib', vnum='9.8.7') #bld.shlib(source='a.cpp', target='mylib', vnum='9.8.7')