// Copyright 2017-2018 ccls Authors // SPDX-License-Identifier: Apache-2.0 #if defined(__unix__) || defined(__APPLE__) #include "platform.hh" #include "log.hh" #include "utils.hh" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // required for stat.h #include #include #ifdef __GLIBC__ #include #endif #include #include #include #include #include #include namespace ccls { namespace pipeline { void threadEnter(); } std::string normalizePath(const std::string &path) { llvm::SmallString<256> p(path); llvm::sys::path::remove_dots(p, true); return {p.data(), p.size()}; } void freeUnusedMemory() { #ifdef __GLIBC__ malloc_trim(4 * 1024 * 1024); #endif } void traceMe() { // If the environment variable is defined, wait for a debugger. // In gdb, you need to invoke `signal SIGCONT` if you want ccls to continue // after detaching. const char *traceme = getenv("CCLS_TRACEME"); if (traceme) raise(traceme[0] == 's' ? SIGSTOP : SIGTSTP); } void spawnThread(void *(*fn)(void *), void *arg) { pthread_t thd; pthread_attr_t attr; struct rlimit rlim; size_t stack_size = 4 * 1024 * 1024; if (getrlimit(RLIMIT_STACK, &rlim) == 0 && rlim.rlim_cur != RLIM_INFINITY) stack_size = rlim.rlim_cur; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_attr_setstacksize(&attr, stack_size); pipeline::threadEnter(); pthread_create(&thd, &attr, fn, arg); pthread_attr_destroy(&attr); } void setBatchPriority() { #ifdef SCHED_BATCH pid_t this_thread_id = gettid(); // get a sched_param with the existing thread sched_priority errno = 0; struct sched_param p; p.sched_priority = getpriority(PRIO_PROCESS, this_thread_id); if (p.sched_priority == -1 && errno != 0) { LOG_S(ERROR) << "failed to getpriority(): " << strerror(errno); return; } // retain the existing sched_priority, but use SCHED_BATCH policy if (sched_setscheduler(this_thread_id, SCHED_BATCH, &p) == -1) { LOG_S(ERROR) << "failed to sched_setscheduler(): " << strerror(errno); } } #endif } // namespace ccls #endif