On 12/18/06, Vlad Seryakov <[EMAIL PROTECTED]> wrote:
I tried to run this program, it crahses with all allocators on free when it was allocated in other thread. zippy does it as well, i amnot sure how Naviserver works then.
I don't think allocate in one thread, free in another is an unusual strategy. Googling around I see a lot of people doing it. There must be some bugs in your program. Here's one: At the end of MemThread() gPtr is checked and freed, but the gMutex is not held. This thread may have finished it's tight loop, but the other 3 threads could still be running. Also, the gPtr is not set to NULL after the free(), leading to a double free when the next thread checks it.
#include <tcl.h> #define MemAlloc ckalloc #define MemFree ckfree int nbuffer = 16384; int nloops = 50000; int nthreads = 4; int gAllocs = 0; void *gPtr = NULL; Tcl_Mutex gLock; void MemThread(void *arg) { int i,n; void *ptr = NULL; for (i = 0; i < nloops; ++i) { n = 1 + (int) (nbuffer * (rand() / (RAND_MAX + 1.0))); if (ptr != NULL) { MemFree(ptr); } ptr = MemAlloc(n); // Testing inter-thread alloc/free if (n % 5 == 0) { Tcl_MutexLock(&gLock); if (gPtr != NULL) { MemFree(gPtr); } gPtr = MemAlloc(n); gAllocs++; Tcl_MutexUnlock(&gLock); } } if (ptr != NULL) { MemFree(ptr); } if (gPtr != NULL) { MemFree(gPtr); } } void MemTime() { int i; Tcl_ThreadId *tids; tids = (Tcl_ThreadId *)malloc(sizeof(Tcl_ThreadId) * nthreads); for (i = 0; i < nthreads; ++i) { Tcl_CreateThread( &tids[i], MemThread, NULL, TCL_THREAD_STACK_DEFAULT, TCL_THREAD_JOINABLE); } for (i = 0; i < nthreads; ++i) { Tcl_JoinThread(tids[i], NULL); } } int main (int argc, char **argv) { MemTime(); }