| 214 | // Returns an error on failure or the previous value on success. |
| 215 | template<typename T> |
| 216 | Try<T> updateJemallocSetting(const char* name, const T& value) |
| 217 | { |
| 218 | #ifdef LIBPROCESS_ALLOW_JEMALLOC |
| 219 | if (!detectJemalloc()) { |
| 220 | return Error(JEMALLOC_NOT_DETECTED_MESSAGE); |
| 221 | } |
| 222 | |
| 223 | T previous; |
| 224 | size_t size = sizeof(previous); |
| 225 | int error = ::mallctl( |
| 226 | name, &previous, &size, const_cast<T*>(&value), sizeof(value)); |
| 227 | |
| 228 | if (error) { |
| 229 | return Error(strings::format( |
| 230 | "Couldn't write value %s for option %s: %s", |
| 231 | stringify(value), name, ::strerror(error)).get()); |
| 232 | } |
| 233 | |
| 234 | return previous; |
| 235 | #else |
| 236 | UNREACHABLE(); |
| 237 | #endif |
| 238 | } |
| 239 | |
| 240 | |
| 241 | // Sadly, we cannot just use `updateJemallocSetting()` and ignore the result, |