1 // Copyright 2017-2018 ccls Authors
2 // SPDX-License-Identifier: Apache-2.0
3
4 #if defined(__unix__) || defined(__APPLE__)
5 #include "platform.hh"
6
7 #include "utils.hh"
8
9 #include <assert.h>
10 #include <limits.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <time.h>
15
16 #include <dirent.h>
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <pthread.h>
20 #include <signal.h>
21 #include <sys/resource.h>
22 #include <sys/stat.h>
23 #include <sys/types.h> // required for stat.h
24 #include <sys/wait.h>
25 #include <unistd.h>
26 #ifdef __GLIBC__
27 #include <malloc.h>
28 #endif
29
30 #include <llvm/ADT/SmallString.h>
31 #include <llvm/Support/Path.h>
32
33 #include <atomic>
34 #include <condition_variable>
35 #include <mutex>
36 #include <string>
37
38 namespace ccls {
39 namespace pipeline {
40 void threadEnter();
41 }
42
normalizePath(llvm::StringRef path)43 std::string normalizePath(llvm::StringRef path) {
44 llvm::SmallString<256> p(path);
45 llvm::sys::path::remove_dots(p, true);
46 return {p.data(), p.size()};
47 }
48
freeUnusedMemory()49 void freeUnusedMemory() {
50 #ifdef __GLIBC__
51 malloc_trim(4 * 1024 * 1024);
52 #endif
53 }
54
traceMe()55 void traceMe() {
56 // If the environment variable is defined, wait for a debugger.
57 // In gdb, you need to invoke `signal SIGCONT` if you want ccls to continue
58 // after detaching.
59 const char *traceme = getenv("CCLS_TRACEME");
60 if (traceme)
61 raise(traceme[0] == 's' ? SIGSTOP : SIGTSTP);
62 }
63
spawnThread(void * (* fn)(void *),void * arg)64 void spawnThread(void *(*fn)(void *), void *arg) {
65 pthread_t thd;
66 pthread_attr_t attr;
67 struct rlimit rlim;
68 size_t stack_size = 4 * 1024 * 1024;
69 if (getrlimit(RLIMIT_STACK, &rlim) == 0 && rlim.rlim_cur != RLIM_INFINITY)
70 stack_size = rlim.rlim_cur;
71 pthread_attr_init(&attr);
72 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
73 pthread_attr_setstacksize(&attr, stack_size);
74 pipeline::threadEnter();
75 pthread_create(&thd, &attr, fn, arg);
76 pthread_attr_destroy(&attr);
77 }
78 } // namespace ccls
79
80 #endif
81