void Ns_ThreadCreate(Ns_ThreadProc *proc, void *arg, long stacksize, Ns_Thread *resultPtr) { ThreadArg *argPtr; /* * Determine the stack size and add the guard. */ if (stacksize <= 0) { stacksize = Ns_ThreadStackSize(0); } if (stacksize < stackmin) { stacksize = stackmin; } /* * Create the thread. */ argPtr = ns_malloc(sizeof(ThreadArg)); argPtr->proc = proc; argPtr->arg = arg; argPtr->flags = resultPtr ? 0 : FLAG_DETACHED; strcpy(argPtr->parent, Ns_ThreadGetName()); NsCreateThread(argPtr, stacksize, resultPtr); }
void NsConfUpdate(void) { int stacksize; Ns_DString ds; Ns_DStringInit(&ds); Ns_HomePath(&ds, "modules", "tcl", NULL); nsconf.tcl.sharedlibrary = Ns_DStringExport(&ds); nsconf.shutdowntimeout = NsParamInt("shutdowntimeout", SHUTDOWNTIMEOUT); nsconf.sched.maxelapsed = NsParamInt("schedmaxelapsed", SCHED_MAXELAPSED); nsconf.backlog = NsParamInt("listenbacklog", LISTEN_BACKLOG); nsconf.http.major = (unsigned) NsParamInt("httpmajor", HTTP_MAJOR); nsconf.http.minor = (unsigned) NsParamInt("httpmajor", HTTP_MINOR); nsconf.tcl.lockoninit = NsParamBool("tclinitlock", TCL_INITLCK); if (!Ns_ConfigGetInt(NS_CONFIG_THREADS, "stacksize", &stacksize)) { stacksize = NsParamInt("stacksize", THREAD_STACKSIZE); } Ns_ThreadStackSize(stacksize); NsLogConf(); NsEnableDNSCache(); NsUpdateEncodings(); NsUpdateMimeTypes(); }
int main(int argc, char *argv[]) { int i, code; Ns_Thread threads[10]; Ns_Thread self, dumper; void *arg; char *p; #if PTHREAD_TEST pthread_t tids[10]; #endif NsThreads_LibInit(); Ns_ThreadSetName("-main-"); /* * Jump directly to memory test if requested. */ for (i = 1; i < argc; ++i) { p = argv[i]; switch (*p) { case 'n': break; case 'm': nthreads = atoi(p + 1); goto mem; break; } } Ns_ThreadCreate(DetachedThread, NULL, 0, NULL); Ns_ThreadCreate(DumperThread, NULL, 0, &dumper); Ns_MutexSetName(&lock, "startlock"); Ns_MutexSetName(&dlock, "dumplock"); Ns_MutexSetName(&mlock, "msglock"); Ns_MutexSetName(&block, "busylock"); Ns_ThreadStackSize(81920); Ns_SemaInit(&sema, 3); Msg("sema initialized to 3"); atexit(AtExit); Msg("pid = %d", getpid()); Ns_TlsAlloc(&key, TlsLogArg); for (i = 0; i < 10; ++i) { Msg("starting work thread %d", i); Ns_ThreadCreate(WorkThread, (void *) i, 0, &threads[i]); } sleep(1); /* Ns_CondSignal(&cond); */ Ns_SemaPost(&sema, 10); Msg("sema post 10"); Ns_RWLockWrLock(&rwlock); Msg("rwlock write locked (main thread)"); sleep(1); Ns_RWLockUnlock(&rwlock); Msg("rwlock write unlocked (main thread)"); for (i = 0; i < 10; ++i) { Msg("waiting for thread %d to exit", i); Ns_ThreadJoin(&threads[i], (void **) &code); Msg("thread %d exited - code: %d", i, code); } #if PTHREAD_TEST for (i = 0; i < 10; ++i) { pthread_create(&tids[i], NULL, Pthread, (void *) i); printf("pthread: create %d = %d\n", i, (int) tids[i]); Ns_ThreadYield(); } Ns_MutexLock(&plock); pgo = 1; Ns_MutexUnlock(&plock); Ns_CondBroadcast(&pcond); for (i = 0; i < 10; ++i) { pthread_join(tids[i], &arg); printf("pthread: join %d = %d\n", i, (int) arg); } #endif Ns_ThreadSelf(&self); Ns_MutexLock(&dlock); dstop = 1; Ns_CondSignal(&dcond); Ns_MutexUnlock(&dlock); Ns_ThreadJoin(&dumper, NULL); Msg("threads joined"); for (i = 0; i < 10; ++i) { Ns_ThreadCreate(CheckStackThread, NULL, 8192*(i+1), &threads[i]); } for (i = 0; i < 10; ++i) { Ns_ThreadJoin(&threads[i], &arg); printf("check stack %d = %d\n", i, (int) arg); } /*Ns_ThreadEnum(DumpThreads, NULL);*/ /*Ns_MutexEnum(DumpLocks, NULL);*/ mem: MemTime(0); MemTime(1); return 0; }