I have some recursive functions of unbounded depth (depending on user input equations), so I need to check remaining stack space on the fly. In C with pthreads this is straightforward:
// Mac OS X 10.5's pthread_get_stackaddr_np now uses a global lock which introduces contention to StackSpace serializing RunPCode so cache the stack top in thread local storage
const int kStackSpaceRoomForError = 32*1024;
Bool OurStackSpace(int size)
{
char* stackLimit = static_cast<char*>(pthread_getspecific(gStackLimit));
char c = 0;
if (stackLimit == NULL) {
Assert(StackGrowsUpwards(&c));
stackLimit = static_cast<char*>(pthread_get_stackaddr_np(pthread_self())) - pthread_get_stacksize_np(pthread_self());
pthread_setspecific(gStackLimit, stackLimit);
}
long spaceRemaining = &c - stackLimit;
return (spaceRemaining > size + kStackSpaceRoomForError);
}
Is there a better or more Swift-y approach or is this an occasion to call out to C?
(And as a bonus question, since I haven't yet studied the new Swift Concurrency runtime model, will that change what is necessary for this?)
eskimo
(Quinn “The Eskimo!”)
2
Is there a better or more Swift-y approach or is this an occasion to
call out to C?
Honestly, I’d call out to C for this. The PThread API is available to Swift but you end up on much squishier ground. For example, your &c construct is guaranteed to yield a stack address in C but that’s not the case in Swift [1]. That’s unlikely to cause problems in practice, but if you have the option to call C and you already have a C implementation, what’s the downside?
Share and Enjoy
Quinn “The Eskimo!” @ DTS @ Apple
[1] See The Peril of the Ampersand for more on this.
1 Like