diff options
-rw-r--r-- | ANNOUNCE | 37 | ||||
-rw-r--r-- | condvar.c | 10 | ||||
-rw-r--r-- | rwlock.c | 2 | ||||
-rw-r--r-- | tests/cleanup0.c | 2 | ||||
-rw-r--r-- | tests/cleanup1.c | 2 | ||||
-rw-r--r-- | tests/cleanup2.c | 2 | ||||
-rw-r--r-- | tests/cleanup3.c | 2 | ||||
-rw-r--r-- | tests/condvar7.c | 2 | ||||
-rw-r--r-- | tests/condvar8.c | 2 | ||||
-rw-r--r-- | tests/condvar9.c | 2 |
10 files changed, 42 insertions, 21 deletions
@@ -151,6 +151,8 @@ As defined in the new POSIX standard, and the Single Unix Spec version 3: pthread.h no longer includes windows.h
--------------------------------------
+[Not yet for G++]
+
This was done to prevent conflicts.
HANDLE, DWORD, and NULL are temporarily defined within pthread.h if
@@ -208,13 +210,19 @@ Known bugs in this snapshot Workaround [rpj - 2 Feb 2002]
-----------------------------
- The problem disappears when /Ob0 is used, i.e. /O2 /Ob0 works OK.
+ The problem disappears when /Ob0 is used, i.e. /O2 /Ob0 works OK,
+ but if you want to use inlining optimisation you can be much more
+ specific about where it's switched off and on by using a pragma.
So the inlining optimisation is interfering with the way that cleanup
- handlers are run. In order to confirm this, the following use of pragmas
- gets around the problem but I don't know how to make it transparent, in say,
- pthread.h where pthread_cleanup_push is a macro that expands (in the C++ case) to
- a local object instantiation with handlerFunc as the destructor (see pthread.h):
+ handlers are run. It appears to relate to auto-inlining of class methods
+ since this is the only auto inlining that is performed at /O1 optimisation
+ (functions with the "inline" qualifier are also inlined, but the problem
+ doesn't appear to involve any such functions in the library or testsuite).
+
+ In order to confirm the inlining culprit, the following use of pragmas
+ eliminate the problem but I don't know how to make it transparent, putting
+ it in, say, pthread.h where pthread_cleanup_push defined as a macro.
#pragma inline_depth(0)
pthread_cleanup_push(handlerFunc, (void *) &arg);
@@ -222,13 +230,26 @@ Known bugs in this snapshot /* ... */
pthread_cleanup_pop(0);
- #pragma inline_depth(8)
+ #pragma inline_depth()
+
+ Note the empty () value after the pop macro. This resets depth to the
+ default. Or you can specify a non-zero depth here.
The pragma is also needed (and now used) within the library itself wherever
cleanup handlers are used (condvar.c and rwlock.c).
- Use of these pragmas allows compiler optimisation /O2 to be used for
- both the library and applications.
+ Use of these pragmas allows compiler optimisations /O1 and /O2 to be
+ used for either or both the library and applications.
+
+ Experimenting further, I found that wrapping the actual cleanup handler
+ function with #pragma auto_inline(off|on) does NOT work.
+
+ MSVC6.0 doesn't appear to support the C99 standard's _Pragma directive,
+ however, later versions may. This form is embeddable inside #define
+ macros, which would be ideal because it would mean that it could be added
+ to the push/pop macro definitions in pthread.h and hidden from the
+ application programmer.
+
[/rpj]
Original problem description
@@ -753,9 +753,9 @@ ptw32_cond_wait_cleanup(void * args) int result; /* - * Whether we got here as a result of signal/broadcast or because of - * timeout on wait or thread cancellation we indicate that we are no - * longer waiting. The waiter is responsible for adjusting waiters + * Whether we got here as a result of signal/broadcast or because of + * timeout on wait or thread cancellation we indicate that we are no + * longer waiting. The waiter is responsible for adjusting waiters * (to)unblock(ed) counts (protected by unblock lock). */ if ((result = pthread_mutex_lock(&(cv->mtxUnblockLock))) != 0) @@ -853,7 +853,7 @@ ptw32_cond_wait_cleanup(void * args) } /* - * XSH: Upon successful return, the mutex has been locked and is owned + * XSH: Upon successful return, the mutex has been locked and is owned * by the calling thread */ if ((result = pthread_mutex_lock(cleanup_args->mutexPtr)) != 0) @@ -963,7 +963,7 @@ ptw32_cond_timedwait (pthread_cond_t * cond, */ pthread_cleanup_pop(1); #ifdef _MSC_VER -#pragma inline_depth(8) +#pragma inline_depth() #endif /* @@ -632,7 +632,7 @@ pthread_rwlock_wrlock(pthread_rwlock_t * rwlock) pthread_cleanup_pop ((result != 0) ? 1 : 0); #ifdef _MSC_VER -#pragma inline_depth(8) +#pragma inline_depth() #endif if (result == 0) diff --git a/tests/cleanup0.c b/tests/cleanup0.c index 9cd9c5c..a237be4 100644 --- a/tests/cleanup0.c +++ b/tests/cleanup0.c @@ -118,7 +118,7 @@ mythread(void * arg) pthread_cleanup_pop(1); #ifdef _MSC_VER -#pragma inline_depth(8) +#pragma inline_depth() #endif return (void *) result; diff --git a/tests/cleanup1.c b/tests/cleanup1.c index 52a67c7..a5313d9 100644 --- a/tests/cleanup1.c +++ b/tests/cleanup1.c @@ -128,7 +128,7 @@ mythread(void * arg) pthread_cleanup_pop(0); #ifdef _MSC_VER -#pragma inline_depth(8) +#pragma inline_depth() #endif return (void *) result; diff --git a/tests/cleanup2.c b/tests/cleanup2.c index 4d1fafe..5db9e58 100644 --- a/tests/cleanup2.c +++ b/tests/cleanup2.c @@ -112,7 +112,7 @@ mythread(void * arg) pthread_cleanup_pop(1); #ifdef _MSC_VER -#pragma inline_depth(8) +#pragma inline_depth() #endif return (void *) result; diff --git a/tests/cleanup3.c b/tests/cleanup3.c index 2d44f79..c98dd62 100644 --- a/tests/cleanup3.c +++ b/tests/cleanup3.c @@ -115,7 +115,7 @@ mythread(void * arg) pthread_cleanup_pop(0); #ifdef _MSC_VER -#pragma inline_depth(8) +#pragma inline_depth() #endif return (void *) result; diff --git a/tests/condvar7.c b/tests/condvar7.c index 0e52c64..6ac52f7 100644 --- a/tests/condvar7.c +++ b/tests/condvar7.c @@ -126,7 +126,7 @@ mythread(void * arg) pthread_cleanup_pop(0); #ifdef _MSC_VER -#pragma inline_depth(8) +#pragma inline_depth() #endif assert(cvthing.shared > 0); diff --git a/tests/condvar8.c b/tests/condvar8.c index 6f2b458..48486d4 100644 --- a/tests/condvar8.c +++ b/tests/condvar8.c @@ -126,7 +126,7 @@ mythread(void * arg) pthread_cleanup_pop(0); #ifdef _MSC_VER -#pragma inline_depth(8) +#pragma inline_depth() #endif assert(cvthing.shared > 0); diff --git a/tests/condvar9.c b/tests/condvar9.c index e06df17..bdf10df 100644 --- a/tests/condvar9.c +++ b/tests/condvar9.c @@ -131,7 +131,7 @@ mythread(void * arg) pthread_cleanup_pop(0); #ifdef _MSC_VER -#pragma inline_depth(8) +#pragma inline_depth() #endif assert(cvthing.shared > 0); |