aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorHirokazu Takata <takata@linux-m32r.org>2005-11-28 13:43:58 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-28 14:42:24 -0800
commit91f4ab056d85d23fa6955927fdeb1558673e8cd1 (patch)
tree95745578b92f329b3fbe7761baf8c422b2975473 /include
parentbce61dd49d6ba7799be2de17c772e4c701558f14 (diff)
[PATCH] m32r: Fix sys_tas() syscall
This patch fixes a deadlock problem of the m32r SMP kernel. In the m32r kernel, sys_tas() system call is provided as a test-and-set function for userspace, for backward compatibility. In some multi-threading application program, deadlocks were rarely caused at sys_tas() funcion. Such a deadlock was caused due to a collision of __pthread_lock() and __pthread_unlock() operations. The "tas" syscall is repeatedly called by pthread_mutex_lock() to get a lock, while a lock variable's value is not 0. On the other hand, pthead_mutex_unlock() sets the lock variable to 0 for unlocking. In the previous implementation of sys_tas() routine, there was a possibility that a unlock operation was ignored in the following case: - Assume a lock variable (*addr) was equal to 1 before sys_tas() execution. - __pthread_unlock() operation is executed by the other processor and the lock variable (*addr) is set to 0, between a read operation ("oldval = *addr;") and the following write operation ("*addr = 1;") during a execution of sys_tas(). In this case, the following write operation ("*addr = 1;") overwrites the __pthread_unlock() result, and sys_tas() fails to get a lock in the next turn and after that. According to the attatched patch, sys_tas() returns 0 value in the next turn and deadlocks never happen. Signed-off-by: Hitoshi Yamamoto <Yamamoto.Hitoshi@ap.MitsubishiElectric.co.jp> Signed-off-by: Hirokazu Takata <takata@linux-m32r.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include')
0 files changed, 0 insertions, 0 deletions