> The problem is that when you call swapcontext() to switch the user-thread
> running on a kernel-thread, the NSAutoreleasePool stack is not swapped out.
> It remains rooted in thread-local storage. As a result, serious problems
> result. Let me give an example.
> 
> - (void)doStuff {
>  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
>  // do some stuff that calls swapcontext()
>  [pool drain];
> }

That doesn't work correctly with regular threads, pthreads, GCD or any other 
concurrency pattern.  The autorelease pool needs to be pushed and popped within 
the context of the asynchronous subtask.  The original thread of control needs 
its own pool, and you cannot rely upon autorelease to keep objects alive across 
asynchronous task boundaries.  You will need to be careful to ensure that the 
sending thread transfers ownership of a retain to the receiving thread which 
releases it.  Not autoreleases it.

It would need to conceptually be:

- (void)doStuff {
 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
// some stuff Before
[pool drain];

 // do some stuff that calls swapcontext(), and has it's only scoped 
autorelease pool

pool = [[NSAutoreleasePool alloc] init];
// some more stuff After
 [pool drain];
}

Object you want to keep alive across drains should be retained and later 
released.  

Autorelease pools are cheap.  Make more.  A lot more.  If you have places where 
that doesn't work with coroutines then don't leak important objects into 
autorelease pools.  Either don't create them that way, or retain them again, 
and release them after you can verify the autorelease pool was destroyed.

> Using kernel-level
> threads is, naturally, simpler, but due to the cost of kernel-level context
> switches, they don't scale well. (You just can't run 500 threads at once
> very well.) User-space threads require more programmer attention, certainly,
> but also allow certain programming models that can't be done otherwise. For
> example, they can be used for coroutines, cooperative threading, or all
> sorts of esoteric-yet-sometimes-useful effects.

That's true, but I'm not sure it's relevant for the "I wish I had 500 threads 
to handle this web server communication" task.  There are a lot of different 
ways to organize the tasks as inert data that can be processed cooperatively by 
a set of active worker threads.

The mental model of each task being its own little world and a thread is nice, 
but it's also artificial.  You can reorganize the relationship between active 
workers and command data.  Nothing is stopping you from that except a 
preconception that tasks and threads must have a 1:1 correspondence.

You could create a finite state machine to process a queue of the tasks as 
inert command structures and firing up 8 of those finite state machines on 
their own dedicated normal threads on your Mac Pro.  The semantic effect will 
be similar to user threads, yet you won't run into all these crazy problems.  
Destroying thread local storage and its affect on autorelease pools is just 
your first problem stuffing Cocoa into swapcontext()

This point from Mike is particularly apt:

> Since you mention in another message that this is portable,
> cross-platform code, why do you need to call Cocoa from the user-level
> threads at all? Separate your code into cross-platform code that does
> this swapcontext stuff, and Mac-specific code that doesn't, and you
> should be good.

You could use a sandboxing approach like Safari and have your cross platform 
code run in a background CLI and talk to the GUI app over IPC.  No Cocoa in the 
CLI and no user threads in the GUI app.  

Pretty sure, though, you'd get better performance conceptually restructuring 
the task / actor relationship.  The cooperative finite state machine approach 
along with a prioritized queue can provide soft real time performance with 
thousands of task objects ... every second.  That's basically what some older 
MMORPG servers did before people went wild with distributed computing.

- Ben

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to