]> arthur.barton.de Git - netdata.git/blob - src/common.c
build: migrate to autotools
[netdata.git] / src / common.c
1 #ifdef HAVE_CONFIG_H
2 #include <config.h>
3 #endif
4 #include <sys/syscall.h>
5 #include <string.h>
6 #include <ctype.h>
7 #include <errno.h>
8 #include <unistd.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 #include <sys/mman.h>
13
14
15 #include "log.h"
16 #include "common.h"
17
18 char *global_host_prefix = "";
19
20 /*
21 // http://stackoverflow.com/questions/7666509/hash-function-for-string
22 uint32_t simple_hash(const char *name)
23 {
24         const char *s = name;
25         uint32_t hash = 5381;
26         int i;
27
28         while((i = *s++)) hash = ((hash << 5) + hash) + i;
29
30         // fprintf(stderr, "HASH: %lu %s\n", hash, name);
31
32         return hash;
33 }
34 */
35
36
37 // http://isthe.com/chongo/tech/comp/fnv/#FNV-1a
38 uint32_t simple_hash(const char *name) {
39         unsigned char *s = (unsigned char *)name;
40         uint32_t hval = 0x811c9dc5;
41
42         // FNV-1a algorithm
43         while (*s) {
44                 // multiply by the 32 bit FNV magic prime mod 2^32
45                 // gcc optimized
46                 hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24);
47
48                 // xor the bottom with the current octet
49                 hval ^= (uint32_t)*s++;
50         }
51
52         // fprintf(stderr, "HASH: %u = %s\n", hval, name);
53         return hval;
54 }
55
56 /*
57 // http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx
58 // one at a time hash
59 uint32_t simple_hash(const char *name) {
60         unsigned char *s = (unsigned char *)name;
61         uint32_t h = 0;
62
63         while(*s) {
64                 h += *s++;
65                 h += (h << 10);
66                 h ^= (h >> 6);
67         }
68
69         h += (h << 3);
70         h ^= (h >> 11);
71         h += (h << 15);
72
73         // fprintf(stderr, "HASH: %u = %s\n", h, name);
74
75         return h;
76 }
77 */
78
79 void strreverse(char* begin, char* end)
80 {
81     char aux;
82     while (end > begin)
83         aux = *end, *end-- = *begin, *begin++ = aux;
84 }
85
86 char *mystrsep(char **ptr, char *s)
87 {
88         char *p = "";
89         while ( p && !p[0] && *ptr ) p = strsep(ptr, s);
90         return(p);
91 }
92
93 char *trim(char *s)
94 {
95         // skip leading spaces
96         while(*s && isspace(*s)) s++;
97         if(!*s || *s == '#') return NULL;
98
99         // skip tailing spaces
100         int c = strlen(s) - 1;
101         while(c >= 0 && isspace(s[c])) {
102                 s[c] = '\0';
103                 c--;
104         }
105         if(c < 0) return NULL;
106         if(!*s) return NULL;
107         return s;
108 }
109
110 void *mymmap(const char *filename, unsigned long size, int flags)
111 {
112         int fd;
113         void *mem = NULL;
114
115         errno = 0;
116         fd = open(filename, O_RDWR|O_CREAT|O_NOATIME, 0664);
117         if(fd != -1) {
118                 if(lseek(fd, size, SEEK_SET) == (long)size) {
119                         if(write(fd, "", 1) == 1) {
120
121                                 if(ftruncate(fd, size))
122                                         error("Cannot truncate file '%s' to size %ld. Will use the larger file.", filename, size);
123
124                                 mem = mmap(NULL, size, PROT_READ|PROT_WRITE, flags, fd, 0);
125                                 if(mem) {
126                                         if(madvise(mem, size, MADV_SEQUENTIAL|MADV_DONTFORK|MADV_WILLNEED) != 0)
127                                                 error("Cannot advise the kernel about the memory usage of file '%s'.", filename);
128                                 }
129                         }
130                         else error("Cannot write to file '%s' at position %ld.", filename, size);
131                 }
132                 else error("Cannot seek file '%s' to size %ld.", filename, size);
133
134                 close(fd);
135         }
136         else error("Cannot create/open file '%s'.", filename);
137
138         return mem;
139 }
140
141 int savememory(const char *filename, void *mem, unsigned long size)
142 {
143         char tmpfilename[FILENAME_MAX + 1];
144
145         snprintf(tmpfilename, FILENAME_MAX, "%s.%ld.tmp", filename, (long)getpid());
146
147         int fd = open(tmpfilename, O_RDWR|O_CREAT|O_NOATIME, 0664);
148         if(fd < 0) {
149                 error("Cannot create/open file '%s'.", filename);
150                 return -1;
151         }
152
153         if(write(fd, mem, size) != (long)size) {
154                 error("Cannot write to file '%s' %ld bytes.", filename, (long)size);
155                 close(fd);
156                 return -1;
157         }
158
159         close(fd);
160
161         int ret = 0;
162         if(rename(tmpfilename, filename)) {
163                 error("Cannot rename '%s' to '%s'", tmpfilename, filename);
164                 ret = -1;
165         }
166
167         return ret;
168 }
169
170 int fd_is_valid(int fd) {
171     return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
172 }
173
174 /*
175  ***************************************************************************
176  * Get number of clock ticks per second.
177  ***************************************************************************
178  */
179 unsigned int hz;
180
181 void get_HZ(void)
182 {
183         long ticks;
184
185         if ((ticks = sysconf(_SC_CLK_TCK)) == -1) {
186                 perror("sysconf");
187         }
188
189         hz = (unsigned int) ticks;
190 }
191
192 pid_t gettid(void)
193 {
194         return syscall(SYS_gettid);
195 }
196