utils.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2010, 2012-2014 Université de Bordeaux 1
  4. * Copyright (C) 2010, 2011, 2012, 2013, 2014 Centre National de la Recherche Scientifique
  5. *
  6. * StarPU is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published by
  8. * the Free Software Foundation; either version 2.1 of the License, or (at
  9. * your option) any later version.
  10. *
  11. * StarPU is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  14. *
  15. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  16. */
  17. #include <starpu.h>
  18. #include <common/config.h>
  19. #include <common/utils.h>
  20. #include <errno.h>
  21. #ifdef HAVE_UNISTD_H
  22. #include <unistd.h>
  23. #endif
  24. #include <fcntl.h>
  25. #if defined(_WIN32) && !defined(__CYGWIN__)
  26. #include <io.h>
  27. #include <sys/locking.h>
  28. #define mkdir(path, mode) mkdir(path)
  29. #if !defined(__MINGW32__)
  30. #define ftruncate(fd, length) _chsize(fd, length)
  31. #endif
  32. #endif
  33. #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
  34. #include <direct.h>
  35. static char * dirname(char * path)
  36. {
  37. char drive[_MAX_DRIVE];
  38. char dir[_MAX_DIR];
  39. /* Remove trailing slash */
  40. while (strlen(path) > 0 && (*(path+strlen(path)-1) == '/' || *(path+strlen(path)-1) == '\\'))
  41. *(path+strlen(path)-1) = '\0';
  42. _splitpath(path, drive, dir, NULL, NULL);
  43. _makepath(path, drive, dir, NULL, NULL);
  44. return path;
  45. }
  46. #else
  47. #include <libgen.h>
  48. #endif
  49. /* Function with behaviour like `mkdir -p'. This function was adapted from
  50. * http://niallohiggins.com/2009/01/08/mkpath-mkdir-p-alike-in-c-for-unix/ */
  51. int _starpu_mkpath(const char *s, mode_t mode)
  52. {
  53. int olderrno;
  54. char *q, *r = NULL, *path = NULL, *up = NULL;
  55. int rv;
  56. rv = -1;
  57. if (strcmp(s, ".") == 0 || strcmp(s, "/") == 0
  58. #if defined(_WIN32)
  59. /* C:/ or C:\ */
  60. || (s[0] && s[1] == ':' && (s[2] == '/' || s[2] == '\\') && !s[3])
  61. #endif
  62. )
  63. return 0;
  64. if ((path = strdup(s)) == NULL)
  65. STARPU_ABORT();
  66. if ((q = strdup(s)) == NULL)
  67. STARPU_ABORT();
  68. if ((r = dirname(q)) == NULL)
  69. goto out;
  70. if ((up = strdup(r)) == NULL)
  71. STARPU_ABORT();
  72. if ((_starpu_mkpath(up, mode) == -1) && (errno != EEXIST))
  73. goto out;
  74. if ((mkdir(path, mode) == -1) && (errno != EEXIST))
  75. rv = -1;
  76. else
  77. rv = 0;
  78. out:
  79. olderrno = errno;
  80. if (up)
  81. free(up);
  82. free(q);
  83. free(path);
  84. errno = olderrno;
  85. return rv;
  86. }
  87. void _starpu_mkpath_and_check(const char *path, mode_t mode)
  88. {
  89. int ret;
  90. ret = _starpu_mkpath(path, mode);
  91. if (ret == -1)
  92. {
  93. if (errno != EEXIST)
  94. {
  95. fprintf(stderr,"Error making StarPU directory %s:\n", path);
  96. perror("mkdir");
  97. STARPU_ABORT();
  98. }
  99. /* make sure that it is actually a directory */
  100. struct stat sb;
  101. stat(path, &sb);
  102. if (!S_ISDIR(sb.st_mode))
  103. {
  104. fprintf(stderr,"Error: %s is not a directory:\n", path);
  105. STARPU_ABORT();
  106. }
  107. }
  108. }
  109. int _starpu_ftruncate(FILE *file)
  110. {
  111. return ftruncate(fileno(file), 0);
  112. }
  113. int _starpu_frdlock(FILE *file)
  114. {
  115. #if defined(_WIN32) && !defined(__CYGWIN__)
  116. int ret;
  117. do {
  118. ret = _locking(fileno(file), _LK_RLCK, 10);
  119. } while (ret == EDEADLOCK);
  120. return ret;
  121. #else
  122. struct flock lock = {
  123. .l_type = F_RDLCK,
  124. .l_whence = SEEK_SET,
  125. .l_start = 0,
  126. .l_len = 0
  127. };
  128. return fcntl(fileno(file), F_SETLKW, &lock);
  129. #endif
  130. }
  131. int _starpu_frdunlock(FILE *file)
  132. {
  133. #if defined(_WIN32) && !defined(__CYGWIN__)
  134. # ifndef _LK_UNLCK
  135. # define _LK_UNLCK _LK_UNLOCK
  136. # endif
  137. return _locking(fileno(file), _LK_UNLCK, 10);
  138. #else
  139. struct flock lock = {
  140. .l_type = F_UNLCK,
  141. .l_whence = SEEK_SET,
  142. .l_start = 0,
  143. .l_len = 0
  144. };
  145. return fcntl(fileno(file), F_SETLKW, &lock);
  146. #endif
  147. }
  148. int _starpu_fwrlock(FILE *file)
  149. {
  150. #if defined(_WIN32) && !defined(__CYGWIN__)
  151. int ret;
  152. do {
  153. ret = _locking(fileno(file), _LK_LOCK, 10);
  154. } while (ret == EDEADLOCK);
  155. return ret;
  156. #else
  157. struct flock lock = {
  158. .l_type = F_WRLCK,
  159. .l_whence = SEEK_SET,
  160. .l_start = 0,
  161. .l_len = 0
  162. };
  163. return fcntl(fileno(file), F_SETLKW, &lock);
  164. #endif
  165. }
  166. int _starpu_fwrunlock(FILE *file)
  167. {
  168. return _starpu_frdunlock(file);
  169. }
  170. int _starpu_check_mutex_deadlock(starpu_pthread_mutex_t *mutex)
  171. {
  172. int ret;
  173. ret = starpu_pthread_mutex_trylock(mutex);
  174. if (!ret)
  175. {
  176. STARPU_PTHREAD_MUTEX_UNLOCK(mutex);
  177. return 0;
  178. }
  179. if (ret == EBUSY)
  180. return 0;
  181. STARPU_ASSERT (ret != EDEADLK);
  182. return 1;
  183. }
  184. char *_starpu_get_home_path(void)
  185. {
  186. char *path = getenv("XDG_CACHE_HOME");
  187. if (!path)
  188. path = getenv("STARPU_HOME");
  189. if (!path)
  190. path = getenv("HOME");
  191. if (!path)
  192. path = getenv("USERPROFILE");
  193. if (!path) {
  194. static int warn;
  195. if (!warn) {
  196. warn = 1;
  197. _STARPU_DISP("couldn't find a $STARPU_HOME place to put .starpu data, using /tmp\n");
  198. }
  199. path = "/tmp";
  200. }
  201. return path;
  202. }
  203. void _starpu_gethostname(char *hostname, size_t size)
  204. {
  205. char *forced_hostname = getenv("STARPU_HOSTNAME");
  206. if (forced_hostname && forced_hostname[0])
  207. {
  208. snprintf(hostname, size-1, "%s", forced_hostname);
  209. hostname[size-1] = 0;
  210. }
  211. else
  212. {
  213. char *c;
  214. gethostname(hostname, size-1);
  215. hostname[size-1] = 0;
  216. c = strchr(hostname, '.');
  217. if (c)
  218. *c = 0;
  219. }
  220. }
  221. void _starpu_sleep(struct timespec ts)
  222. {
  223. #ifdef STARPU_SIMGRID
  224. MSG_process_sleep(ts.tv_sec + ts.tv_nsec / 1000000000.);
  225. #elif defined(STARPU_HAVE_WINDOWS)
  226. Sleep((ts.tv_sec * 1000) + (ts.tv_nsec / 1000000));
  227. #else
  228. struct timespec req, rem;
  229. req = ts;
  230. while (nanosleep(&req, &rem))
  231. req = rem;
  232. #endif
  233. }