On 12/18/06, Vlad Seryakov <[EMAIL PROTECTED]> wrote:
Still, even without the last free and with mutex around it, it core dumps in free(gPtr) during the loop.
OK. Still doesn't mean your program is bug free :-) There's a lot of extra stuff going on in your example program that makes it hard to see what's going on. I simplified it to this: #include <tcl.h> #include <stdlib.h> #include <assert.h> #define MemAlloc ckalloc #define MemFree ckfree void *gPtr = NULL; /* Global pointer to memory. */ void Thread(void *arg) { assert(gPtr != NULL); MemFree(gPtr); gPtr = NULL; } int main (int argc, char **argv) { Tcl_ThreadId tid; int i; for (i = 0; i < 100000; ++i) { gPtr = MemAlloc(1024); assert(gPtr != NULL); Tcl_CreateThread(&tid, Thread, NULL, TCL_THREAD_STACK_DEFAULT, TCL_THREAD_JOINABLE); Tcl_JoinThread(tid, NULL); assert(gPtr == NULL); } } Works for me. I say you can allocate memory in one thread and free it in another. Let me know what the bug turns out to be..!
Stephen Deasey wrote: > 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(); >> } > > ------------------------------------------------------------------------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the chance to share your > opinions on IT & business topics through brief surveys - and earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > _______________________________________________ > naviserver-devel mailing list > naviserver-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/naviserver-devel > -- Vlad Seryakov 571 262-8608 office [EMAIL PROTECTED] http://www.crystalballinc.com/vlad/ ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ naviserver-devel mailing list naviserver-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/naviserver-devel