]> 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 195bfc84df7b2942b9abb904b14dbd7f85a88e60..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] = '_', //
@@ -685,7 +730,7 @@ void *mymmap(const char *filename, size_t size, int flags, int ksm)
                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) {
@@ -734,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);
        }
@@ -851,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;
 }