sync_tester.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #include <errno.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include <sys/stat.h>
  5. #include <sys/types.h>
  6. #include <sys/mman.h>
  7. #include <sys/types.h>
  8. #define _GNU_SOURCE /* See feature_test_macros(7) */
  9. #define __USE_GNU
  10. #include <fcntl.h>
  11. #include <unistd.h>
  12. void test_sync_file_range(char *output, char *text, size_t length)
  13. {
  14. int fd = open (output, O_WRONLY | O_CREAT | O_APPEND, 0660);
  15. if (fd < 0 ) {
  16. perror("Cannot get page size");
  17. return;
  18. }
  19. int i;
  20. size_t offset = 0;
  21. for ( i = 0 ; i < 10000; i++ ) {
  22. write(fd, text, length);
  23. sync_file_range(fd, offset, length, SYNC_FILE_RANGE_WRITE);
  24. offset += length;
  25. }
  26. close(fd);
  27. sleep(5);
  28. }
  29. // test based on IBM example https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_71/apis/msync.htm
  30. void test_msync(char *output, char *text, size_t length)
  31. {
  32. int pagesize = sysconf(_SC_PAGE_SIZE);
  33. if (pagesize < 0) {
  34. perror("Cannot get page size");
  35. return;
  36. }
  37. int fd = open(output, (O_CREAT | O_TRUNC | O_RDWR), (S_IRWXU | S_IRWXG | S_IRWXO));
  38. if (fd < 0 ) {
  39. perror("Cannot open file");
  40. return;
  41. }
  42. off_t lastoffset = lseek( fd, pagesize, SEEK_SET);
  43. ssize_t written = write(fd, " ", 1);
  44. if ( written != 1 ) {
  45. perror("Write error. ");
  46. close(fd);
  47. return;
  48. }
  49. off_t my_offset = 0;
  50. void *address = mmap(NULL, pagesize, PROT_WRITE, MAP_SHARED, fd, my_offset);
  51. if ( address == MAP_FAILED ) {
  52. perror("Map error. ");
  53. close(fd);
  54. return;
  55. }
  56. (void) strcpy( (char*) address, text);
  57. if ( msync( address, pagesize, MS_SYNC) < 0 ) {
  58. perror("msync failed with error:");
  59. }
  60. close(fd);
  61. sleep(5);
  62. }
  63. void test_synchronization(char *output, char *text, size_t length, int (*fcnt)(int))
  64. {
  65. int fd = open (output, O_WRONLY | O_CREAT | O_APPEND, 0660);
  66. if (fd < 0 ) {
  67. perror("Cannot get page size");
  68. return;
  69. }
  70. int i;
  71. for ( i = 0 ; i < 10000; i++ )
  72. write(fd, text, length);
  73. fcnt(fd);
  74. close(fd);
  75. sleep(5);
  76. }
  77. void remove_files(char **files) {
  78. size_t i = 0;
  79. while (files[i]) {
  80. unlink(files[i]);
  81. i++;
  82. }
  83. }
  84. int main()
  85. {
  86. char *default_text = { "This is a simple example to test a PR. The sleep is used to create different peaks on charts.\n" };
  87. char *files[] = { "fsync.txt", "fdatasync.txt", "syncfs.txt", "msync.txt", "sync_file_range.txt", NULL };
  88. size_t length = strlen(default_text);
  89. test_synchronization(files[0], default_text, length, fsync);
  90. test_synchronization(files[1], default_text, length, fdatasync);
  91. test_synchronization(files[2], default_text, length, syncfs);
  92. test_msync(files[3], default_text, length);
  93. test_sync_file_range(files[4], default_text, length);
  94. sync();
  95. remove_files(files);
  96. return 0;
  97. }