]>
Commit | Line | Data |
---|---|---|
30a4e827 MT |
1 | From libc-alpha-return-31329-listarch-libc-alpha=sources dot redhat dot com at sourceware dot org Wed Jul 11 11:36:39 2012 |
2 | Return-Path: <libc-alpha-return-31329-listarch-libc-alpha=sources dot redhat dot com at sourceware dot org> | |
3 | Delivered-To: listarch-libc-alpha at sources dot redhat dot com | |
4 | Received: (qmail 15677 invoked by alias); 11 Jul 2012 11:36:39 -0000 | |
5 | Received: (qmail 15654 invoked by uid 22791); 11 Jul 2012 11:36:37 -0000 | |
6 | X-SWARE-Spam-Status: No, hits=-4.3 required=5.0 | |
7 | tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,KHOP_RCVD_TRUST,RCVD_IN_DNSWL_LOW,RCVD_IN_HOSTKARMA_YE | |
8 | X-Spam-Check-By: sourceware.org | |
9 | Date: Wed, 11 Jul 2012 21:06:06 +0930 | |
10 | From: Alan Modra <amodra at gmail dot com> | |
11 | To: libc-alpha at sourceware dot org | |
12 | Cc: rsa at linux dot vnet dot ibm dot com | |
13 | Subject: powerpc pthread_once bug fix | |
14 | Message-ID: <20120711113606.GM3117@bubble.grove.modra.org> | |
15 | MIME-Version: 1.0 | |
16 | Content-Type: text/plain; charset=us-ascii | |
17 | Content-Disposition: inline | |
18 | User-Agent: Mutt/1.5.21 (2010-09-15) | |
19 | Mailing-List: contact libc-alpha-help at sourceware dot org; run by ezmlm | |
20 | Precedence: bulk | |
21 | List-Id: <libc-alpha.sourceware.org> | |
22 | List-Subscribe: <mailto:libc-alpha-subscribe at sourceware dot org> | |
23 | List-Archive: <http://sourceware.org/ml/libc-alpha/> | |
24 | List-Post: <mailto:libc-alpha at sourceware dot org> | |
25 | List-Help: <mailto:libc-alpha-help at sourceware dot org>, <http://sourceware dot org/ml/#faqs> | |
26 | Sender: libc-alpha-owner at sourceware dot org | |
27 | Delivered-To: mailing list libc-alpha at sourceware dot org | |
28 | ||
29 | This fixes some bugs in the powerpc pthread_once code. Ref | |
30 | gcc.gnu.org/bugzilla/show_bug.cgi?id=52839#c10 | |
31 | ||
32 | Release barriers are needed to ensure any memory written by | |
33 | init_routine is seen by other threads before *once_control changes. | |
34 | In the case of clear_once_control we need to flush any partially | |
35 | written state. | |
36 | ||
37 | 2012-06-28 Alan Modra <amodra@gmail.com> | |
38 | ||
39 | * sysdeps/unix/sysv/linux/powerpc/pthread_once.c (__pthread_once): | |
40 | Add release barrier before setting once_control to say | |
41 | initialisation is done. Add hints on lwarx. Use macro in | |
42 | place of isync. | |
43 | (clear_once_control): Add release barrier. | |
44 | ||
45 | [ This was slightly edited -- the constraint for operand 0 in the last asm was changed | |
46 | from "=&r" to "=&b" as using r0 in that context results in a load immediate 1 into | |
47 | the target rather than incrementing the target. ] | |
48 | ||
49 | diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c | |
50 | index 4e3d7bd..bb1ebf2 100644 | |
51 | --- a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c | |
52 | +++ b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c | |
53 | @@ -28,6 +28,7 @@ clear_once_control (void *arg) | |
54 | { | |
55 | pthread_once_t *once_control = (pthread_once_t *) arg; | |
56 | ||
57 | + __asm __volatile (__lll_rel_instr); | |
58 | *once_control = 0; | |
59 | lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE); | |
60 | } | |
61 | @@ -47,15 +48,15 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void)) | |
62 | oldval = *once_control; | |
63 | if ((oldval & 2) == 0) | |
64 | *once_control = newval; | |
65 | - Do this atomically. | |
66 | + Do this atomically with an acquire barrier. | |
67 | */ | |
68 | newval = __fork_generation | 1; | |
69 | - __asm __volatile ("1: lwarx %0,0,%3\n" | |
70 | + __asm __volatile ("1: lwarx %0,0,%3" MUTEX_HINT_ACQ "\n" | |
71 | " andi. %1,%0,2\n" | |
72 | " bne 2f\n" | |
73 | " stwcx. %4,0,%3\n" | |
74 | " bne 1b\n" | |
75 | - "2: isync" | |
76 | + "2: " __lll_acq_instr | |
77 | : "=&r" (oldval), "=&r" (tmp), "=m" (*once_control) | |
78 | : "r" (once_control), "r" (newval), "m" (*once_control) | |
79 | : "cr0"); | |
80 | @@ -87,8 +88,18 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void)) | |
81 | pthread_cleanup_pop (0); | |
82 | ||
83 | ||
84 | - /* Add one to *once_control to take the bottom 2 bits from 01 to 10. */ | |
85 | - atomic_increment (once_control); | |
86 | + /* Add one to *once_control to take the bottom 2 bits from 01 to 10. | |
87 | + A release barrier is needed to ensure memory written by init_routine | |
88 | + is seen in other threads before *once_control changes. */ | |
89 | + int tmp; | |
90 | + __asm __volatile (__lll_rel_instr "\n" | |
91 | + "1: lwarx %0,0,%2" MUTEX_HINT_REL "\n" | |
92 | + " addi %0,%0,1\n" | |
93 | + " stwcx. %0,0,%2\n" | |
94 | + " bne- 1b" | |
95 | + : "=&b" (tmp), "=m" (*once_control) | |
96 | + : "r" (once_control), "m" (*once_control) | |
97 | + : "cr0"); | |
98 | ||
99 | /* Wake up all other threads. */ | |
100 | lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE); | |
101 | ||
102 | -- | |
103 | Alan Modra | |
104 | Australia Development Lab, IBM | |
105 |