|
pthreads patches: msg#00163lib.uclibc.general
Hello! We are using pthreads quite heavily and have experienced some races and have therefore made some changes to the code in order for our application to work correctly. I'm a little curious why nobody else have experienced problems, we surely can't be the only one using pthreads and uClinux 2.0.38? In the patches below is also some code changing the system call poll to select as the poll call isn't supported in 2.0 kernel. Would it be possible to introduce some means to indicate which kernel version the uClibc is to be used against, I believe this is necessary as the kernels seems to disagree on the system calls supported (and other stuff)? The patches are made against manager.c and pthread.c in 0.9.15 but the latest version in CVS seems to be the same as in 0.9.15. Best regards, /Arne Jonsson -- Arne Jonsson i3 micro technology AB Phone:+46-8-506 388 00 Fax: +46-8-506 388 75*** libpthread/linuxthreads/manager.c.submit_to_uclibc.org Mon Oct 21 16:50:22 2002 --- libpthread/linuxthreads/manager.c.org Wed Feb 20 10:18:44 2002 *************** *** 14,22 **** /* The "thread manager" thread: manages creation and termination of threads */ - /* poll is not supported in kernel <= 2.0, therefore substituted using select */ - //#define USE_SELECT - /* mods for uClibc: getpwd and getpagesize are the syscalls */ #define __getpid getpid #define __getpagesize getpagesize --- 14,19 ---- *************** *** 107,118 **** int __pthread_manager(void *arg) { int reqfd = (int) (long int) arg; - #ifndef USE_SELECT struct pollfd ufd; - #else - struct timeval tv; - fd_set fd; - #endif sigset_t mask; int n; struct pthread_request request; --- 104,110 ---- *************** *** 134,156 **** /* Synchronize debugging of the thread manager */ n = __libc_read(reqfd, (char *)&request, sizeof(request)); ASSERT(n == sizeof(request) && request.req_kind == REQ_DEBUG); - #ifndef USE_SELECT ufd.fd = reqfd; ufd.events = POLLIN; - #endif /* Enter server loop */ while(1) { - #ifndef USE_SELECT PDEBUG("before poll\n"); n = poll(&ufd, 1, 2000); PDEBUG("after poll\n"); ! #else ! tv.tv_sec = 2; ! tv.tv_usec = 0; ! FD_ZERO (&fd); ! FD_SET (reqfd, &fd); ! n = select (reqfd + 1, &fd, NULL, NULL, &tv); ! #endif /* Check for termination of the main thread */ if (getppid() == 1) { pthread_kill_all_threads(SIGKILL, 0); --- 126,139 ---- /* Synchronize debugging of the thread manager */ n = __libc_read(reqfd, (char *)&request, sizeof(request)); ASSERT(n == sizeof(request) && request.req_kind == REQ_DEBUG); ufd.fd = reqfd; ufd.events = POLLIN; /* Enter server loop */ while(1) { PDEBUG("before poll\n"); n = poll(&ufd, 1, 2000); PDEBUG("after poll\n"); ! /* Check for termination of the main thread */ if (getppid() == 1) { pthread_kill_all_threads(SIGKILL, 0); *************** *** 162,173 **** pthread_reap_children(); } /* Read and execute request */ - #ifndef USE_SELECT if (n == 1 && (ufd.revents & POLLIN)) { - #else - if (n == 1) { - #endif - PDEBUG("before __libc_read\n"); n = __libc_read(reqfd, (char *)&request, sizeof(request)); PDEBUG("after __libc_read, n=%d\n", n); --- 145,151 ---- *************** *** 510,527 **** /* Do the cloning. We have to use two different functions depending on whether we are debugging or not. */ pid = 0; /* Note that the thread never can have PID zero. */ - - /* ******************************************************** */ - // This code is moved from below, see comment below! - - // Insert new thread in doubly linked list of active threads - new_thread->p_prevlive = __pthread_main_thread; - new_thread->p_nextlive = __pthread_main_thread->p_nextlive; - __pthread_main_thread->p_nextlive->p_prevlive = new_thread; - __pthread_main_thread->p_nextlive = new_thread; - - /* ********************************************************* */ - if (report_events) { /* See whether the TD_CREATE event bit is set in any of the --- 488,493 ---- *************** *** 569,581 **** __pthread_sig_cancel, new_thread); /* Check if cloning succeeded */ if (pid == -1) { - /********************************************************/ - // Code inserted to unlink in case of failure, see comment below! - /* Remove thread from list of active threads */ - new_thread->p_nextlive->p_prevlive = new_thread->p_prevlive; - new_thread->p_prevlive->p_nextlive = new_thread->p_nextlive; - /********************************************************/ - /* Free the stack if we allocated it */ if (attr == NULL || !attr->__stackaddr_set) { --- 535,540 ---- *************** *** 594,614 **** return errno; } PDEBUG("new thread pid = %d\n", pid); ! /* *********************************************************** ! This code is moved to before clone (). Because, in uClinux, ! the use of wait on a semaphore is dependant upon that the child ! must be in the active threads list. This list is used in ! pthread_find_self () to get the pthread_descr of self. So, if ! the child calls sem_wait before this code is executed , it will ! hang forever and initial_thread will instead be posted by a ! sem_post call. ! // Insert new thread in doubly linked list of active threads new_thread->p_prevlive = __pthread_main_thread; new_thread->p_nextlive = __pthread_main_thread->p_nextlive; __pthread_main_thread->p_nextlive->p_prevlive = new_thread; __pthread_main_thread->p_nextlive = new_thread; - *********************************************************** */ - /* Set pid field of the new thread, in case we get there before the child starts. */ new_thread->p_pid = pid; --- 553,563 ---- return errno; } PDEBUG("new thread pid = %d\n", pid); ! /* Insert new thread in doubly linked list of active threads */ new_thread->p_prevlive = __pthread_main_thread; new_thread->p_nextlive = __pthread_main_thread->p_nextlive; __pthread_main_thread->p_nextlive->p_prevlive = new_thread; __pthread_main_thread->p_nextlive = new_thread; /* Set pid field of the new thread, in case we get there before the child starts. */ new_thread->p_pid = pid; *** libpthread/linuxthreads/pthread.c.submit_to_uclibc.org Tue Oct 22 07:16:37 2002 --- libpthread/linuxthreads/pthread.c.org Fri Aug 30 11:12:15 2002 *************** *** 14,22 **** /* Thread creation, initialization, and basic low-level routines */ - /* Use changed __pthread_find_self */ - #define FIND_SELF - #define __FORCE_GLIBC #include <features.h> #include <errno.h> --- 14,19 ---- *************** *** 491,507 **** pthread_descr __pthread_find_self() { char * sp = CURRENT_STACK_FRAME; - #ifdef FIND_SELF - pthread_descr th = __pthread_initial_thread.p_nextlive ; - - while (th != &__pthread_initial_thread) { - if ((sp <= (char*)th ) && ( sp >= __pthread_handles[th->p_nr].h_bottom)) { - return th; - } - th = th->p_nextlive ; - } - return NULL; - #else pthread_handle h; /* __pthread_handles[0] is the initial thread, __pthread_handles[1] is --- 488,493 ---- *************** *** 517,523 **** #endif return h->h_descr; - #endif /* FIND_SELF */ } #endif --- 503,508 ---- |
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | RE: (fwd) Re: Making OpenSSH work with uClibc: 00163, Joseph Chiu |
|---|---|
| Next by Date: | Re: problems compiling lshd: 00163, Erik Andersen |
| Previous by Thread: | (fwd) Re: Making OpenSSH work with uClibci: 00163, Erik Andersen |
| Next by Thread: | Re: pthreads patches: 00163, Erik Andersen |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
| News | FAQ | advertise |