]> arthur.barton.de Git - netdata.git/blobdiff - src/common.c
handle usleep() on systems that do not accept more than 999999 usec; implement altern...
[netdata.git] / src / common.c
index c67d8125ed041087b5af031e317f37a47840b6fd..02d37ab675ccd8a8c7dba1a12e8f0bcfb9efeed2 100644 (file)
@@ -10,7 +10,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <sys/mman.h>
-
+#include <time.h>
 
 #include "log.h"
 #include "common.h"
@@ -27,6 +27,51 @@ unsigned long long timems(void) {
        return now.tv_sec * 1000000ULL + now.tv_usec;
 }
 
+int usecsleep(unsigned long long usec) {
+
+#ifdef NETDATA_WITH_NANOSLEEP
+       // we expect microseconds (1.000.000 per second)
+       // but timespec is nanoseconds (1.000.000.000 per second)
+       struct timespec req = { .tv_sec = usec / 1000000, .tv_nsec = (usec % 1000000) * 1000 }, rem;
+
+       while(nanosleep(&req, &rem) == -1) {
+               error("nanosleep() failed for %llu microseconds.", usec);
+
+               if(likely(errno == EINTR)) {
+                       req.tv_sec = rem.tv_sec;
+                       req.tv_nsec = rem.tv_nsec;
+               }
+               else {
+                       error("Cannot nanosleep() for %llu microseconds.", usec);
+                       break;
+               }
+       }
+
+       return 0;
+#else
+       int ret = usleep(usec);
+       if(unlikely(ret == -1 && errno == EINVAL)) {
+               // on certain systems, usec has to be up to 999999
+               if(usec > 999999) {
+                       int counter = usec / 999999;
+                       while(counter--)
+                               usleep(999999);
+
+                       usleep(usec % 999999);
+               }
+               else {
+                       error("Cannot usleep() for %llu microseconds.", usec);
+                       return ret;
+               }
+       }
+
+       if(ret != 0)
+               error("usleep() failed for %llu microseconds.", usec);
+
+       return ret;
+#endif
+}
+
 unsigned char netdata_map_chart_names[256] = {
                [0] = '\0', //
                [1] = '_', //
@@ -682,16 +727,16 @@ void *mymmap(const char *filename, size_t size, int flags, int ksm)
        errno = 0;
        fd = open(filename, O_RDWR|O_CREAT|O_NOATIME, 0664);
        if(fd != -1) {
-               if(lseek(fd, size, SEEK_SET) == (long)size) {
+               if(lseek(fd, size, SEEK_SET) == (off_t)size) {
                        if(write(fd, "", 1) == 1) {
                                if(ftruncate(fd, size))
-                                       error("Cannot truncate file '%s' to size %ld. Will use the larger file.", filename, size);
+                                       error("Cannot truncate file '%s' to size %zu. Will use the larger file.", filename, size);
 
 #ifdef MADV_MERGEABLE
                                if(flags & MAP_SHARED || !enable_ksm || !ksm) {
 #endif
                                        mem = mmap(NULL, size, PROT_READ|PROT_WRITE, flags, fd, 0);
-                                       if(mem) {
+                                       if(mem != MAP_FAILED) {
                                                int advise = MADV_SEQUENTIAL|MADV_DONTFORK;
                                                if(flags & MAP_SHARED) advise |= MADV_WILLNEED;
 
@@ -701,7 +746,9 @@ void *mymmap(const char *filename, size_t size, int flags, int ksm)
 #ifdef MADV_MERGEABLE
                                }
                                else {
-                                       mem = mmap(NULL, size, PROT_READ|PROT_WRITE, flags|MAP_ANONYMOUS, -1, 0);
+/*
+                                       // test - load the file into memory
+                                       mem = calloc(1, size);
                                        if(mem) {
                                                if(lseek(fd, 0, SEEK_SET) == 0) {
                                                        if(read(fd, mem, size) != (ssize_t)size)
@@ -709,6 +756,16 @@ void *mymmap(const char *filename, size_t size, int flags, int ksm)
                                                }
                                                else
                                                        error("Cannot seek to beginning of file '%s'.", filename);
+                                       }
+*/
+                                       mem = mmap(NULL, size, PROT_READ|PROT_WRITE, flags|MAP_ANONYMOUS, -1, 0);
+                                       if(mem != MAP_FAILED) {
+                                               if(lseek(fd, 0, SEEK_SET) == 0) {
+                                                       if(read(fd, mem, size) != (ssize_t)size)
+                                                               error("Cannot read from file '%s'", filename);
+                                               }
+                                               else
+                                                       error("Cannot seek to beginning of file '%s'.", filename);
 
                                                // don't use MADV_SEQUENTIAL|MADV_DONTFORK, they disable MADV_MERGEABLE
                                                if(madvise(mem, size, MADV_SEQUENTIAL|MADV_DONTFORK) != 0)
@@ -722,9 +779,9 @@ void *mymmap(const char *filename, size_t size, int flags, int ksm)
                                }
 #endif
                        }
-                       else error("Cannot write to file '%s' at position %ld.", filename, size);
+                       else error("Cannot write to file '%s' at position %zu.", filename, size);
                }
-               else error("Cannot seek file '%s' to size %ld.", filename, size);
+               else error("Cannot seek file '%s' to size %zu.", filename, size);
 
                close(fd);
        }
@@ -733,7 +790,7 @@ void *mymmap(const char *filename, size_t size, int flags, int ksm)
        return mem;
 }
 
-int savememory(const char *filename, void *mem, unsigned long size)
+int savememory(const char *filename, void *mem, size_t size)
 {
        char tmpfilename[FILENAME_MAX + 1];
 
@@ -745,7 +802,7 @@ int savememory(const char *filename, void *mem, unsigned long size)
                return -1;
        }
 
-       if(write(fd, mem, size) != (long)size) {
+       if(write(fd, mem, size) != (ssize_t)size) {
                error("Cannot write to file '%s' %ld bytes.", filename, (long)size);
                close(fd);
                return -1;
@@ -753,13 +810,12 @@ int savememory(const char *filename, void *mem, unsigned long size)
 
        close(fd);
 
-       int ret = 0;
        if(rename(tmpfilename, filename)) {
                error("Cannot rename '%s' to '%s'", tmpfilename, filename);
-               ret = -1;
+               return -1;
        }
 
-       return ret;
+       return 0;
 }
 
 int fd_is_valid(int fd) {
@@ -840,6 +896,8 @@ int snprintfz(char *dst, size_t n, const char *fmt, ...) {
        va_list args;
 
        va_start(args, fmt);
-       return vsnprintfz(dst, n, fmt, args);
+       int ret = vsnprintfz(dst, n, fmt, args);
        va_end(args);
+
+       return ret;
 }