summaryrefslogtreecommitdiff
path: root/pthread/pt-alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'pthread/pt-alloc.c')
-rw-r--r--pthread/pt-alloc.c215
1 files changed, 0 insertions, 215 deletions
diff --git a/pthread/pt-alloc.c b/pthread/pt-alloc.c
deleted file mode 100644
index 6af2da92..00000000
--- a/pthread/pt-alloc.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/* Allocate a new thread structure.
- Copyright (C) 2000, 2002, 2005, 2007, 2008 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#include <assert.h>
-#include <errno.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <pt-internal.h>
-
-/* This braindamage is necessary because the standard says that some
- of the threads functions "shall fail" if "No thread could be found
- corresponding to that specified by the given thread ID." */
-
-/* Thread ID lookup table. */
-struct __pthread **__pthread_threads;
-
-/* The size of the thread ID lookup table. */
-int __pthread_max_threads;
-
-/* The total number of thread IDs currently in use, or on the list of
- available thread IDs. */
-int __pthread_num_threads;
-
-/* A lock for the table, and the other variables above. */
-pthread_rwlock_t __pthread_threads_lock;
-
-/* List of thread structures corresponding to free thread IDs. */
-struct __pthread *__pthread_free_threads;
-pthread_mutex_t __pthread_free_threads_lock;
-
-static inline error_t
-initialize_pthread (struct __pthread *new, int recycling)
-{
- error_t err;
-
- err = __pthread_init_specific (new);
- if (err)
- return err;
-
- new->cancel_state = PTHREAD_CANCEL_ENABLE;
- new->cancel_type = PTHREAD_CANCEL_DEFERRED;
- new->cancel_pending = 0;
-
- if (recycling)
- /* Since we are recycling PTHREAD, we can assume certains things
- about PTHREAD's current state and save some cycles by not
- rewriting the memory. */
- return 0;
-
- new->stack = 0;
-
- new->state_lock = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
- new->state_cond = (pthread_cond_t) PTHREAD_COND_INITIALIZER;
-
- new->cancelation_handlers = 0;
-
- new->next = 0;
- new->prevp = 0;
-
- return 0;
-}
-
-
-/* Allocate a new thread structure and its pthread thread ID (but not
- a kernel thread). */
-int
-__pthread_alloc (struct __pthread **pthread)
-{
- error_t err;
-
- struct __pthread *new;
- struct __pthread **threads;
- struct __pthread **old_threads;
- int max_threads;
- int new_max_threads;
-
- pthread_mutex_lock (&__pthread_free_threads_lock);
- for (new = __pthread_free_threads; new; new = new->next)
- {
- /* There is no need to take NEW->STATE_LOCK: if NEW is on this
- list, then it is protected by __PTHREAD_FREE_THREADS_LOCK
- except in __pthread_dealloc where after it is added to the
- list (with the lock held), it drops the lock and then sets
- NEW->STATE and immediately stops using NEW. */
- if (new->state == PTHREAD_TERMINATED)
- {
- __pthread_dequeue (new);
- break;
- }
- }
- pthread_mutex_unlock (&__pthread_free_threads_lock);
-
- if (new)
- {
- /* The thread may still be running. Make sure it is stopped.
- If this is the case, then the thread is either at the end of
- __pthread_dealloc or in __pthread_thread_halt. In both
- cases, we are interrupt it. */
- __pthread_thread_halt (new);
-
- err = initialize_pthread (new, 1);
- if (! err)
- *pthread = new;
- return err;
- }
-
- /* Allocate a new thread structure. */
- new = malloc (sizeof (struct __pthread));
- if (new == NULL)
- return ENOMEM;
-
- err = initialize_pthread (new, 0);
- if (err)
- {
- free (new);
- return err;
- }
-
- retry:
- pthread_rwlock_wrlock (&__pthread_threads_lock);
-
- if (__pthread_num_threads < __pthread_max_threads)
- {
- /* We have a free slot. Use the slot number plus one as the
- thread ID for the new thread. */
- new->thread = 1 + __pthread_num_threads++;
- __pthread_threads[new->thread - 1] = NULL;
-
- pthread_rwlock_unlock (&__pthread_threads_lock);
-
- *pthread = new;
- return 0;
- }
-#ifdef PTHREAD_THREADS_MAX
- else if (__pthread_num_threads >= PTHREAD_THREADS_MAX)
- {
- /* We have reached the limit on the number of threads per process. */
- pthread_rwlock_unlock (&__pthread_threads_lock);
-
- free (new);
- return EAGAIN;
- }
-#endif
-
- /* We are going to enlarge the threads table. Save its current
- size. We're going to release the lock before doing the necessary
- memory allocation, since that's a potentially blocking operation. */
- max_threads = __pthread_max_threads;
-
- pthread_rwlock_unlock (&__pthread_threads_lock);
-
- /* Allocate a new lookup table that's twice as large. */
- new_max_threads
- = max_threads > 0 ? max_threads * 2 : _POSIX_THREAD_THREADS_MAX;
- threads = malloc (new_max_threads * sizeof (struct __pthread *));
- if (threads == NULL)
- {
- free (new);
- return ENOMEM;
- }
-
- pthread_rwlock_wrlock (&__pthread_threads_lock);
-
- /* Check if nobody else has already enlarged the table. */
- if (max_threads != __pthread_max_threads)
- {
- /* Yep, they did. */
- pthread_rwlock_unlock (&__pthread_threads_lock);
-
- /* Free the newly allocated table and try again to allocate a slot. */
- free (threads);
- goto retry;
- }
-
- /* Copy over the contents of the old table. */
- memcpy (threads, __pthread_threads,
- __pthread_max_threads * sizeof (struct __pthread *));
-
- /* Save the location of the old table. We want to deallocate its
- storage after we released the lock. */
- old_threads = __pthread_threads;
-
- /* Replace the table with the new one. */
- __pthread_max_threads = new_max_threads;
- __pthread_threads = threads;
-
- /* And allocate ourselves one of the newly created slots. */
- new->thread = 1 + __pthread_num_threads++;
- __pthread_threads[new->thread - 1] = NULL;
-
- pthread_rwlock_unlock (&__pthread_threads_lock);
-
- free (old_threads);
-
- *pthread = new;
- return 0;
-}