Returns the **highest** address of the calling pthread's stack and its total size, matching brpc's `StackStorage::bottom` convention (see comment in bthread/stack.h: "Assume stack grows upwards"). Note that on Linux `pthread_attr_getstack(3)` returns the lowest address of the region, so we have to translate it; on macOS `pthread_get_stackaddr_np(3)` already returns the stack base (highest address)
| 254 | // we have to translate it; on macOS `pthread_get_stackaddr_np(3)` already |
| 255 | // returns the stack base (highest address), so we use it as-is. |
| 256 | int PthreadAttrGetStack(void*& stack_addr, size_t& stack_size) { |
| 257 | #if defined(OS_MACOSX) |
| 258 | stack_addr = pthread_get_stackaddr_np(pthread_self()); |
| 259 | stack_size = pthread_get_stacksize_np(pthread_self()); |
| 260 | return 0; |
| 261 | #else |
| 262 | pthread_attr_t attr; |
| 263 | int rc = pthread_getattr_np(pthread_self(), &attr); |
| 264 | if (0 != rc) { |
| 265 | LOG(ERROR) << "Fail to get pthread attributes: " << berror(rc); |
| 266 | return rc; |
| 267 | } |
| 268 | void* stack_lowest = NULL; |
| 269 | rc = pthread_attr_getstack(&attr, &stack_lowest, &stack_size); |
| 270 | if (0 != rc) { |
| 271 | LOG(ERROR) << "Fail to get pthread stack: " << berror(rc); |
| 272 | } else { |
| 273 | // Translate lowest -> highest to match StackStorage::bottom. |
| 274 | stack_addr = (char*)stack_lowest + stack_size; |
| 275 | } |
| 276 | pthread_attr_destroy(&attr); |
| 277 | return rc; |
| 278 | #endif // OS_MACOSX |
| 279 | } |
| 280 | #endif // BUTIL_USE_ASAN |
| 281 | |
| 282 | int TaskGroup::init(size_t runqueue_capacity) { |