On 12/18/06, Zoran Vasiljevic <[EMAIL PROTECTED]> wrote:

On 18.12.2006, at 19:57, Stephen Deasey wrote:
>
>
> One thing I wonder about this is, how do requests average out across
> all threads? If you set the conn threads to exit after 10,000
> requests, will they all quit at roughly the same time causing an
> extreme load on the server?  Also, this is only an option for conn
> threads. With scheduled proc threads, job threads etc. you get
> nothing.
>

Well, if they all start to exit at the same time, they will
serialize at the point where per-thread cache is pushed to
the shared pool.

I was worried more about things like all the Tcl procs needing to be
recompiled in the new interp for the thread, and all the other stuff
which is cached.  If threads exit regularly, say after 10,000
requests, and the requests average out over all threads, then your
site will regularly go down, effectively. It would be nice if we could
make sure the thread exits were spread out.

Anyway...

> I think some people are experiencing fragmentation problems with
> ptmalloc -- the Squid and OpenLDAP guys, for example.  There's also
> the malloc-in-one-thread, free-in-another problem, which if your
> threads don't exit is basically a leak.

Really a leak? Why? Wouln't that depend on the implementation?

Yes, and I thought that was the case with Linux ptmalloc, but maybe I
got it wrong or this is old news...

This program allocates memory in a worker thread and frees it in the
main thread. If all free()'s put memory into a thread-local cache then
you would expect this program to bloat, but it doesn't, so I guess
it's not a problem (at least not on Fedora Core 5).


#include <tcl.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>


#define MemAlloc malloc
#define MemFree  free


void *gPtr = NULL;

static void Thread(void *arg);
static void PrintMemUsage(const char *msg);


int
main (int argc, char **argv)
{
   Tcl_ThreadId tid;
   int          i;

   PrintMemUsage("start");

   for (i = 0; i < 100000; ++i) {

       Tcl_CreateThread(&tid, Thread, NULL,
                        TCL_THREAD_STACK_DEFAULT, TCL_THREAD_JOINABLE);
       Tcl_JoinThread(tid, NULL);

       MemFree(gPtr);
       gPtr = NULL;
   }

   PrintMemUsage("stop");
}

static void
Thread(void *arg)
{
   assert(gPtr == NULL);
   gPtr = MemAlloc(1024);
   assert(gPtr != NULL);
}

static void
PrintMemUsage(const char *msg)
{
   FILE *f;
   int   m;

   f = fopen("/proc/self/statm", "r");
   if (f == NULL) {
       perror("fopen failed: ");
       exit(-1);
   }
   if (fscanf(f, "%d", &m) != 1) {
       perror("fscanf failed: ");
       exit(-1);
   }
   fclose(f);

   printf("%s: %d\n", msg, m);
}

Reply via email to