On Fri, 2004-05-21 at 18:07, Aaron W. LaFramboise wrote:
> Wu Yongwei wrote:
> | On Sat, 2004-05-15 at 13:49, Danny Smith wrote:
> |> | kng wrote: | | >Error Starting Program | > | >The HELLO.EXE
> |> file is linked to missing export
> |> KERNEL32.DLL:InterlockedCompareExchange. | > | >
> |> Wu, this is from your performance changes to gthr-win32.
> | Yes. As I have stated before, my current solution requires Windows
> | 98 or later. I have personally confirmed that it does not work in
> | Windows 95.
> There is another important problem with regard to Windows 95 support
> that should be considered.
> According to the Platform SDK, of InterlockedIncrement():
> "Windows NT 3.51 and earlier, Windows 95: If the result of the
> operation is zero, the return value is zero. If the result of the
> operation is less than zero, the return value is negative, but it is
> not necessarily equal to the result. If the result of the operation is
> greater than zero, the return value is positive, but it is not
> necessarily equal to the result."
> ~From __gthr_win32_mutex_lock():
> ~ if (InterlockedIncrement (&mutex->counter) == 1 ||
> The behavior of this construct on the above-mentioned systems is
> undocumented, and as far as the documentation is authoritative on
> anything, incorrect. As a practical matter, on CPUs that do not have
> an XADD or equivalent instruction (in particular, the 386), the EFLAGS
> changes as a result of an INC or ADD are the only way to atomically
> determine what the value is. This limits the granularity of value
> information to positive, zero, or negative.
> In contrast to the __gthr_win32_mutex_trylock case, where the
> correctness of the operation is not terribly important, this bug will
> probably cause deadlocks on the afflicted systems if they exercise the
> locking code in a multi-threaded environment. While some people may
> not think 386 compatibility is valuable, its probably worth hanging on
> to nonetheless if easily possible. If not, I would suggest that GCC
> flat-out refuse to compile for 386 at all, rather than produce code
> with subtle bugs.
> I think the bug can be fixed by initializing the lock to -1, then
> testing for 0 instead of testing for 1.
> Also, on the subject of __gthr_win32_mutex_trylock, perhaps it would
> be better the simply not implement the function, or implement it
> conditionally based on guaranteed availability of support, rather than
> implement a function that has subtle bugs on some targets if actually
> used? That way, if or when someone does actually use the function,
> the problem will immediately be obvious on the relevant targets, and
> could be revisited then.
Did you miss Thomas's e-mail on this subject? He suggests writing all
three of InterlockedIncrement, InterlockedDecrement, and
InterlockedCompareExchange in assembly. I think it is a good idea.
> Also, is there any reason __gthread_objc_mutex_lock and family do not
> use __gthr_win32_mutex_trylock?
The reason is that it is not necessary. Only EnterCriticalSection and
LeaveCriticalSection semantics are really needed currently.
> By the way, Wu, your locking code is excellent. I've been doing
The mutex implementation is contributed by Thomas. I just made it into
an entire patch. Thomas also found the fault in my earlier code
attempting to solve this problem.
> performance comparisons over the past few days, and it does seem to be
> "as good as it gets." No combination of other performance primitives
> that are guaranteed to be safe comes close to the performance of your
> locks in my tests on uniprocessor systems. Perhaps that comment about
> using critical sections in gthr-win32.h should be modified, as, on
> uniprocessor systems, your lock seems to be faster.
> Thank you for your consideration,
> Aaron W. LaFramboise