qemu/linux-user
Nathan Froyd 48e15fc2de linux-user: fix memory leaks with NPTL emulation
Running programs that create large numbers of threads, such as this
snippet from libstdc++'s pthread7-rope.cc:

  const int max_thread_count = 4;
  const int max_loop_count = 10000;
  ...
  for (int j = 0; j < max_loop_count; j++)
    {
      ...
      for (int i = 0; i < max_thread_count; i++)
	pthread_create (&tid[i], NULL, thread_main, 0);

      for (int i = 0; i < max_thread_count; i++)
	pthread_join (tid[i], NULL);
    }

in user-mode emulation will quickly run out of memory.  This is caused
by a failure to free memory in do_syscall prior to thread exit:

          /* TODO: Free CPU state.  */
          pthread_exit(NULL);

The first step in fixing this is to make all TaskStates used by QEMU
dynamically allocated.  The TaskState used by the initial thread was
not, as it was allocated on main's stack.  So fix that, free the
cpu_env, free the TaskState, and we're home free, right?

Not exactly.  When we create a thread, we do:

        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
        ...
        new_stack = ts->stack;
        ...
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);

If we blindly free the TaskState, then, we yank the current (host)
thread's stack out from underneath it while it still has things to do,
like calling pthread_exit.  That causes problems, as you might expect.

The solution adopted here is to let the C library allocate the thread's
stack (so the C library can properly clean it up at pthread_exit) and
provide a hint that we want NEW_STACK_SIZE bytes of stack.

With those two changes, we're done, right?  Well, almost.  You see,
we're creating all these host threads and their parent threads never
bother to check that their children are finished.  There's no good place
for the parent threads to do so.  Therefore, we need to create the
threads in a detached state so the parent thread doesn't have to call
pthread_join on the child to release the child's resources; the child
does so automatically.

With those three major changes, we can comfortably run programs like the
above without exhausting memory.  We do need to delete 'stack' from the
TaskState structure.

Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Riku Voipio <riku.voipio@nokia.com>
2010-12-03 15:09:38 +02:00
..
alpha alpha-linux-user: Implement signals. 2010-02-28 17:54:52 +01:00
arm linux-user: Add the syscall id for pselect6 on ARM 2010-03-26 20:48:30 +01:00
cris Revert "Get rid of _t suffix" 2009-10-01 16:12:16 -05:00
i386 Revert "Get rid of _t suffix" 2009-10-01 16:12:16 -05:00
m68k Revert "Get rid of _t suffix" 2009-10-01 16:12:16 -05:00
microblaze Revert "Get rid of _t suffix" 2009-10-01 16:12:16 -05:00
mips Revert "Get rid of _t suffix" 2009-10-01 16:12:16 -05:00
mips64 Revert "Get rid of _t suffix" 2009-10-01 16:12:16 -05:00
mipsn32 Revert "Get rid of _t suffix" 2009-10-01 16:12:16 -05:00
ppc Revert "Get rid of _t suffix" 2009-10-01 16:12:16 -05:00
sh4 Revert "Get rid of _t suffix" 2009-10-01 16:12:16 -05:00
sparc Revert "Get rid of _t suffix" 2009-10-01 16:12:16 -05:00
sparc64 Revert "Get rid of _t suffix" 2009-10-01 16:12:16 -05:00
x86_64 Revert "Get rid of _t suffix" 2009-10-01 16:12:16 -05:00
cpu-uname.c linux-user: adapt uname machine to emulated CPU 2010-02-06 17:19:43 +01:00
cpu-uname.h linux-user: adapt uname machine to emulated CPU 2010-02-06 17:19:43 +01:00
elfload.c linux-user: Protect against allocation failure in load_symbols. 2010-07-29 20:54:35 +04:00
errno_defs.h Remove unnecessary trailing newlines 2008-12-13 09:32:43 +00:00
flat.h Support for 32 bit ABI on 64 bit targets (only enabled Sparc64) 2007-10-14 16:27:31 +00:00
flatload.c linux-user: improve flatload error checking 2010-09-18 05:53:14 +00:00
ioctls.h linux-user: KD/VT/FB ioctls 2009-10-17 11:38:00 +03:00
linux_loop.h Fix build failure with old kernel headers (loop.h is incompatible with 2008-05-23 16:06:43 +00:00
linuxload.c linux-user: Reduce lseek+reads while loading elf files. 2010-07-29 08:32:28 +02:00
m68k-sim.c linux-user: Fix typo m86k -> m68k 2010-10-05 13:53:56 -05:00
main.c linux-user: fix memory leaks with NPTL emulation 2010-12-03 15:09:38 +02:00
mmap.c linux-user: mmap_reserve() not controlled by RESERVED_VA 2010-12-03 15:09:38 +02:00
qemu-types.h linux-user: Move abi_* typedefs into qemu-types.h 2008-12-08 18:12:04 +00:00
qemu.h linux-user: fix memory leaks with NPTL emulation 2010-12-03 15:09:38 +02:00
signal.c microblaze: target-ify target_ucontext 2010-11-23 10:04:30 +01:00
socket.h Various linux-user structures and definitions fixes for PowerPC targets. 2007-12-10 08:24:59 +00:00
strace.c Strace mprotect flags. 2010-06-16 13:03:51 +01:00
strace.list linux-user: strace now handles guest strings correctly [v2] 2009-06-16 16:56:28 +03:00
syscall.c linux-user: fix memory leaks with NPTL emulation 2010-12-03 15:09:38 +02:00
syscall_defs.h microblaze: Fix the target version of stat64 struct 2010-08-09 10:13:33 +02:00
syscall_types.h linux-user: KD/VT/FB ioctls 2009-10-17 11:38:00 +03:00
uaccess.c Fix missing strnlen problems 2009-07-01 18:24:44 +00:00
vm86.c Update to a hopefully more future proof FSF address 2009-07-16 20:47:01 +00:00