Send save data to parent. */
| 68 | |
| 69 | /* Send save data to parent. */ |
| 70 | void sendChildInfoGeneric(childInfoType info_type, size_t keys, double progress, char *pname) { |
| 71 | if (server.child_info_pipe[1] == -1) return; |
| 72 | |
| 73 | static monotime cow_updated = 0; |
| 74 | static uint64_t cow_update_cost = 0; |
| 75 | static size_t cow = 0; |
| 76 | |
| 77 | child_info_data data = {0}; /* zero everything, including padding to satisfy valgrind */ |
| 78 | |
| 79 | /* When called to report current info, we need to throttle down CoW updates as they |
| 80 | * can be very expensive. To do that, we measure the time it takes to get a reading |
| 81 | * and schedule the next reading to happen not before time*CHILD_COW_COST_FACTOR |
| 82 | * passes. */ |
| 83 | |
| 84 | monotime now = getMonotonicUs(); |
| 85 | if (info_type != CHILD_INFO_TYPE_CURRENT_INFO || |
| 86 | !cow_updated || |
| 87 | now - cow_updated > cow_update_cost * CHILD_COW_DUTY_CYCLE) |
| 88 | { |
| 89 | cow = zmalloc_get_private_dirty(-1); |
| 90 | cow_updated = getMonotonicUs(); |
| 91 | cow_update_cost = cow_updated - now; |
| 92 | |
| 93 | if (cow) { |
| 94 | serverLog((info_type == CHILD_INFO_TYPE_CURRENT_INFO) ? LL_VERBOSE : LL_NOTICE, |
| 95 | "%s: %zu MB of memory used by copy-on-write", |
| 96 | pname, cow / (1024 * 1024)); |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | data.information_type = info_type; |
| 101 | data.keys = keys; |
| 102 | data.cow = cow; |
| 103 | data.cow_updated = cow_updated; |
| 104 | data.progress = progress; |
| 105 | |
| 106 | ssize_t wlen = sizeof(data); |
| 107 | |
| 108 | if (write(server.child_info_pipe[1], &data, wlen) != wlen) { |
| 109 | /* Nothing to do on error, this will be detected by the other side. */ |
| 110 | } |
| 111 | } |
| 112 | |
| 113 | /* Update Child info. */ |
| 114 | void updateChildInfo(childInfoType information_type, size_t cow, monotime cow_updated, size_t keys, double progress) { |
no test coverage detected