summaryrefslogtreecommitdiff
path: root/create.c
diff options
context:
space:
mode:
authorrpj <rpj>1998-07-21 17:04:38 +0000
committerrpj <rpj>1998-07-21 17:04:38 +0000
commit492c73cf1f1b3e35b394aec991d1201726ec606d (patch)
treef7bddcaa8a2f89e567b94b20bde64973bb626fd2 /create.c
parente51aa9d5fe177407b0c29903fec27b589ea529da (diff)
Wed Jul 22 00:16:22 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
* cleanup.c (_pthread_cleanup_push): Implement. (_pthread_cleanup_pop): Implement. (_pthread_do_cancellation): Implement. These are private to the implementation. The real cleanup functions are macros. See below. * pthread.h (pthread_cleanup_push): Implement as a macro. (pthread_cleanup_pop): Implement as a macro. Because these are macros which start and end a block, the POSIX scoping requirement is observed. See the comment in the file. * exit.c (pthread_exit): Refine the code. * create.c (pthread_create): Code cleanup. * implement.h (RND_SIZEOF): Add RND_SIZEOF(T) to round sizeof(T) up to multiple of DWORD. Add function prototypes. * private.c (_pthread_getthreadindex): "*thread" should have been "thread". Detect empty slot fail condition.
Diffstat (limited to 'create.c')
-rw-r--r--create.c34
1 files changed, 16 insertions, 18 deletions
diff --git a/create.c b/create.c
index 6897a9f..3814a23 100644
--- a/create.c
+++ b/create.c
@@ -42,26 +42,24 @@ pthread_create(pthread_t *thread, const pthread_attr_t *attr,
/* Use and modify attr_copy. Only after we've succeeded in creating the
new thread can we modify any passed-in structures.
- We use one malloc() to get all of our heap space and then allocate
- it further.
+ To save time we use one malloc() to get all of our heap space and
+ then allocate it further.
*/
- if (NULL == (privmem = (char) malloc(sizeof(pthread_attr_t) +
- sizeof(_pthread_cleanup_stack_t) +
- sizeof(DWORD)))) {
+
+ if (NULL ==
+ (privmem = (char) malloc(RND_SIZEOF(pthread_attr_t) +
+ RND_SIZEOF(_pthread_cleanup_stack_t)))) {
return EAGAIN;
}
attr_copy = (pthread_attr_t *) privmem;
- /* Force the next to a DWORD boundary.
- This is all compile time arithmetic.
+
+ /* Force cleanup_stack to start at a DWORD boundary within privmem.
*/
cleanup_stack =
- (_pthread_cleanup_stack_t *) &privmem[((sizeof(pthread_attr_t) /
- sizeof(DWORD)) + 1)
- * sizeof(DWORD)];
+ (_pthread_cleanup_stack_t *) &privmem[RND_SIZEOF(pthread_attr_t)];
(void) memcpy(attr_copy, attr);
-
/* CRITICAL SECTION */
pthread_mutex_lock(&_pthread_count_mutex);
@@ -82,7 +80,10 @@ pthread_create(pthread_t *thread, const pthread_attr_t *attr,
break;
}
- flags = 1; /* Start suspended and resume at the last moment */
+ flags = 1; /* Start suspended and resume at the last moment to avoid
+ race conditions, ie. where a thread may enquire it's
+ attributes before we finish storing them away.
+ */
handle = (HANDLE) _beginthreadex(security,
stack,
@@ -92,22 +93,21 @@ pthread_create(pthread_t *thread, const pthread_attr_t *attr,
&threadID);
if (handle != NULL) {
- /* We have a new thread */
_pthread_threads_count++;
/* The hash table works as follows:
hash into the table,
if the slot is occupied then start single stepping from there
until we find an available slot.
-
- There is at least one slot available at this point.
*/
t = _PTHREAD_HASH_INDEX(handle);
while ((_pthread_threads_table[t])->thread != NULL) {
t++;
+
if (t == PTHREAD_THREADS_MAX)
- t = 0; /* Wrap around to the first slot */
+ t = 0; /* Wrap to the top of the table. */
}
+
if ((_pthread_threads_table[t])->thread != NULL) {
/* INTERNAL ERROR */
} else {
@@ -131,8 +131,6 @@ pthread_create(pthread_t *thread, const pthread_attr_t *attr,
(void) memcpy(attr, attr_copy);
/* POSIX threads are always running after creation.
- Start the thread only after passed-in structures have been
- modified to avoid race conditions.
*/
ResumeThread(handle);
} else {