From mathieu.desnoyers at efficios.com Tue May 1 10:16:09 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 1 May 2012 10:16:09 -0400 Subject: [lttng-dev] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120430023352.GA16024@Krystal> References: <20120426165544.795e9c24@nehalam.linuxnetplumber.net> <20120427022608.GA7574@Krystal> <20120430023352.GA16024@Krystal> Message-ID: <20120501141609.GA24046@Krystal> Hi! After 1 year of development, with the last 6-7 months spent polishing the API and testing the implementation, I think it is getting about time to release the RCU lock-free hash table in a new Userspace RCU version (0.7). I recently described the guarantees provided by the hash table in more detail, and created tests for the uniqueness guarantee for traversals performed concurrently with add_unique and add_replace operations. I also added test modes that create long hash chains, to test corner-cases of the hash table. One small thing I wonder is whether we should document that the hash table update operations imply full memory barriers ? I'm personally getting confident that the hash table API is clean enough, and the implementation well tested, but I'd like to have your thoughts on the readiness of the hash table for production use. Thanks, Mathieu -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From paulmck at linux.vnet.ibm.com Tue May 1 10:49:24 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Tue, 1 May 2012 07:49:24 -0700 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120501141609.GA24046@Krystal> References: <20120426165544.795e9c24@nehalam.linuxnetplumber.net> <20120427022608.GA7574@Krystal> <20120430023352.GA16024@Krystal> <20120501141609.GA24046@Krystal> Message-ID: <20120501144924.GB2441@linux.vnet.ibm.com> On Tue, May 01, 2012 at 10:16:09AM -0400, Mathieu Desnoyers wrote: > Hi! > > After 1 year of development, with the last 6-7 months spent polishing > the API and testing the implementation, I think it is getting about time > to release the RCU lock-free hash table in a new Userspace RCU version > (0.7). > > I recently described the guarantees provided by the hash table in more > detail, and created tests for the uniqueness guarantee for traversals > performed concurrently with add_unique and add_replace operations. I > also added test modes that create long hash chains, to test corner-cases > of the hash table. > > One small thing I wonder is whether we should document that the hash > table update operations imply full memory barriers ? The Linux kernel's rule seems good here -- if a hash-table operation is atomic and returns a value, it should imply a full barrier. So: cds_lfht_new(): No point in claiming barriers -- publishing the pointer to the hash table is where the barriers are important. cds_lfht_destroy(): Ditto. cds_lfht_lookup(): Not an update (let alone an atomic update), no barriers. cds_lfht_next_duplicate(): Ditto. cds_lfht_first(): Ditto. cds_lfht_next(): Ditto. cds_lfht_add(): Atomic update, but no return value, so no barrier implied. cds_lfht_add_unique(): Atomic update that returns a value, so should imply a full memory barrier. cds_lfht_add_replace(): Ditto. cds_lfht_replace(): Ditto. cds_lfht_del(): Ditto. cds_lfht_is_node_deleted(): Not an update (let alone an atomic update), no barriers. cds_lfht_resize(): Atomic update, but no return value, so no barrier implied. cds_lfht_for_each(): Not an update (let alone an atomic update), no barriers. cds_lfht_for_each_duplicate(): Ditto. cds_lfht_for_each_entry(): Ditto. cds_lfht_for_each_entry_duplicate(): Ditto. Thanx, Paul > I'm personally getting confident that the hash table API is clean > enough, and the implementation well tested, but I'd like to have your > thoughts on the readiness of the hash table for production use. > > Thanks, > > Mathieu > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > rp mailing list > rp at svcs.cs.pdx.edu > http://svcs.cs.pdx.edu/mailman/listinfo/rp > From mathieu.desnoyers at efficios.com Tue May 1 11:12:15 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 1 May 2012 11:12:15 -0400 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120501144924.GB2441@linux.vnet.ibm.com> References: <20120426165544.795e9c24@nehalam.linuxnetplumber.net> <20120427022608.GA7574@Krystal> <20120430023352.GA16024@Krystal> <20120501141609.GA24046@Krystal> <20120501144924.GB2441@linux.vnet.ibm.com> Message-ID: <20120501151215.GB24840@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > On Tue, May 01, 2012 at 10:16:09AM -0400, Mathieu Desnoyers wrote: > > Hi! > > > > After 1 year of development, with the last 6-7 months spent polishing > > the API and testing the implementation, I think it is getting about time > > to release the RCU lock-free hash table in a new Userspace RCU version > > (0.7). > > > > I recently described the guarantees provided by the hash table in more > > detail, and created tests for the uniqueness guarantee for traversals > > performed concurrently with add_unique and add_replace operations. I > > also added test modes that create long hash chains, to test corner-cases > > of the hash table. > > > > One small thing I wonder is whether we should document that the hash > > table update operations imply full memory barriers ? > > The Linux kernel's rule seems good here -- if a hash-table operation is > atomic and returns a value, it should imply a full barrier. So: > > cds_lfht_new(): No point in claiming barriers -- publishing the > pointer to the hash table is where the barriers are important. > > cds_lfht_destroy(): Ditto. > > cds_lfht_lookup(): Not an update (let alone an atomic update), no barriers. > > cds_lfht_next_duplicate(): Ditto. > > cds_lfht_first(): Ditto. > > cds_lfht_next(): Ditto. > > cds_lfht_add(): Atomic update, but no return value, so no barrier > implied. Yep, makes sense. We use cmpxchg internally to perform the update, but it could make sense to eventually use a cmpxchg that has no memory barriers to perform this update. So I agree on not providing a memory barrier guarantee on the "add" operation, since it does not return any value. > > cds_lfht_add_unique(): Atomic update that returns a value, so should > imply a full memory barrier. add_unique is a bit special: - if it returns the node received as parameter, it means the add succeeded, which imply an update, and thus a memory barrier. - if it returns a different node than the one received as parameter, it failed, and thus means that it only performed a lookup, so there is no guarantee that a memory barrier has been executed. > > cds_lfht_add_replace(): Ditto. > > cds_lfht_replace(): Ditto. > > cds_lfht_del(): Ditto. Yep, makes sense. I'll add this documentation in the API. Thanks! Mathieu > > cds_lfht_is_node_deleted(): Not an update (let alone an atomic update), > no barriers. > > cds_lfht_resize(): Atomic update, but no return value, so no barrier > implied. > > cds_lfht_for_each(): Not an update (let alone an atomic update), > no barriers. > > cds_lfht_for_each_duplicate(): Ditto. > > cds_lfht_for_each_entry(): Ditto. > > cds_lfht_for_each_entry_duplicate(): Ditto. > > Thanx, Paul > > > I'm personally getting confident that the hash table API is clean > > enough, and the implementation well tested, but I'd like to have your > > thoughts on the readiness of the hash table for production use. > > > > Thanks, > > > > Mathieu > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > > > _______________________________________________ > > rp mailing list > > rp at svcs.cs.pdx.edu > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Tue May 1 11:21:44 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 1 May 2012 11:21:44 -0400 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120501151215.GB24840@Krystal> References: <20120426165544.795e9c24@nehalam.linuxnetplumber.net> <20120427022608.GA7574@Krystal> <20120430023352.GA16024@Krystal> <20120501141609.GA24046@Krystal> <20120501144924.GB2441@linux.vnet.ibm.com> <20120501151215.GB24840@Krystal> Message-ID: <20120501152144.GA25061@Krystal> * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > On Tue, May 01, 2012 at 10:16:09AM -0400, Mathieu Desnoyers wrote: > > > Hi! > > > > > > After 1 year of development, with the last 6-7 months spent polishing > > > the API and testing the implementation, I think it is getting about time > > > to release the RCU lock-free hash table in a new Userspace RCU version > > > (0.7). > > > > > > I recently described the guarantees provided by the hash table in more > > > detail, and created tests for the uniqueness guarantee for traversals > > > performed concurrently with add_unique and add_replace operations. I > > > also added test modes that create long hash chains, to test corner-cases > > > of the hash table. > > > > > > One small thing I wonder is whether we should document that the hash > > > table update operations imply full memory barriers ? > > > > The Linux kernel's rule seems good here -- if a hash-table operation is > > atomic and returns a value, it should imply a full barrier. So: > > > > cds_lfht_new(): No point in claiming barriers -- publishing the > > pointer to the hash table is where the barriers are important. > > > > cds_lfht_destroy(): Ditto. > > > > cds_lfht_lookup(): Not an update (let alone an atomic update), no barriers. > > > > cds_lfht_next_duplicate(): Ditto. > > > > cds_lfht_first(): Ditto. > > > > cds_lfht_next(): Ditto. > > > > cds_lfht_add(): Atomic update, but no return value, so no barrier > > implied. > > Yep, makes sense. We use cmpxchg internally to perform the update, but > it could make sense to eventually use a cmpxchg that has no memory > barriers to perform this update. So I agree on not providing a memory > barrier guarantee on the "add" operation, since it does not return any > value. > > > > > cds_lfht_add_unique(): Atomic update that returns a value, so should > > imply a full memory barrier. > > add_unique is a bit special: > > - if it returns the node received as parameter, it means the add > succeeded, which imply an update, and thus a memory barrier. Hrm, thinking further: if we make the "add" operation not act as a full memory barrier, then the add_unique success should not act as a full mb neither. > > - if it returns a different node than the one received as parameter, it > failed, and thus means that it only performed a lookup, so there is no > guarantee that a memory barrier has been executed. > > > > > > cds_lfht_add_replace(): Ditto. > > > > cds_lfht_replace(): Ditto. > > > > cds_lfht_del(): Ditto. One more point: "del" is similar to add_unique: if it succeeds, we execute a full memory barrier. If it fails, no memory barrier is guaranteed. But if we want to make the guarantees relax, we might not want to guarantee that a memory barrier is present in any of the "del" cases. In the end, the only primitives for which I think it really makes sense to provide memory barrier semantic is the add_replace and replace : they actually act as an higher-level "cmpxchg" over the hash table nodes. Thoughts ? Thanks, Mathieu > > Yep, makes sense. > > I'll add this documentation in the API. > > Thanks! > > Mathieu > > > > > cds_lfht_is_node_deleted(): Not an update (let alone an atomic update), > > no barriers. > > > > cds_lfht_resize(): Atomic update, but no return value, so no barrier > > implied. > > > > cds_lfht_for_each(): Not an update (let alone an atomic update), > > no barriers. > > > > cds_lfht_for_each_duplicate(): Ditto. > > > > cds_lfht_for_each_entry(): Ditto. > > > > cds_lfht_for_each_entry_duplicate(): Ditto. > > > > Thanx, Paul > > > > > I'm personally getting confident that the hash table API is clean > > > enough, and the implementation well tested, but I'd like to have your > > > thoughts on the readiness of the hash table for production use. > > > > > > Thanks, > > > > > > Mathieu > > > > > > -- > > > Mathieu Desnoyers > > > Operating System Efficiency R&D Consultant > > > EfficiOS Inc. > > > http://www.efficios.com > > > > > > _______________________________________________ > > > rp mailing list > > > rp at svcs.cs.pdx.edu > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From paulmck at linux.vnet.ibm.com Tue May 1 12:09:14 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Tue, 1 May 2012 09:09:14 -0700 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120501151215.GB24840@Krystal> References: <20120426165544.795e9c24@nehalam.linuxnetplumber.net> <20120427022608.GA7574@Krystal> <20120430023352.GA16024@Krystal> <20120501141609.GA24046@Krystal> <20120501144924.GB2441@linux.vnet.ibm.com> <20120501151215.GB24840@Krystal> Message-ID: <20120501160914.GE2441@linux.vnet.ibm.com> On Tue, May 01, 2012 at 11:12:15AM -0400, Mathieu Desnoyers wrote: > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > On Tue, May 01, 2012 at 10:16:09AM -0400, Mathieu Desnoyers wrote: > > > Hi! > > > > > > After 1 year of development, with the last 6-7 months spent polishing > > > the API and testing the implementation, I think it is getting about time > > > to release the RCU lock-free hash table in a new Userspace RCU version > > > (0.7). > > > > > > I recently described the guarantees provided by the hash table in more > > > detail, and created tests for the uniqueness guarantee for traversals > > > performed concurrently with add_unique and add_replace operations. I > > > also added test modes that create long hash chains, to test corner-cases > > > of the hash table. > > > > > > One small thing I wonder is whether we should document that the hash > > > table update operations imply full memory barriers ? > > > > The Linux kernel's rule seems good here -- if a hash-table operation is > > atomic and returns a value, it should imply a full barrier. So: > > > > cds_lfht_new(): No point in claiming barriers -- publishing the > > pointer to the hash table is where the barriers are important. > > > > cds_lfht_destroy(): Ditto. > > > > cds_lfht_lookup(): Not an update (let alone an atomic update), no barriers. > > > > cds_lfht_next_duplicate(): Ditto. > > > > cds_lfht_first(): Ditto. > > > > cds_lfht_next(): Ditto. > > > > cds_lfht_add(): Atomic update, but no return value, so no barrier > > implied. > > Yep, makes sense. We use cmpxchg internally to perform the update, but > it could make sense to eventually use a cmpxchg that has no memory > barriers to perform this update. So I agree on not providing a memory > barrier guarantee on the "add" operation, since it does not return any > value. > > > cds_lfht_add_unique(): Atomic update that returns a value, so should > > imply a full memory barrier. > > add_unique is a bit special: > > - if it returns the node received as parameter, it means the add > succeeded, which imply an update, and thus a memory barrier. > > - if it returns a different node than the one received as parameter, it > failed, and thus means that it only performed a lookup, so there is no > guarantee that a memory barrier has been executed. Good point! But I would suggest handling this like some architectures handle a failing cmpxchg() -- there is a memory barrier beforehand, but not afterwards. This works well because although the caller can easily supply a memory barrier after a failing cmpxchg(), there is no way to supply one beforehand except by supplying a redundant barrier in the case of a successful cmpxchg(). So I suggest that a failing add_unique() guarantee full memory barrier beforehand, but not afterwards. Thanx, Paul > > cds_lfht_add_replace(): Ditto. > > > > cds_lfht_replace(): Ditto. > > > > cds_lfht_del(): Ditto. > > Yep, makes sense. > > I'll add this documentation in the API. > > Thanks! > > Mathieu > > > > > cds_lfht_is_node_deleted(): Not an update (let alone an atomic update), > > no barriers. > > > > cds_lfht_resize(): Atomic update, but no return value, so no barrier > > implied. > > > > cds_lfht_for_each(): Not an update (let alone an atomic update), > > no barriers. > > > > cds_lfht_for_each_duplicate(): Ditto. > > > > cds_lfht_for_each_entry(): Ditto. > > > > cds_lfht_for_each_entry_duplicate(): Ditto. > > > > Thanx, Paul > > > > > I'm personally getting confident that the hash table API is clean > > > enough, and the implementation well tested, but I'd like to have your > > > thoughts on the readiness of the hash table for production use. > > > > > > Thanks, > > > > > > Mathieu > > > > > > -- > > > Mathieu Desnoyers > > > Operating System Efficiency R&D Consultant > > > EfficiOS Inc. > > > http://www.efficios.com > > > > > > _______________________________________________ > > > rp mailing list > > > rp at svcs.cs.pdx.edu > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > From paulmck at linux.vnet.ibm.com Tue May 1 12:13:37 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Tue, 1 May 2012 09:13:37 -0700 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120501152144.GA25061@Krystal> References: <20120426165544.795e9c24@nehalam.linuxnetplumber.net> <20120427022608.GA7574@Krystal> <20120430023352.GA16024@Krystal> <20120501141609.GA24046@Krystal> <20120501144924.GB2441@linux.vnet.ibm.com> <20120501151215.GB24840@Krystal> <20120501152144.GA25061@Krystal> Message-ID: <20120501161337.GF2441@linux.vnet.ibm.com> On Tue, May 01, 2012 at 11:21:44AM -0400, Mathieu Desnoyers wrote: > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > On Tue, May 01, 2012 at 10:16:09AM -0400, Mathieu Desnoyers wrote: > > > > Hi! > > > > > > > > After 1 year of development, with the last 6-7 months spent polishing > > > > the API and testing the implementation, I think it is getting about time > > > > to release the RCU lock-free hash table in a new Userspace RCU version > > > > (0.7). > > > > > > > > I recently described the guarantees provided by the hash table in more > > > > detail, and created tests for the uniqueness guarantee for traversals > > > > performed concurrently with add_unique and add_replace operations. I > > > > also added test modes that create long hash chains, to test corner-cases > > > > of the hash table. > > > > > > > > One small thing I wonder is whether we should document that the hash > > > > table update operations imply full memory barriers ? > > > > > > The Linux kernel's rule seems good here -- if a hash-table operation is > > > atomic and returns a value, it should imply a full barrier. So: > > > > > > cds_lfht_new(): No point in claiming barriers -- publishing the > > > pointer to the hash table is where the barriers are important. > > > > > > cds_lfht_destroy(): Ditto. > > > > > > cds_lfht_lookup(): Not an update (let alone an atomic update), no barriers. > > > > > > cds_lfht_next_duplicate(): Ditto. > > > > > > cds_lfht_first(): Ditto. > > > > > > cds_lfht_next(): Ditto. > > > > > > cds_lfht_add(): Atomic update, but no return value, so no barrier > > > implied. > > > > Yep, makes sense. We use cmpxchg internally to perform the update, but > > it could make sense to eventually use a cmpxchg that has no memory > > barriers to perform this update. So I agree on not providing a memory > > barrier guarantee on the "add" operation, since it does not return any > > value. > > > > > > > > cds_lfht_add_unique(): Atomic update that returns a value, so should > > > imply a full memory barrier. > > > > add_unique is a bit special: > > > > - if it returns the node received as parameter, it means the add > > succeeded, which imply an update, and thus a memory barrier. > > Hrm, thinking further: if we make the "add" operation not act as a > full memory barrier, then the add_unique success should not act as a > full mb neither. Think of it as being similar to the Linux kernel's atomic_inc() and atomic_add_return() primitives. The latter guarantees memory barriers and the former does not. > > - if it returns a different node than the one received as parameter, it > > failed, and thus means that it only performed a lookup, so there is no > > guarantee that a memory barrier has been executed. > > > > > > > > > > cds_lfht_add_replace(): Ditto. > > > > > > cds_lfht_replace(): Ditto. > > > > > > cds_lfht_del(): Ditto. > > One more point: "del" is similar to add_unique: if it succeeds, we > execute a full memory barrier. If it fails, no memory barrier is > guaranteed. But if we want to make the guarantees relax, we might not > want to guarantee that a memory barrier is present in any of the "del" > cases. > > In the end, the only primitives for which I think it really makes sense > to provide memory barrier semantic is the add_replace and replace : they > actually act as an higher-level "cmpxchg" over the hash table nodes. I believe that this should do the same -- memory barrier before, but no memory barrier after on failure. Another approach is C++11, in which there are a couple of arguments to the compare-and-swap primitive specifying the memory ordering constraints for the success and failure cases, respectively. Unless you expect use cases with lots of failing cds_lfht_del() and add_unique() calls, the performance difference should not be significant. Thanx, Paul > Thoughts ? > > Thanks, > > Mathieu > > > > > Yep, makes sense. > > > > I'll add this documentation in the API. > > > > Thanks! > > > > Mathieu > > > > > > > > cds_lfht_is_node_deleted(): Not an update (let alone an atomic update), > > > no barriers. > > > > > > cds_lfht_resize(): Atomic update, but no return value, so no barrier > > > implied. > > > > > > cds_lfht_for_each(): Not an update (let alone an atomic update), > > > no barriers. > > > > > > cds_lfht_for_each_duplicate(): Ditto. > > > > > > cds_lfht_for_each_entry(): Ditto. > > > > > > cds_lfht_for_each_entry_duplicate(): Ditto. > > > > > > Thanx, Paul > > > > > > > I'm personally getting confident that the hash table API is clean > > > > enough, and the implementation well tested, but I'd like to have your > > > > thoughts on the readiness of the hash table for production use. > > > > > > > > Thanks, > > > > > > > > Mathieu > > > > > > > > -- > > > > Mathieu Desnoyers > > > > Operating System Efficiency R&D Consultant > > > > EfficiOS Inc. > > > > http://www.efficios.com > > > > > > > > _______________________________________________ > > > > rp mailing list > > > > rp at svcs.cs.pdx.edu > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > _______________________________________________ > > > lttng-dev mailing list > > > lttng-dev at lists.lttng.org > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > rp mailing list > rp at svcs.cs.pdx.edu > http://svcs.cs.pdx.edu/mailman/listinfo/rp > From mathieu.desnoyers at efficios.com Tue May 1 13:41:36 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 1 May 2012 13:41:36 -0400 Subject: [lttng-dev] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120501161337.GF2441@linux.vnet.ibm.com> References: <20120426165544.795e9c24@nehalam.linuxnetplumber.net> <20120427022608.GA7574@Krystal> <20120430023352.GA16024@Krystal> <20120501141609.GA24046@Krystal> <20120501144924.GB2441@linux.vnet.ibm.com> <20120501151215.GB24840@Krystal> <20120501152144.GA25061@Krystal> <20120501161337.GF2441@linux.vnet.ibm.com> Message-ID: <20120501174136.GA26609@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > On Tue, May 01, 2012 at 11:21:44AM -0400, Mathieu Desnoyers wrote: > > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > On Tue, May 01, 2012 at 10:16:09AM -0400, Mathieu Desnoyers wrote: > > > > > Hi! > > > > > > > > > > After 1 year of development, with the last 6-7 months spent polishing > > > > > the API and testing the implementation, I think it is getting about time > > > > > to release the RCU lock-free hash table in a new Userspace RCU version > > > > > (0.7). > > > > > > > > > > I recently described the guarantees provided by the hash table in more > > > > > detail, and created tests for the uniqueness guarantee for traversals > > > > > performed concurrently with add_unique and add_replace operations. I > > > > > also added test modes that create long hash chains, to test corner-cases > > > > > of the hash table. > > > > > > > > > > One small thing I wonder is whether we should document that the hash > > > > > table update operations imply full memory barriers ? > > > > > > > > The Linux kernel's rule seems good here -- if a hash-table operation is > > > > atomic and returns a value, it should imply a full barrier. So: > > > > > > > > cds_lfht_new(): No point in claiming barriers -- publishing the > > > > pointer to the hash table is where the barriers are important. > > > > > > > > cds_lfht_destroy(): Ditto. > > > > > > > > cds_lfht_lookup(): Not an update (let alone an atomic update), no barriers. > > > > > > > > cds_lfht_next_duplicate(): Ditto. > > > > > > > > cds_lfht_first(): Ditto. > > > > > > > > cds_lfht_next(): Ditto. > > > > > > > > cds_lfht_add(): Atomic update, but no return value, so no barrier > > > > implied. > > > > > > Yep, makes sense. We use cmpxchg internally to perform the update, but > > > it could make sense to eventually use a cmpxchg that has no memory > > > barriers to perform this update. So I agree on not providing a memory > > > barrier guarantee on the "add" operation, since it does not return any > > > value. > > > > > > > > > > > cds_lfht_add_unique(): Atomic update that returns a value, so should > > > > imply a full memory barrier. > > > > > > add_unique is a bit special: > > > > > > - if it returns the node received as parameter, it means the add > > > succeeded, which imply an update, and thus a memory barrier. > > > > Hrm, thinking further: if we make the "add" operation not act as a > > full memory barrier, then the add_unique success should not act as a > > full mb neither. > > Think of it as being similar to the Linux kernel's atomic_inc() and > atomic_add_return() primitives. The latter guarantees memory barriers > and the former does not. I think add/add_unique vs atomic_inc/atomic_add_return are fundamentally different. atomic_inc: - input: increment - output: none - effect: increment target address value atomic_add_return: - input: increment - output: incremented value - effect: increment target address value, atomically reading the resulting value. hash table add: - input: new node to add - output: none - effect: atomically add the new node into the table hash table add_unique (success): - input: new node to add - output: (we just return whether the operation has succeeded) - effect: atomically add the new node into the table hash table add_unique (failure): - input: new node to try adding - output: (we just return whether the operation has succeeded) - effect: simple lookup (read) So as we see, the add_unique failure only performs a read. Adding a memory barrier before this read would require us to add a memory barrier also on the success path, which would degrade performance. The success path does: lookup failure, cmpxchg to add the node, retry if changed. Adding a memory barrier before the lookup would add an extra memory barrier in addition to the one located in the cmpxchg, and I don't think we want that overhead. > > > > - if it returns a different node than the one received as parameter, it > > > failed, and thus means that it only performed a lookup, so there is no > > > guarantee that a memory barrier has been executed. > > > > > > > > > > > > > > cds_lfht_add_replace(): Ditto. > > > > > > > > cds_lfht_replace(): Ditto. > > > > > > > > cds_lfht_del(): Ditto. > > > > One more point: "del" is similar to add_unique: if it succeeds, we > > execute a full memory barrier. If it fails, no memory barrier is > > guaranteed. But if we want to make the guarantees relax, we might not > > want to guarantee that a memory barrier is present in any of the "del" > > cases. > > > > In the end, the only primitives for which I think it really makes sense > > to provide memory barrier semantic is the add_replace and replace : they > > actually act as an higher-level "cmpxchg" over the hash table nodes. > > I believe that this should do the same -- memory barrier before, but no > memory barrier after on failure. > > Another approach is C++11, in which there are a couple of arguments to > the compare-and-swap primitive specifying the memory ordering constraints > for the success and failure cases, respectively. Hrm, I think adding this kind of flexibility might make the API too clobbered by details that "usual cases" don't care about. > > Unless you expect use cases with lots of failing cds_lfht_del() and > add_unique() calls, the performance difference should not be significant. The problem is that I expect very, very frequent failing add_unique calls for use-cases like Binary Decision Diagrams (BDD) creation. This is why I don't think it is appropriate to put memory barriers on the failure cases, as these should have no more overhead than a simple lookup. And if we choose not to provide memory barriers for add_unique failure, we should probably do the same for "del" to keep a consistent behavior over the API. Thoughts ? Thanks, Mathieu > > Thanx, Paul > > > Thoughts ? > > > > Thanks, > > > > Mathieu > > > > > > > > Yep, makes sense. > > > > > > I'll add this documentation in the API. > > > > > > Thanks! > > > > > > Mathieu > > > > > > > > > > > cds_lfht_is_node_deleted(): Not an update (let alone an atomic update), > > > > no barriers. > > > > > > > > cds_lfht_resize(): Atomic update, but no return value, so no barrier > > > > implied. > > > > > > > > cds_lfht_for_each(): Not an update (let alone an atomic update), > > > > no barriers. > > > > > > > > cds_lfht_for_each_duplicate(): Ditto. > > > > > > > > cds_lfht_for_each_entry(): Ditto. > > > > > > > > cds_lfht_for_each_entry_duplicate(): Ditto. > > > > > > > > Thanx, Paul > > > > > > > > > I'm personally getting confident that the hash table API is clean > > > > > enough, and the implementation well tested, but I'd like to have your > > > > > thoughts on the readiness of the hash table for production use. > > > > > > > > > > Thanks, > > > > > > > > > > Mathieu > > > > > > > > > > -- > > > > > Mathieu Desnoyers > > > > > Operating System Efficiency R&D Consultant > > > > > EfficiOS Inc. > > > > > http://www.efficios.com > > > > > > > > > > _______________________________________________ > > > > > rp mailing list > > > > > rp at svcs.cs.pdx.edu > > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > > > > > _______________________________________________ > > > > lttng-dev mailing list > > > > lttng-dev at lists.lttng.org > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > -- > > > Mathieu Desnoyers > > > Operating System Efficiency R&D Consultant > > > EfficiOS Inc. > > > http://www.efficios.com > > > > > > _______________________________________________ > > > lttng-dev mailing list > > > lttng-dev at lists.lttng.org > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > > > _______________________________________________ > > rp mailing list > > rp at svcs.cs.pdx.edu > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From paulmck at linux.vnet.ibm.com Tue May 1 15:47:14 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Tue, 1 May 2012 12:47:14 -0700 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120501174136.GA26609@Krystal> References: <20120426165544.795e9c24@nehalam.linuxnetplumber.net> <20120427022608.GA7574@Krystal> <20120430023352.GA16024@Krystal> <20120501141609.GA24046@Krystal> <20120501144924.GB2441@linux.vnet.ibm.com> <20120501151215.GB24840@Krystal> <20120501152144.GA25061@Krystal> <20120501161337.GF2441@linux.vnet.ibm.com> <20120501174136.GA26609@Krystal> Message-ID: <20120501194713.GL2441@linux.vnet.ibm.com> On Tue, May 01, 2012 at 01:41:36PM -0400, Mathieu Desnoyers wrote: > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > On Tue, May 01, 2012 at 11:21:44AM -0400, Mathieu Desnoyers wrote: > > > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > On Tue, May 01, 2012 at 10:16:09AM -0400, Mathieu Desnoyers wrote: > > > > > > Hi! > > > > > > > > > > > > After 1 year of development, with the last 6-7 months spent polishing > > > > > > the API and testing the implementation, I think it is getting about time > > > > > > to release the RCU lock-free hash table in a new Userspace RCU version > > > > > > (0.7). > > > > > > > > > > > > I recently described the guarantees provided by the hash table in more > > > > > > detail, and created tests for the uniqueness guarantee for traversals > > > > > > performed concurrently with add_unique and add_replace operations. I > > > > > > also added test modes that create long hash chains, to test corner-cases > > > > > > of the hash table. > > > > > > > > > > > > One small thing I wonder is whether we should document that the hash > > > > > > table update operations imply full memory barriers ? > > > > > > > > > > The Linux kernel's rule seems good here -- if a hash-table operation is > > > > > atomic and returns a value, it should imply a full barrier. So: > > > > > > > > > > cds_lfht_new(): No point in claiming barriers -- publishing the > > > > > pointer to the hash table is where the barriers are important. > > > > > > > > > > cds_lfht_destroy(): Ditto. > > > > > > > > > > cds_lfht_lookup(): Not an update (let alone an atomic update), no barriers. > > > > > > > > > > cds_lfht_next_duplicate(): Ditto. > > > > > > > > > > cds_lfht_first(): Ditto. > > > > > > > > > > cds_lfht_next(): Ditto. > > > > > > > > > > cds_lfht_add(): Atomic update, but no return value, so no barrier > > > > > implied. > > > > > > > > Yep, makes sense. We use cmpxchg internally to perform the update, but > > > > it could make sense to eventually use a cmpxchg that has no memory > > > > barriers to perform this update. So I agree on not providing a memory > > > > barrier guarantee on the "add" operation, since it does not return any > > > > value. > > > > > > > > > > > > > > cds_lfht_add_unique(): Atomic update that returns a value, so should > > > > > imply a full memory barrier. > > > > > > > > add_unique is a bit special: > > > > > > > > - if it returns the node received as parameter, it means the add > > > > succeeded, which imply an update, and thus a memory barrier. > > > > > > Hrm, thinking further: if we make the "add" operation not act as a > > > full memory barrier, then the add_unique success should not act as a > > > full mb neither. > > > > Think of it as being similar to the Linux kernel's atomic_inc() and > > atomic_add_return() primitives. The latter guarantees memory barriers > > and the former does not. > > I think add/add_unique vs atomic_inc/atomic_add_return are fundamentally > different. > > atomic_inc: > - input: increment > - output: none > - effect: increment target address value > > atomic_add_return: > - input: increment > - output: incremented value > - effect: increment target address value, atomically reading the > resulting value. > > hash table add: > - input: new node to add > - output: none > - effect: atomically add the new node into the table > > hash table add_unique (success): > - input: new node to add > - output: (we just return whether the operation has succeeded) > - effect: atomically add the new node into the table > > hash table add_unique (failure): > - input: new node to try adding > - output: (we just return whether the operation has succeeded) > - effect: simple lookup (read) > > So as we see, the add_unique failure only performs a read. Adding a > memory barrier before this read would require us to add a memory barrier > also on the success path, which would degrade performance. The success > path does: lookup failure, cmpxchg to add the node, retry if changed. > Adding a memory barrier before the lookup would add an extra memory > barrier in addition to the one located in the cmpxchg, and I don't think > we want that overhead. Perhaps a better analogy is cmpxchg() in the Linux kernel. Some architectures place the memory barrier before unconditionally, but place a memory barrier after only if the cmpxchg() succeeds. Of course, architectures for which the cmpxchg instruction implies a barrier don't need any explicit memory-barrier instructions. I do see your point about the memory barrier in the failure case requiring an additional memory barrier in the success case, however. > > > > - if it returns a different node than the one received as parameter, it > > > > failed, and thus means that it only performed a lookup, so there is no > > > > guarantee that a memory barrier has been executed. > > > > > > > > > > > > > > > > > > cds_lfht_add_replace(): Ditto. > > > > > > > > > > cds_lfht_replace(): Ditto. > > > > > > > > > > cds_lfht_del(): Ditto. > > > > > > One more point: "del" is similar to add_unique: if it succeeds, we > > > execute a full memory barrier. If it fails, no memory barrier is > > > guaranteed. But if we want to make the guarantees relax, we might not > > > want to guarantee that a memory barrier is present in any of the "del" > > > cases. > > > > > > In the end, the only primitives for which I think it really makes sense > > > to provide memory barrier semantic is the add_replace and replace : they > > > actually act as an higher-level "cmpxchg" over the hash table nodes. > > > > I believe that this should do the same -- memory barrier before, but no > > memory barrier after on failure. > > > > Another approach is C++11, in which there are a couple of arguments to > > the compare-and-swap primitive specifying the memory ordering constraints > > for the success and failure cases, respectively. > > Hrm, I think adding this kind of flexibility might make the API too > clobbered by details that "usual cases" don't care about. ;-) > > Unless you expect use cases with lots of failing cds_lfht_del() and > > add_unique() calls, the performance difference should not be significant. > > The problem is that I expect very, very frequent failing add_unique > calls for use-cases like Binary Decision Diagrams (BDD) creation. This > is why I don't think it is appropriate to put memory barriers on the > failure cases, as these should have no more overhead than a simple > lookup. > > And if we choose not to provide memory barriers for add_unique failure, > we should probably do the same for "del" to keep a consistent behavior > over the API. > > Thoughts ? Given your BDD example, letting the failure cases avoid memory barriers seems reasonable. If problems arise, the default interfaces can be fully ordered with faster versions where the failure cases avoid memory barriers. Thanx, Paul > Thanks, > > Mathieu > > > > > > Thanx, Paul > > > > > Thoughts ? > > > > > > Thanks, > > > > > > Mathieu > > > > > > > > > > > Yep, makes sense. > > > > > > > > I'll add this documentation in the API. > > > > > > > > Thanks! > > > > > > > > Mathieu > > > > > > > > > > > > > > cds_lfht_is_node_deleted(): Not an update (let alone an atomic update), > > > > > no barriers. > > > > > > > > > > cds_lfht_resize(): Atomic update, but no return value, so no barrier > > > > > implied. > > > > > > > > > > cds_lfht_for_each(): Not an update (let alone an atomic update), > > > > > no barriers. > > > > > > > > > > cds_lfht_for_each_duplicate(): Ditto. > > > > > > > > > > cds_lfht_for_each_entry(): Ditto. > > > > > > > > > > cds_lfht_for_each_entry_duplicate(): Ditto. > > > > > > > > > > Thanx, Paul > > > > > > > > > > > I'm personally getting confident that the hash table API is clean > > > > > > enough, and the implementation well tested, but I'd like to have your > > > > > > thoughts on the readiness of the hash table for production use. > > > > > > > > > > > > Thanks, > > > > > > > > > > > > Mathieu > > > > > > > > > > > > -- > > > > > > Mathieu Desnoyers > > > > > > Operating System Efficiency R&D Consultant > > > > > > EfficiOS Inc. > > > > > > http://www.efficios.com > > > > > > > > > > > > _______________________________________________ > > > > > > rp mailing list > > > > > > rp at svcs.cs.pdx.edu > > > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > lttng-dev mailing list > > > > > lttng-dev at lists.lttng.org > > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > -- > > > > Mathieu Desnoyers > > > > Operating System Efficiency R&D Consultant > > > > EfficiOS Inc. > > > > http://www.efficios.com > > > > > > > > _______________________________________________ > > > > lttng-dev mailing list > > > > lttng-dev at lists.lttng.org > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > -- > > > Mathieu Desnoyers > > > Operating System Efficiency R&D Consultant > > > EfficiOS Inc. > > > http://www.efficios.com > > > > > > _______________________________________________ > > > rp mailing list > > > rp at svcs.cs.pdx.edu > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > rp mailing list > rp at svcs.cs.pdx.edu > http://svcs.cs.pdx.edu/mailman/listinfo/rp > From mathieu.desnoyers at efficios.com Tue May 1 17:02:06 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 1 May 2012 17:02:06 -0400 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120501194713.GL2441@linux.vnet.ibm.com> References: <20120426165544.795e9c24@nehalam.linuxnetplumber.net> <20120427022608.GA7574@Krystal> <20120430023352.GA16024@Krystal> <20120501141609.GA24046@Krystal> <20120501144924.GB2441@linux.vnet.ibm.com> <20120501151215.GB24840@Krystal> <20120501152144.GA25061@Krystal> <20120501161337.GF2441@linux.vnet.ibm.com> <20120501174136.GA26609@Krystal> <20120501194713.GL2441@linux.vnet.ibm.com> Message-ID: <20120501210206.GA31952@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > On Tue, May 01, 2012 at 01:41:36PM -0400, Mathieu Desnoyers wrote: > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > On Tue, May 01, 2012 at 11:21:44AM -0400, Mathieu Desnoyers wrote: > > > > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > > On Tue, May 01, 2012 at 10:16:09AM -0400, Mathieu Desnoyers wrote: > > > > > > > Hi! > > > > > > > > > > > > > > After 1 year of development, with the last 6-7 months spent polishing > > > > > > > the API and testing the implementation, I think it is getting about time > > > > > > > to release the RCU lock-free hash table in a new Userspace RCU version > > > > > > > (0.7). > > > > > > > > > > > > > > I recently described the guarantees provided by the hash table in more > > > > > > > detail, and created tests for the uniqueness guarantee for traversals > > > > > > > performed concurrently with add_unique and add_replace operations. I > > > > > > > also added test modes that create long hash chains, to test corner-cases > > > > > > > of the hash table. > > > > > > > > > > > > > > One small thing I wonder is whether we should document that the hash > > > > > > > table update operations imply full memory barriers ? > > > > > > > > > > > > The Linux kernel's rule seems good here -- if a hash-table operation is > > > > > > atomic and returns a value, it should imply a full barrier. So: > > > > > > > > > > > > cds_lfht_new(): No point in claiming barriers -- publishing the > > > > > > pointer to the hash table is where the barriers are important. > > > > > > > > > > > > cds_lfht_destroy(): Ditto. > > > > > > > > > > > > cds_lfht_lookup(): Not an update (let alone an atomic update), no barriers. > > > > > > > > > > > > cds_lfht_next_duplicate(): Ditto. > > > > > > > > > > > > cds_lfht_first(): Ditto. > > > > > > > > > > > > cds_lfht_next(): Ditto. > > > > > > > > > > > > cds_lfht_add(): Atomic update, but no return value, so no barrier > > > > > > implied. > > > > > > > > > > Yep, makes sense. We use cmpxchg internally to perform the update, but > > > > > it could make sense to eventually use a cmpxchg that has no memory > > > > > barriers to perform this update. So I agree on not providing a memory > > > > > barrier guarantee on the "add" operation, since it does not return any > > > > > value. > > > > > > > > > > > > > > > > > cds_lfht_add_unique(): Atomic update that returns a value, so should > > > > > > imply a full memory barrier. > > > > > > > > > > add_unique is a bit special: > > > > > > > > > > - if it returns the node received as parameter, it means the add > > > > > succeeded, which imply an update, and thus a memory barrier. > > > > > > > > Hrm, thinking further: if we make the "add" operation not act as a > > > > full memory barrier, then the add_unique success should not act as a > > > > full mb neither. > > > > > > Think of it as being similar to the Linux kernel's atomic_inc() and > > > atomic_add_return() primitives. The latter guarantees memory barriers > > > and the former does not. > > > > I think add/add_unique vs atomic_inc/atomic_add_return are fundamentally > > different. > > > > atomic_inc: > > - input: increment > > - output: none > > - effect: increment target address value > > > > atomic_add_return: > > - input: increment > > - output: incremented value > > - effect: increment target address value, atomically reading the > > resulting value. > > > > hash table add: > > - input: new node to add > > - output: none > > - effect: atomically add the new node into the table > > > > hash table add_unique (success): > > - input: new node to add > > - output: (we just return whether the operation has succeeded) > > - effect: atomically add the new node into the table > > > > hash table add_unique (failure): > > - input: new node to try adding > > - output: (we just return whether the operation has succeeded) > > - effect: simple lookup (read) > > > > So as we see, the add_unique failure only performs a read. Adding a > > memory barrier before this read would require us to add a memory barrier > > also on the success path, which would degrade performance. The success > > path does: lookup failure, cmpxchg to add the node, retry if changed. > > Adding a memory barrier before the lookup would add an extra memory > > barrier in addition to the one located in the cmpxchg, and I don't think > > we want that overhead. > > Perhaps a better analogy is cmpxchg() in the Linux kernel. Some > architectures place the memory barrier before unconditionally, but place > a memory barrier after only if the cmpxchg() succeeds. Of course, > architectures for which the cmpxchg instruction implies a barrier > don't need any explicit memory-barrier instructions. > > I do see your point about the memory barrier in the failure case requiring > an additional memory barrier in the success case, however. > > > > > > - if it returns a different node than the one received as parameter, it > > > > > failed, and thus means that it only performed a lookup, so there is no > > > > > guarantee that a memory barrier has been executed. > > > > > > > > > > > > > > > > > > > > > > cds_lfht_add_replace(): Ditto. > > > > > > > > > > > > cds_lfht_replace(): Ditto. > > > > > > > > > > > > cds_lfht_del(): Ditto. > > > > > > > > One more point: "del" is similar to add_unique: if it succeeds, we > > > > execute a full memory barrier. If it fails, no memory barrier is > > > > guaranteed. But if we want to make the guarantees relax, we might not > > > > want to guarantee that a memory barrier is present in any of the "del" > > > > cases. > > > > > > > > In the end, the only primitives for which I think it really makes sense > > > > to provide memory barrier semantic is the add_replace and replace : they > > > > actually act as an higher-level "cmpxchg" over the hash table nodes. > > > > > > I believe that this should do the same -- memory barrier before, but no > > > memory barrier after on failure. > > > > > > Another approach is C++11, in which there are a couple of arguments to > > > the compare-and-swap primitive specifying the memory ordering constraints > > > for the success and failure cases, respectively. > > > > Hrm, I think adding this kind of flexibility might make the API too > > clobbered by details that "usual cases" don't care about. > > ;-) > > > > Unless you expect use cases with lots of failing cds_lfht_del() and > > > add_unique() calls, the performance difference should not be significant. > > > > The problem is that I expect very, very frequent failing add_unique > > calls for use-cases like Binary Decision Diagrams (BDD) creation. This > > is why I don't think it is appropriate to put memory barriers on the > > failure cases, as these should have no more overhead than a simple > > lookup. > > > > And if we choose not to provide memory barriers for add_unique failure, > > we should probably do the same for "del" to keep a consistent behavior > > over the API. > > > > Thoughts ? > > Given your BDD example, letting the failure cases avoid memory barriers > seems reasonable. If problems arise, the default interfaces can be > fully ordered with faster versions where the failure cases avoid memory > barriers. I think we agree on the failure cases of del and add_unique, which is good. Now, I'm thinking slightly further about the success cases of add, add_unique and del. Typically, when giving a node to add or add_unique for population into the hash table, we have to order the writes that initialize the node before its insertion into the hash table. So I think it would make sense to guarantee that we provide a memory barrier prior to add and add_unique (success) operations. For the "del" case, it's the other way around: if a deletion succeeds, we want to have a memory barrier between the removal flag write and the following "free()" of the element. So we need to ensure that there is a memory barrier after a successful deletion. If we think about it, the "add_replace" acts both as an "add" and "del": in all cases, we need to have a memory barrier before the add_replace, because we need to order the node initialization before the atomic insertion into the hash table, and we also need a memory barrier after, but only really in the case where add_replace replaced an old node, thus acting as a delete of that old node. Considering all this, the barrier semantic I'm proposing is: add: - full memory barrier before the insertion. add_unique: - success: full memory barrier before the insertion. - failure: no memory barrier. replace: - success: full memory barrier before the insertion, and after the removal of the old node. - failure: no memory barrier. add_replace: - returns an old node (replace): full memory barrier before the insertion, and after the removal of the old node. - returns NULL (add): full memory barrier before the insertion. del: - success: full memory barrier after the removal. - failure: no memory barrier. I think those are the minimal barriers we need to provide to ensure that users will not have to add barriers of their own to use the API. Thoughts ? Thanks, Mathieu > > Thanx, Paul > > > Thanks, > > > > Mathieu > > > > > > > > > > Thanx, Paul > > > > > > > Thoughts ? > > > > > > > > Thanks, > > > > > > > > Mathieu > > > > > > > > > > > > > > Yep, makes sense. > > > > > > > > > > I'll add this documentation in the API. > > > > > > > > > > Thanks! > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > cds_lfht_is_node_deleted(): Not an update (let alone an atomic update), > > > > > > no barriers. > > > > > > > > > > > > cds_lfht_resize(): Atomic update, but no return value, so no barrier > > > > > > implied. > > > > > > > > > > > > cds_lfht_for_each(): Not an update (let alone an atomic update), > > > > > > no barriers. > > > > > > > > > > > > cds_lfht_for_each_duplicate(): Ditto. > > > > > > > > > > > > cds_lfht_for_each_entry(): Ditto. > > > > > > > > > > > > cds_lfht_for_each_entry_duplicate(): Ditto. > > > > > > > > > > > > Thanx, Paul > > > > > > > > > > > > > I'm personally getting confident that the hash table API is clean > > > > > > > enough, and the implementation well tested, but I'd like to have your > > > > > > > thoughts on the readiness of the hash table for production use. > > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > -- > > > > > > > Mathieu Desnoyers > > > > > > > Operating System Efficiency R&D Consultant > > > > > > > EfficiOS Inc. > > > > > > > http://www.efficios.com > > > > > > > > > > > > > > _______________________________________________ > > > > > > > rp mailing list > > > > > > > rp at svcs.cs.pdx.edu > > > > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > lttng-dev mailing list > > > > > > lttng-dev at lists.lttng.org > > > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > > > -- > > > > > Mathieu Desnoyers > > > > > Operating System Efficiency R&D Consultant > > > > > EfficiOS Inc. > > > > > http://www.efficios.com > > > > > > > > > > _______________________________________________ > > > > > lttng-dev mailing list > > > > > lttng-dev at lists.lttng.org > > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > -- > > > > Mathieu Desnoyers > > > > Operating System Efficiency R&D Consultant > > > > EfficiOS Inc. > > > > http://www.efficios.com > > > > > > > > _______________________________________________ > > > > rp mailing list > > > > rp at svcs.cs.pdx.edu > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > > > _______________________________________________ > > rp mailing list > > rp at svcs.cs.pdx.edu > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Tue May 1 17:43:16 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 1 May 2012 17:43:16 -0400 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120501210206.GA31952@Krystal> References: <20120427022608.GA7574@Krystal> <20120430023352.GA16024@Krystal> <20120501141609.GA24046@Krystal> <20120501144924.GB2441@linux.vnet.ibm.com> <20120501151215.GB24840@Krystal> <20120501152144.GA25061@Krystal> <20120501161337.GF2441@linux.vnet.ibm.com> <20120501174136.GA26609@Krystal> <20120501194713.GL2441@linux.vnet.ibm.com> <20120501210206.GA31952@Krystal> Message-ID: <20120501214316.GA32549@Krystal> * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: [...] > Now, I'm thinking slightly further about the success cases of add, > add_unique and del. > > Typically, when giving a node to add or add_unique for population into > the hash table, we have to order the writes that initialize the node > before its insertion into the hash table. So I think it would make sense > to guarantee that we provide a memory barrier prior to add and > add_unique (success) operations. > > For the "del" case, it's the other way around: if a deletion succeeds, > we want to have a memory barrier between the removal flag write and the > following "free()" of the element. So we need to ensure that there is a > memory barrier after a successful deletion. > > If we think about it, the "add_replace" acts both as an "add" and "del": > in all cases, we need to have a memory barrier before the add_replace, > because we need to order the node initialization before the atomic > insertion into the hash table, and we also need a memory barrier after, > but only really in the case where add_replace replaced an old node, thus > acting as a delete of that old node. > > Considering all this, the barrier semantic I'm proposing is: > One small modification I'm thinking about: changing every "full memory barrier" below for a "write memory barrier". All we really need to order are writes cs writes, right ? I'm concerned that if we publish an API providing memory ordering semantics guarantees stricter than required, we will never be able to optimize further if we ever need to relax the barriers in the implementation, because users will assume that the full barriers are in place. Thoughts ? Thanks, Mathieu > add: > - full memory barrier before the insertion. > > add_unique: > - success: full memory barrier before the insertion. > - failure: no memory barrier. > > replace: > - success: full memory barrier before the insertion, and after the > removal of the old node. > - failure: no memory barrier. > > add_replace: > - returns an old node (replace): full memory barrier before the > insertion, and after the removal of the old node. > - returns NULL (add): full memory barrier before the insertion. > > del: > - success: full memory barrier after the removal. > - failure: no memory barrier. > > I think those are the minimal barriers we need to provide to ensure that > users will not have to add barriers of their own to use the API. > > Thoughts ? > > Thanks, > > Mathieu > > > > > > Thanx, Paul > > > > > Thanks, > > > > > > Mathieu > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > Thoughts ? > > > > > > > > > > Thanks, > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > Yep, makes sense. > > > > > > > > > > > > I'll add this documentation in the API. > > > > > > > > > > > > Thanks! > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > > > cds_lfht_is_node_deleted(): Not an update (let alone an atomic update), > > > > > > > no barriers. > > > > > > > > > > > > > > cds_lfht_resize(): Atomic update, but no return value, so no barrier > > > > > > > implied. > > > > > > > > > > > > > > cds_lfht_for_each(): Not an update (let alone an atomic update), > > > > > > > no barriers. > > > > > > > > > > > > > > cds_lfht_for_each_duplicate(): Ditto. > > > > > > > > > > > > > > cds_lfht_for_each_entry(): Ditto. > > > > > > > > > > > > > > cds_lfht_for_each_entry_duplicate(): Ditto. > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > > > > > > > I'm personally getting confident that the hash table API is clean > > > > > > > > enough, and the implementation well tested, but I'd like to have your > > > > > > > > thoughts on the readiness of the hash table for production use. > > > > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > -- > > > > > > > > Mathieu Desnoyers > > > > > > > > Operating System Efficiency R&D Consultant > > > > > > > > EfficiOS Inc. > > > > > > > > http://www.efficios.com > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > > rp mailing list > > > > > > > > rp at svcs.cs.pdx.edu > > > > > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > lttng-dev mailing list > > > > > > > lttng-dev at lists.lttng.org > > > > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > > > > > -- > > > > > > Mathieu Desnoyers > > > > > > Operating System Efficiency R&D Consultant > > > > > > EfficiOS Inc. > > > > > > http://www.efficios.com > > > > > > > > > > > > _______________________________________________ > > > > > > lttng-dev mailing list > > > > > > lttng-dev at lists.lttng.org > > > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > > > -- > > > > > Mathieu Desnoyers > > > > > Operating System Efficiency R&D Consultant > > > > > EfficiOS Inc. > > > > > http://www.efficios.com > > > > > > > > > > _______________________________________________ > > > > > rp mailing list > > > > > rp at svcs.cs.pdx.edu > > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > > > -- > > > Mathieu Desnoyers > > > Operating System Efficiency R&D Consultant > > > EfficiOS Inc. > > > http://www.efficios.com > > > > > > _______________________________________________ > > > rp mailing list > > > rp at svcs.cs.pdx.edu > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From paulmck at linux.vnet.ibm.com Tue May 1 19:50:07 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Tue, 1 May 2012 16:50:07 -0700 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120501210206.GA31952@Krystal> References: <20120427022608.GA7574@Krystal> <20120430023352.GA16024@Krystal> <20120501141609.GA24046@Krystal> <20120501144924.GB2441@linux.vnet.ibm.com> <20120501151215.GB24840@Krystal> <20120501152144.GA25061@Krystal> <20120501161337.GF2441@linux.vnet.ibm.com> <20120501174136.GA26609@Krystal> <20120501194713.GL2441@linux.vnet.ibm.com> <20120501210206.GA31952@Krystal> Message-ID: <20120501235007.GS2441@linux.vnet.ibm.com> On Tue, May 01, 2012 at 05:02:06PM -0400, Mathieu Desnoyers wrote: > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > On Tue, May 01, 2012 at 01:41:36PM -0400, Mathieu Desnoyers wrote: > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > On Tue, May 01, 2012 at 11:21:44AM -0400, Mathieu Desnoyers wrote: > > > > > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > > > On Tue, May 01, 2012 at 10:16:09AM -0400, Mathieu Desnoyers wrote: > > > > > > > > Hi! > > > > > > > > > > > > > > > > After 1 year of development, with the last 6-7 months spent polishing > > > > > > > > the API and testing the implementation, I think it is getting about time > > > > > > > > to release the RCU lock-free hash table in a new Userspace RCU version > > > > > > > > (0.7). > > > > > > > > > > > > > > > > I recently described the guarantees provided by the hash table in more > > > > > > > > detail, and created tests for the uniqueness guarantee for traversals > > > > > > > > performed concurrently with add_unique and add_replace operations. I > > > > > > > > also added test modes that create long hash chains, to test corner-cases > > > > > > > > of the hash table. > > > > > > > > > > > > > > > > One small thing I wonder is whether we should document that the hash > > > > > > > > table update operations imply full memory barriers ? > > > > > > > > > > > > > > The Linux kernel's rule seems good here -- if a hash-table operation is > > > > > > > atomic and returns a value, it should imply a full barrier. So: > > > > > > > > > > > > > > cds_lfht_new(): No point in claiming barriers -- publishing the > > > > > > > pointer to the hash table is where the barriers are important. > > > > > > > > > > > > > > cds_lfht_destroy(): Ditto. > > > > > > > > > > > > > > cds_lfht_lookup(): Not an update (let alone an atomic update), no barriers. > > > > > > > > > > > > > > cds_lfht_next_duplicate(): Ditto. > > > > > > > > > > > > > > cds_lfht_first(): Ditto. > > > > > > > > > > > > > > cds_lfht_next(): Ditto. > > > > > > > > > > > > > > cds_lfht_add(): Atomic update, but no return value, so no barrier > > > > > > > implied. > > > > > > > > > > > > Yep, makes sense. We use cmpxchg internally to perform the update, but > > > > > > it could make sense to eventually use a cmpxchg that has no memory > > > > > > barriers to perform this update. So I agree on not providing a memory > > > > > > barrier guarantee on the "add" operation, since it does not return any > > > > > > value. > > > > > > > > > > > > > > > > > > > > cds_lfht_add_unique(): Atomic update that returns a value, so should > > > > > > > imply a full memory barrier. > > > > > > > > > > > > add_unique is a bit special: > > > > > > > > > > > > - if it returns the node received as parameter, it means the add > > > > > > succeeded, which imply an update, and thus a memory barrier. > > > > > > > > > > Hrm, thinking further: if we make the "add" operation not act as a > > > > > full memory barrier, then the add_unique success should not act as a > > > > > full mb neither. > > > > > > > > Think of it as being similar to the Linux kernel's atomic_inc() and > > > > atomic_add_return() primitives. The latter guarantees memory barriers > > > > and the former does not. > > > > > > I think add/add_unique vs atomic_inc/atomic_add_return are fundamentally > > > different. > > > > > > atomic_inc: > > > - input: increment > > > - output: none > > > - effect: increment target address value > > > > > > atomic_add_return: > > > - input: increment > > > - output: incremented value > > > - effect: increment target address value, atomically reading the > > > resulting value. > > > > > > hash table add: > > > - input: new node to add > > > - output: none > > > - effect: atomically add the new node into the table > > > > > > hash table add_unique (success): > > > - input: new node to add > > > - output: (we just return whether the operation has succeeded) > > > - effect: atomically add the new node into the table > > > > > > hash table add_unique (failure): > > > - input: new node to try adding > > > - output: (we just return whether the operation has succeeded) > > > - effect: simple lookup (read) > > > > > > So as we see, the add_unique failure only performs a read. Adding a > > > memory barrier before this read would require us to add a memory barrier > > > also on the success path, which would degrade performance. The success > > > path does: lookup failure, cmpxchg to add the node, retry if changed. > > > Adding a memory barrier before the lookup would add an extra memory > > > barrier in addition to the one located in the cmpxchg, and I don't think > > > we want that overhead. > > > > Perhaps a better analogy is cmpxchg() in the Linux kernel. Some > > architectures place the memory barrier before unconditionally, but place > > a memory barrier after only if the cmpxchg() succeeds. Of course, > > architectures for which the cmpxchg instruction implies a barrier > > don't need any explicit memory-barrier instructions. > > > > I do see your point about the memory barrier in the failure case requiring > > an additional memory barrier in the success case, however. > > > > > > > > - if it returns a different node than the one received as parameter, it > > > > > > failed, and thus means that it only performed a lookup, so there is no > > > > > > guarantee that a memory barrier has been executed. > > > > > > > > > > > > > > > > > > > > > > > > > > cds_lfht_add_replace(): Ditto. > > > > > > > > > > > > > > cds_lfht_replace(): Ditto. > > > > > > > > > > > > > > cds_lfht_del(): Ditto. > > > > > > > > > > One more point: "del" is similar to add_unique: if it succeeds, we > > > > > execute a full memory barrier. If it fails, no memory barrier is > > > > > guaranteed. But if we want to make the guarantees relax, we might not > > > > > want to guarantee that a memory barrier is present in any of the "del" > > > > > cases. > > > > > > > > > > In the end, the only primitives for which I think it really makes sense > > > > > to provide memory barrier semantic is the add_replace and replace : they > > > > > actually act as an higher-level "cmpxchg" over the hash table nodes. > > > > > > > > I believe that this should do the same -- memory barrier before, but no > > > > memory barrier after on failure. > > > > > > > > Another approach is C++11, in which there are a couple of arguments to > > > > the compare-and-swap primitive specifying the memory ordering constraints > > > > for the success and failure cases, respectively. > > > > > > Hrm, I think adding this kind of flexibility might make the API too > > > clobbered by details that "usual cases" don't care about. > > > > ;-) > > > > > > Unless you expect use cases with lots of failing cds_lfht_del() and > > > > add_unique() calls, the performance difference should not be significant. > > > > > > The problem is that I expect very, very frequent failing add_unique > > > calls for use-cases like Binary Decision Diagrams (BDD) creation. This > > > is why I don't think it is appropriate to put memory barriers on the > > > failure cases, as these should have no more overhead than a simple > > > lookup. > > > > > > And if we choose not to provide memory barriers for add_unique failure, > > > we should probably do the same for "del" to keep a consistent behavior > > > over the API. > > > > > > Thoughts ? > > > > Given your BDD example, letting the failure cases avoid memory barriers > > seems reasonable. If problems arise, the default interfaces can be > > fully ordered with faster versions where the failure cases avoid memory > > barriers. > > I think we agree on the failure cases of del and add_unique, which is > good. > > Now, I'm thinking slightly further about the success cases of add, > add_unique and del. > > Typically, when giving a node to add or add_unique for population into > the hash table, we have to order the writes that initialize the node > before its insertion into the hash table. So I think it would make sense > to guarantee that we provide a memory barrier prior to add and > add_unique (success) operations. > > For the "del" case, it's the other way around: if a deletion succeeds, > we want to have a memory barrier between the removal flag write and the > following "free()" of the element. So we need to ensure that there is a > memory barrier after a successful deletion. > > If we think about it, the "add_replace" acts both as an "add" and "del": > in all cases, we need to have a memory barrier before the add_replace, > because we need to order the node initialization before the atomic > insertion into the hash table, and we also need a memory barrier after, > but only really in the case where add_replace replaced an old node, thus > acting as a delete of that old node. > > Considering all this, the barrier semantic I'm proposing is: > > add: > - full memory barrier before the insertion. > > add_unique: > - success: full memory barrier before the insertion. > - failure: no memory barrier. > > replace: > - success: full memory barrier before the insertion, and after the > removal of the old node. > - failure: no memory barrier. > > add_replace: > - returns an old node (replace): full memory barrier before the > insertion, and after the removal of the old node. > - returns NULL (add): full memory barrier before the insertion. > > del: > - success: full memory barrier after the removal. > - failure: no memory barrier. > > I think those are the minimal barriers we need to provide to ensure that > users will not have to add barriers of their own to use the API. > > Thoughts ? This means that some other CPU might see an add followed by a del as happening in the opposite order. Is that really OK? Thanx, Paul > Thanks, > > Mathieu > > > > > > Thanx, Paul > > > > > Thanks, > > > > > > Mathieu > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > Thoughts ? > > > > > > > > > > Thanks, > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > Yep, makes sense. > > > > > > > > > > > > I'll add this documentation in the API. > > > > > > > > > > > > Thanks! > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > > > cds_lfht_is_node_deleted(): Not an update (let alone an atomic update), > > > > > > > no barriers. > > > > > > > > > > > > > > cds_lfht_resize(): Atomic update, but no return value, so no barrier > > > > > > > implied. > > > > > > > > > > > > > > cds_lfht_for_each(): Not an update (let alone an atomic update), > > > > > > > no barriers. > > > > > > > > > > > > > > cds_lfht_for_each_duplicate(): Ditto. > > > > > > > > > > > > > > cds_lfht_for_each_entry(): Ditto. > > > > > > > > > > > > > > cds_lfht_for_each_entry_duplicate(): Ditto. > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > > > > > > > I'm personally getting confident that the hash table API is clean > > > > > > > > enough, and the implementation well tested, but I'd like to have your > > > > > > > > thoughts on the readiness of the hash table for production use. > > > > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > -- > > > > > > > > Mathieu Desnoyers > > > > > > > > Operating System Efficiency R&D Consultant > > > > > > > > EfficiOS Inc. > > > > > > > > http://www.efficios.com > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > > rp mailing list > > > > > > > > rp at svcs.cs.pdx.edu > > > > > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > lttng-dev mailing list > > > > > > > lttng-dev at lists.lttng.org > > > > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > > > > > -- > > > > > > Mathieu Desnoyers > > > > > > Operating System Efficiency R&D Consultant > > > > > > EfficiOS Inc. > > > > > > http://www.efficios.com > > > > > > > > > > > > _______________________________________________ > > > > > > lttng-dev mailing list > > > > > > lttng-dev at lists.lttng.org > > > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > > > -- > > > > > Mathieu Desnoyers > > > > > Operating System Efficiency R&D Consultant > > > > > EfficiOS Inc. > > > > > http://www.efficios.com > > > > > > > > > > _______________________________________________ > > > > > rp mailing list > > > > > rp at svcs.cs.pdx.edu > > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > > > -- > > > Mathieu Desnoyers > > > Operating System Efficiency R&D Consultant > > > EfficiOS Inc. > > > http://www.efficios.com > > > > > > _______________________________________________ > > > rp mailing list > > > rp at svcs.cs.pdx.edu > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > From mathieu.desnoyers at efficios.com Wed May 2 00:16:39 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 2 May 2012 00:16:39 -0400 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120501235007.GS2441@linux.vnet.ibm.com> References: <20120430023352.GA16024@Krystal> <20120501141609.GA24046@Krystal> <20120501144924.GB2441@linux.vnet.ibm.com> <20120501151215.GB24840@Krystal> <20120501152144.GA25061@Krystal> <20120501161337.GF2441@linux.vnet.ibm.com> <20120501174136.GA26609@Krystal> <20120501194713.GL2441@linux.vnet.ibm.com> <20120501210206.GA31952@Krystal> <20120501235007.GS2441@linux.vnet.ibm.com> Message-ID: <20120502041639.GA7857@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > On Tue, May 01, 2012 at 05:02:06PM -0400, Mathieu Desnoyers wrote: > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > On Tue, May 01, 2012 at 01:41:36PM -0400, Mathieu Desnoyers wrote: > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > On Tue, May 01, 2012 at 11:21:44AM -0400, Mathieu Desnoyers wrote: > > > > > > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > > > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > > > > On Tue, May 01, 2012 at 10:16:09AM -0400, Mathieu Desnoyers wrote: > > > > > > > > > Hi! > > > > > > > > > > > > > > > > > > After 1 year of development, with the last 6-7 months spent polishing > > > > > > > > > the API and testing the implementation, I think it is getting about time > > > > > > > > > to release the RCU lock-free hash table in a new Userspace RCU version > > > > > > > > > (0.7). > > > > > > > > > > > > > > > > > > I recently described the guarantees provided by the hash table in more > > > > > > > > > detail, and created tests for the uniqueness guarantee for traversals > > > > > > > > > performed concurrently with add_unique and add_replace operations. I > > > > > > > > > also added test modes that create long hash chains, to test corner-cases > > > > > > > > > of the hash table. > > > > > > > > > > > > > > > > > > One small thing I wonder is whether we should document that the hash > > > > > > > > > table update operations imply full memory barriers ? > > > > > > > > > > > > > > > > The Linux kernel's rule seems good here -- if a hash-table operation is > > > > > > > > atomic and returns a value, it should imply a full barrier. So: > > > > > > > > > > > > > > > > cds_lfht_new(): No point in claiming barriers -- publishing the > > > > > > > > pointer to the hash table is where the barriers are important. > > > > > > > > > > > > > > > > cds_lfht_destroy(): Ditto. > > > > > > > > > > > > > > > > cds_lfht_lookup(): Not an update (let alone an atomic update), no barriers. > > > > > > > > > > > > > > > > cds_lfht_next_duplicate(): Ditto. > > > > > > > > > > > > > > > > cds_lfht_first(): Ditto. > > > > > > > > > > > > > > > > cds_lfht_next(): Ditto. > > > > > > > > > > > > > > > > cds_lfht_add(): Atomic update, but no return value, so no barrier > > > > > > > > implied. > > > > > > > > > > > > > > Yep, makes sense. We use cmpxchg internally to perform the update, but > > > > > > > it could make sense to eventually use a cmpxchg that has no memory > > > > > > > barriers to perform this update. So I agree on not providing a memory > > > > > > > barrier guarantee on the "add" operation, since it does not return any > > > > > > > value. > > > > > > > > > > > > > > > > > > > > > > > cds_lfht_add_unique(): Atomic update that returns a value, so should > > > > > > > > imply a full memory barrier. > > > > > > > > > > > > > > add_unique is a bit special: > > > > > > > > > > > > > > - if it returns the node received as parameter, it means the add > > > > > > > succeeded, which imply an update, and thus a memory barrier. > > > > > > > > > > > > Hrm, thinking further: if we make the "add" operation not act as a > > > > > > full memory barrier, then the add_unique success should not act as a > > > > > > full mb neither. > > > > > > > > > > Think of it as being similar to the Linux kernel's atomic_inc() and > > > > > atomic_add_return() primitives. The latter guarantees memory barriers > > > > > and the former does not. > > > > > > > > I think add/add_unique vs atomic_inc/atomic_add_return are fundamentally > > > > different. > > > > > > > > atomic_inc: > > > > - input: increment > > > > - output: none > > > > - effect: increment target address value > > > > > > > > atomic_add_return: > > > > - input: increment > > > > - output: incremented value > > > > - effect: increment target address value, atomically reading the > > > > resulting value. > > > > > > > > hash table add: > > > > - input: new node to add > > > > - output: none > > > > - effect: atomically add the new node into the table > > > > > > > > hash table add_unique (success): > > > > - input: new node to add > > > > - output: (we just return whether the operation has succeeded) > > > > - effect: atomically add the new node into the table > > > > > > > > hash table add_unique (failure): > > > > - input: new node to try adding > > > > - output: (we just return whether the operation has succeeded) > > > > - effect: simple lookup (read) > > > > > > > > So as we see, the add_unique failure only performs a read. Adding a > > > > memory barrier before this read would require us to add a memory barrier > > > > also on the success path, which would degrade performance. The success > > > > path does: lookup failure, cmpxchg to add the node, retry if changed. > > > > Adding a memory barrier before the lookup would add an extra memory > > > > barrier in addition to the one located in the cmpxchg, and I don't think > > > > we want that overhead. > > > > > > Perhaps a better analogy is cmpxchg() in the Linux kernel. Some > > > architectures place the memory barrier before unconditionally, but place > > > a memory barrier after only if the cmpxchg() succeeds. Of course, > > > architectures for which the cmpxchg instruction implies a barrier > > > don't need any explicit memory-barrier instructions. > > > > > > I do see your point about the memory barrier in the failure case requiring > > > an additional memory barrier in the success case, however. > > > > > > > > > > - if it returns a different node than the one received as parameter, it > > > > > > > failed, and thus means that it only performed a lookup, so there is no > > > > > > > guarantee that a memory barrier has been executed. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > cds_lfht_add_replace(): Ditto. > > > > > > > > > > > > > > > > cds_lfht_replace(): Ditto. > > > > > > > > > > > > > > > > cds_lfht_del(): Ditto. > > > > > > > > > > > > One more point: "del" is similar to add_unique: if it succeeds, we > > > > > > execute a full memory barrier. If it fails, no memory barrier is > > > > > > guaranteed. But if we want to make the guarantees relax, we might not > > > > > > want to guarantee that a memory barrier is present in any of the "del" > > > > > > cases. > > > > > > > > > > > > In the end, the only primitives for which I think it really makes sense > > > > > > to provide memory barrier semantic is the add_replace and replace : they > > > > > > actually act as an higher-level "cmpxchg" over the hash table nodes. > > > > > > > > > > I believe that this should do the same -- memory barrier before, but no > > > > > memory barrier after on failure. > > > > > > > > > > Another approach is C++11, in which there are a couple of arguments to > > > > > the compare-and-swap primitive specifying the memory ordering constraints > > > > > for the success and failure cases, respectively. > > > > > > > > Hrm, I think adding this kind of flexibility might make the API too > > > > clobbered by details that "usual cases" don't care about. > > > > > > ;-) > > > > > > > > Unless you expect use cases with lots of failing cds_lfht_del() and > > > > > add_unique() calls, the performance difference should not be significant. > > > > > > > > The problem is that I expect very, very frequent failing add_unique > > > > calls for use-cases like Binary Decision Diagrams (BDD) creation. This > > > > is why I don't think it is appropriate to put memory barriers on the > > > > failure cases, as these should have no more overhead than a simple > > > > lookup. > > > > > > > > And if we choose not to provide memory barriers for add_unique failure, > > > > we should probably do the same for "del" to keep a consistent behavior > > > > over the API. > > > > > > > > Thoughts ? > > > > > > Given your BDD example, letting the failure cases avoid memory barriers > > > seems reasonable. If problems arise, the default interfaces can be > > > fully ordered with faster versions where the failure cases avoid memory > > > barriers. > > > > I think we agree on the failure cases of del and add_unique, which is > > good. > > > > Now, I'm thinking slightly further about the success cases of add, > > add_unique and del. > > > > Typically, when giving a node to add or add_unique for population into > > the hash table, we have to order the writes that initialize the node > > before its insertion into the hash table. So I think it would make sense > > to guarantee that we provide a memory barrier prior to add and > > add_unique (success) operations. > > > > For the "del" case, it's the other way around: if a deletion succeeds, > > we want to have a memory barrier between the removal flag write and the > > following "free()" of the element. So we need to ensure that there is a > > memory barrier after a successful deletion. > > > > If we think about it, the "add_replace" acts both as an "add" and "del": > > in all cases, we need to have a memory barrier before the add_replace, > > because we need to order the node initialization before the atomic > > insertion into the hash table, and we also need a memory barrier after, > > but only really in the case where add_replace replaced an old node, thus > > acting as a delete of that old node. > > > > Considering all this, the barrier semantic I'm proposing is: > > > > add: > > - full memory barrier before the insertion. > > > > add_unique: > > - success: full memory barrier before the insertion. > > - failure: no memory barrier. > > > > replace: > > - success: full memory barrier before the insertion, and after the > > removal of the old node. > > - failure: no memory barrier. > > > > add_replace: > > - returns an old node (replace): full memory barrier before the > > insertion, and after the removal of the old node. > > - returns NULL (add): full memory barrier before the insertion. > > > > del: > > - success: full memory barrier after the removal. > > - failure: no memory barrier. > > > > I think those are the minimal barriers we need to provide to ensure that > > users will not have to add barriers of their own to use the API. > > > > Thoughts ? > > This means that some other CPU might see an add followed by a del as > happening in the opposite order. Is that really OK? Here I suppose you are talking about add and del that touch different nodes, since add/del touching the same node would modify the same memory location, so both operations would be seen in the right order by the other processors. I guess the question here is: how does the remote CPU observe this ? Is it from a read-side traversal, or from update operations performed on the remote CPU ? Or from lookups of arbitrary key values ? Or from other update operations ? For read-side traversal, given the traversal within a single hash chain goes from newer nodes to older nodes, the sequence "add" then "del", adding a new node, then deleting an old one (e.g. from the same hash chain) first adds the new node to the beginning of the hash chain, and then removes the old node that is later in the chain (in traversal order). In this case, if the "del" is published before the "add", this is entirely equivalent to have a read-side traversal that misses the added node, but sees the effect of the "del". In terms of read-side traversal, what we seem to care about is more the "del" then "add" performed on different nodes (e.g. of the same hash chain): given that the "add" is at the beginning of the chain, and "del" is somewhere within the chain, a read-side traversal that observes the "add" would _always_ observe the effect of a prior "del". Thankfully, "del" then "add" is ordered in the scheme I propose, thanks to the memory barrier after "del" and also the one before "add". For traversal of the entire table (not just same hash chain), the traversal vs key order is random, so we cannot assume anything about the observation order of add/del of different keys. If we perform two lookups of different keys, without explicit memory barriers between the lookups, we already have no guarantee whatsoever that the published information will be brought into the observer CPU in the right order: IOW, the lookups of different keys can be reordered. So I guess we don't care about add vs del ordering on the publish side for that one. The other scenarios I see are related to update operations (add, add_unique, add_replace, replace, del). If a sequence of these operations is executed on the "observer" CPU, and expects to see the effect of the sequence of "add" then "del" performed on the "publisher" CPU in order, then, yes, an additional memory barrier would be required to order add before del. The question here is: do we care about providing order of add before del only for the sake of the other update operations running on another CPU that would expect to see their effect in order ? I don't know, maybe. I guess the safest route would be to provide the ordering guarantee, given that there exists a way to observe this and possibly care about it. I wonder if it would be better to put the barrier after the add/add_unique (success), or before the "del". Also, do you think a write barrier would be sufficient, or we should keep full barriers ? Thanks, Mathieu > > Thanx, Paul > > > Thanks, > > > > Mathieu > > > > > > > > > > Thanx, Paul > > > > > > > Thanks, > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > > > Thoughts ? > > > > > > > > > > > > Thanks, > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > > > Yep, makes sense. > > > > > > > > > > > > > > I'll add this documentation in the API. > > > > > > > > > > > > > > Thanks! > > > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > > > > > > cds_lfht_is_node_deleted(): Not an update (let alone an atomic update), > > > > > > > > no barriers. > > > > > > > > > > > > > > > > cds_lfht_resize(): Atomic update, but no return value, so no barrier > > > > > > > > implied. > > > > > > > > > > > > > > > > cds_lfht_for_each(): Not an update (let alone an atomic update), > > > > > > > > no barriers. > > > > > > > > > > > > > > > > cds_lfht_for_each_duplicate(): Ditto. > > > > > > > > > > > > > > > > cds_lfht_for_each_entry(): Ditto. > > > > > > > > > > > > > > > > cds_lfht_for_each_entry_duplicate(): Ditto. > > > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > > > > > > > > > I'm personally getting confident that the hash table API is clean > > > > > > > > > enough, and the implementation well tested, but I'd like to have your > > > > > > > > > thoughts on the readiness of the hash table for production use. > > > > > > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > -- > > > > > > > > > Mathieu Desnoyers > > > > > > > > > Operating System Efficiency R&D Consultant > > > > > > > > > EfficiOS Inc. > > > > > > > > > http://www.efficios.com > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > > > rp mailing list > > > > > > > > > rp at svcs.cs.pdx.edu > > > > > > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > > lttng-dev mailing list > > > > > > > > lttng-dev at lists.lttng.org > > > > > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > > > > > > > -- > > > > > > > Mathieu Desnoyers > > > > > > > Operating System Efficiency R&D Consultant > > > > > > > EfficiOS Inc. > > > > > > > http://www.efficios.com > > > > > > > > > > > > > > _______________________________________________ > > > > > > > lttng-dev mailing list > > > > > > > lttng-dev at lists.lttng.org > > > > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > > > > > -- > > > > > > Mathieu Desnoyers > > > > > > Operating System Efficiency R&D Consultant > > > > > > EfficiOS Inc. > > > > > > http://www.efficios.com > > > > > > > > > > > > _______________________________________________ > > > > > > rp mailing list > > > > > > rp at svcs.cs.pdx.edu > > > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > > > > > > > -- > > > > Mathieu Desnoyers > > > > Operating System Efficiency R&D Consultant > > > > EfficiOS Inc. > > > > http://www.efficios.com > > > > > > > > _______________________________________________ > > > > rp mailing list > > > > rp at svcs.cs.pdx.edu > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > _______________________________________________ > > > lttng-dev mailing list > > > lttng-dev at lists.lttng.org > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From Paul_Woegerer at mentor.com Wed May 2 07:04:19 2012 From: Paul_Woegerer at mentor.com (Woegerer, Paul) Date: Wed, 02 May 2012 13:04:19 +0200 Subject: [lttng-dev] lttng enable-channel option for blocking In-Reply-To: <20120430142026.GA31622@Krystal> References: <4F992213.2090103@mentor.com> <20120426211627.GB1646@Krystal> <4F9A4A91.7090102@mentor.com> <20120427113321.GA6987@Krystal> <4F9A87F3.5090504@mentor.com> <20120427124344.GB21048@Krystal> <4F9AC627.2090203@mentor.com> <20120430142026.GA31622@Krystal> Message-ID: <4FA114B3.1040108@mentor.com> On 04/30/2012 04:20 PM, Mathieu Desnoyers wrote: > * Woegerer, Paul (Paul_Woegerer at mentor.com) wrote: >> On 04/27/2012 02:43 PM, Mathieu Desnoyers wrote: >>> * Woegerer, Paul (Paul_Woegerer at mentor.com) wrote: >>>> On 04/27/2012 01:33 PM, Mathieu Desnoyers wrote: >>>>> A core difference between ulimit and user-space tracing is that ulimit >>>>> can only be set within the environment (and access right) of the user >>>>> running the application. System-wide tracing sessions can be initiated >>>>> by users member of the "tracing" group -- giving them the ability to >>>>> potentially DoS an application does not appear to me to be a good >>>>> security practice. Thoughts ? >>>> Hmm, how would that look in practice ? Lets assume there is the web >>>> server which was started by an init-script in runlevel 3. How does a >>>> user that belongs to group tracing hava a chance to DoS the already >>>> running running web server. As far as I understand the trace session >>>> concept every tracing user can only see (and affect) the tracing session >>>> that he initiated. Even if the web server itself runs in a tracing >>>> session (of user wwwrun) other tracing users wouldn't see it when they >>>> do a "lttng list", right ? >>> Let me clarify the concept of tracing session in lttng 2.0. >>> >>> We support launching per-user sessiond, which only interact with the >>> user's applications. That's all fine with security. >>> >>> Now, we also support a root system-wide sessiond, which allows kernel >>> and user-space tracing. The "tracing" group has every right to create a >>> tracing session and trace the kernel and _all_ applications that were >>> already or will be running on the system. >> Ah, I see. I was not aware of the "... and _all_ applications that were >> already or will be running on the system" aspect of the concept. In that >> case I would rather invert the semantic in the API and instead of having >> a tracepoint() function that potentially blocks I would declare >> tracepoint() to never ever block and additionally provide tracepointb() >> that does potentially block. > So keeping this in mind, one way to allow this kind of "blocking" mode > might be to add a special option to the lttng-sessiond, e.g. a > "--developer" mode, which could enable this feature, and possibly other > features that are not "safe" to deploy on production machines. Sounds good. Our need for blocking channels is only during development phase. In case of blocking it would be useful to emit a meta-event to indicate that blocking happened. This allows to (optionally) factor out blocking periods from event data visualizations. Thanks, Paul PS: A more general question: In the light of the upcoming event streaming support for LTTng, is it intended to use lttng for "regular" event based real-time communication (non-tracing/debugging related) as well. From that perspective, support for blocking (reliably emitted events) would become mandatory (there might be events of kind cooling_system_deactivated, containment_leakage_detected, ...). > > Thoughts ? > > Thanks, > > Mathieu > -- Paul Woegerer | SW Development Engineer Mentor Embedded(tm) | Prinz Eugen Stra?e 72/2/4, Vienna, 1040 Austria P 43.1.535991320 Nucleus? | Linux? | Android(tm) | Services | UI | Multi-OS Android is a trademark of Google Inc. Use of this trademark is subject to Google Permissions. Linux is the registered trademark of Linus Torvalds in the U.S. and other countries. From paulmck at linux.vnet.ibm.com Wed May 2 11:54:30 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Wed, 2 May 2012 08:54:30 -0700 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120502041639.GA7857@Krystal> References: <20120501141609.GA24046@Krystal> <20120501144924.GB2441@linux.vnet.ibm.com> <20120501151215.GB24840@Krystal> <20120501152144.GA25061@Krystal> <20120501161337.GF2441@linux.vnet.ibm.com> <20120501174136.GA26609@Krystal> <20120501194713.GL2441@linux.vnet.ibm.com> <20120501210206.GA31952@Krystal> <20120501235007.GS2441@linux.vnet.ibm.com> <20120502041639.GA7857@Krystal> Message-ID: <20120502155430.GF2450@linux.vnet.ibm.com> On Wed, May 02, 2012 at 12:16:39AM -0400, Mathieu Desnoyers wrote: > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > On Tue, May 01, 2012 at 05:02:06PM -0400, Mathieu Desnoyers wrote: > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > On Tue, May 01, 2012 at 01:41:36PM -0400, Mathieu Desnoyers wrote: > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > > On Tue, May 01, 2012 at 11:21:44AM -0400, Mathieu Desnoyers wrote: > > > > > > > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > > > > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > > > > > On Tue, May 01, 2012 at 10:16:09AM -0400, Mathieu Desnoyers wrote: > > > > > > > > > > Hi! > > > > > > > > > > > > > > > > > > > > After 1 year of development, with the last 6-7 months spent polishing > > > > > > > > > > the API and testing the implementation, I think it is getting about time > > > > > > > > > > to release the RCU lock-free hash table in a new Userspace RCU version > > > > > > > > > > (0.7). > > > > > > > > > > > > > > > > > > > > I recently described the guarantees provided by the hash table in more > > > > > > > > > > detail, and created tests for the uniqueness guarantee for traversals > > > > > > > > > > performed concurrently with add_unique and add_replace operations. I > > > > > > > > > > also added test modes that create long hash chains, to test corner-cases > > > > > > > > > > of the hash table. > > > > > > > > > > > > > > > > > > > > One small thing I wonder is whether we should document that the hash > > > > > > > > > > table update operations imply full memory barriers ? > > > > > > > > > > > > > > > > > > The Linux kernel's rule seems good here -- if a hash-table operation is > > > > > > > > > atomic and returns a value, it should imply a full barrier. So: > > > > > > > > > > > > > > > > > > cds_lfht_new(): No point in claiming barriers -- publishing the > > > > > > > > > pointer to the hash table is where the barriers are important. > > > > > > > > > > > > > > > > > > cds_lfht_destroy(): Ditto. > > > > > > > > > > > > > > > > > > cds_lfht_lookup(): Not an update (let alone an atomic update), no barriers. > > > > > > > > > > > > > > > > > > cds_lfht_next_duplicate(): Ditto. > > > > > > > > > > > > > > > > > > cds_lfht_first(): Ditto. > > > > > > > > > > > > > > > > > > cds_lfht_next(): Ditto. > > > > > > > > > > > > > > > > > > cds_lfht_add(): Atomic update, but no return value, so no barrier > > > > > > > > > implied. > > > > > > > > > > > > > > > > Yep, makes sense. We use cmpxchg internally to perform the update, but > > > > > > > > it could make sense to eventually use a cmpxchg that has no memory > > > > > > > > barriers to perform this update. So I agree on not providing a memory > > > > > > > > barrier guarantee on the "add" operation, since it does not return any > > > > > > > > value. > > > > > > > > > > > > > > > > > > > > > > > > > > cds_lfht_add_unique(): Atomic update that returns a value, so should > > > > > > > > > imply a full memory barrier. > > > > > > > > > > > > > > > > add_unique is a bit special: > > > > > > > > > > > > > > > > - if it returns the node received as parameter, it means the add > > > > > > > > succeeded, which imply an update, and thus a memory barrier. > > > > > > > > > > > > > > Hrm, thinking further: if we make the "add" operation not act as a > > > > > > > full memory barrier, then the add_unique success should not act as a > > > > > > > full mb neither. > > > > > > > > > > > > Think of it as being similar to the Linux kernel's atomic_inc() and > > > > > > atomic_add_return() primitives. The latter guarantees memory barriers > > > > > > and the former does not. > > > > > > > > > > I think add/add_unique vs atomic_inc/atomic_add_return are fundamentally > > > > > different. > > > > > > > > > > atomic_inc: > > > > > - input: increment > > > > > - output: none > > > > > - effect: increment target address value > > > > > > > > > > atomic_add_return: > > > > > - input: increment > > > > > - output: incremented value > > > > > - effect: increment target address value, atomically reading the > > > > > resulting value. > > > > > > > > > > hash table add: > > > > > - input: new node to add > > > > > - output: none > > > > > - effect: atomically add the new node into the table > > > > > > > > > > hash table add_unique (success): > > > > > - input: new node to add > > > > > - output: (we just return whether the operation has succeeded) > > > > > - effect: atomically add the new node into the table > > > > > > > > > > hash table add_unique (failure): > > > > > - input: new node to try adding > > > > > - output: (we just return whether the operation has succeeded) > > > > > - effect: simple lookup (read) > > > > > > > > > > So as we see, the add_unique failure only performs a read. Adding a > > > > > memory barrier before this read would require us to add a memory barrier > > > > > also on the success path, which would degrade performance. The success > > > > > path does: lookup failure, cmpxchg to add the node, retry if changed. > > > > > Adding a memory barrier before the lookup would add an extra memory > > > > > barrier in addition to the one located in the cmpxchg, and I don't think > > > > > we want that overhead. > > > > > > > > Perhaps a better analogy is cmpxchg() in the Linux kernel. Some > > > > architectures place the memory barrier before unconditionally, but place > > > > a memory barrier after only if the cmpxchg() succeeds. Of course, > > > > architectures for which the cmpxchg instruction implies a barrier > > > > don't need any explicit memory-barrier instructions. > > > > > > > > I do see your point about the memory barrier in the failure case requiring > > > > an additional memory barrier in the success case, however. > > > > > > > > > > > > - if it returns a different node than the one received as parameter, it > > > > > > > > failed, and thus means that it only performed a lookup, so there is no > > > > > > > > guarantee that a memory barrier has been executed. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > cds_lfht_add_replace(): Ditto. > > > > > > > > > > > > > > > > > > cds_lfht_replace(): Ditto. > > > > > > > > > > > > > > > > > > cds_lfht_del(): Ditto. > > > > > > > > > > > > > > One more point: "del" is similar to add_unique: if it succeeds, we > > > > > > > execute a full memory barrier. If it fails, no memory barrier is > > > > > > > guaranteed. But if we want to make the guarantees relax, we might not > > > > > > > want to guarantee that a memory barrier is present in any of the "del" > > > > > > > cases. > > > > > > > > > > > > > > In the end, the only primitives for which I think it really makes sense > > > > > > > to provide memory barrier semantic is the add_replace and replace : they > > > > > > > actually act as an higher-level "cmpxchg" over the hash table nodes. > > > > > > > > > > > > I believe that this should do the same -- memory barrier before, but no > > > > > > memory barrier after on failure. > > > > > > > > > > > > Another approach is C++11, in which there are a couple of arguments to > > > > > > the compare-and-swap primitive specifying the memory ordering constraints > > > > > > for the success and failure cases, respectively. > > > > > > > > > > Hrm, I think adding this kind of flexibility might make the API too > > > > > clobbered by details that "usual cases" don't care about. > > > > > > > > ;-) > > > > > > > > > > Unless you expect use cases with lots of failing cds_lfht_del() and > > > > > > add_unique() calls, the performance difference should not be significant. > > > > > > > > > > The problem is that I expect very, very frequent failing add_unique > > > > > calls for use-cases like Binary Decision Diagrams (BDD) creation. This > > > > > is why I don't think it is appropriate to put memory barriers on the > > > > > failure cases, as these should have no more overhead than a simple > > > > > lookup. > > > > > > > > > > And if we choose not to provide memory barriers for add_unique failure, > > > > > we should probably do the same for "del" to keep a consistent behavior > > > > > over the API. > > > > > > > > > > Thoughts ? > > > > > > > > Given your BDD example, letting the failure cases avoid memory barriers > > > > seems reasonable. If problems arise, the default interfaces can be > > > > fully ordered with faster versions where the failure cases avoid memory > > > > barriers. > > > > > > I think we agree on the failure cases of del and add_unique, which is > > > good. > > > > > > Now, I'm thinking slightly further about the success cases of add, > > > add_unique and del. > > > > > > Typically, when giving a node to add or add_unique for population into > > > the hash table, we have to order the writes that initialize the node > > > before its insertion into the hash table. So I think it would make sense > > > to guarantee that we provide a memory barrier prior to add and > > > add_unique (success) operations. > > > > > > For the "del" case, it's the other way around: if a deletion succeeds, > > > we want to have a memory barrier between the removal flag write and the > > > following "free()" of the element. So we need to ensure that there is a > > > memory barrier after a successful deletion. > > > > > > If we think about it, the "add_replace" acts both as an "add" and "del": > > > in all cases, we need to have a memory barrier before the add_replace, > > > because we need to order the node initialization before the atomic > > > insertion into the hash table, and we also need a memory barrier after, > > > but only really in the case where add_replace replaced an old node, thus > > > acting as a delete of that old node. > > > > > > Considering all this, the barrier semantic I'm proposing is: > > > > > > add: > > > - full memory barrier before the insertion. > > > > > > add_unique: > > > - success: full memory barrier before the insertion. > > > - failure: no memory barrier. > > > > > > replace: > > > - success: full memory barrier before the insertion, and after the > > > removal of the old node. > > > - failure: no memory barrier. > > > > > > add_replace: > > > - returns an old node (replace): full memory barrier before the > > > insertion, and after the removal of the old node. > > > - returns NULL (add): full memory barrier before the insertion. > > > > > > del: > > > - success: full memory barrier after the removal. > > > - failure: no memory barrier. > > > > > > I think those are the minimal barriers we need to provide to ensure that > > > users will not have to add barriers of their own to use the API. > > > > > > Thoughts ? > > > > This means that some other CPU might see an add followed by a del as > > happening in the opposite order. Is that really OK? > > Here I suppose you are talking about add and del that touch different > nodes, since add/del touching the same node would modify the same memory > location, so both operations would be seen in the right order by the > other processors. > > I guess the question here is: how does the remote CPU observe this ? > Is it from a read-side traversal, or from update operations performed on > the remote CPU ? Or from lookups of arbitrary key values ? Or from other > update operations ? > > For read-side traversal, given the traversal within a single hash chain > goes from newer nodes to older nodes, the sequence "add" then "del", > adding a new node, then deleting an old one (e.g. from the same hash > chain) first adds the new node to the beginning of the hash chain, and > then removes the old node that is later in the chain (in traversal > order). In this case, if the "del" is published before the "add", this > is entirely equivalent to have a read-side traversal that misses the > added node, but sees the effect of the "del". > > In terms of read-side traversal, what we seem to care about is more the > "del" then "add" performed on different nodes (e.g. of the same hash > chain): given that the "add" is at the beginning of the chain, and "del" > is somewhere within the chain, a read-side traversal that observes the > "add" would _always_ observe the effect of a prior "del". Thankfully, > "del" then "add" is ordered in the scheme I propose, thanks to the > memory barrier after "del" and also the one before "add". > > For traversal of the entire table (not just same hash chain), the > traversal vs key order is random, so we cannot assume anything about the > observation order of add/del of different keys. Indeed, I was thinking in terms of a pair of lookups separated by smp_mb(). > If we perform two lookups of different keys, without explicit memory > barriers between the lookups, we already have no guarantee whatsoever > that the published information will be brought into the observer CPU in > the right order: IOW, the lookups of different keys can be reordered. So > I guess we don't care about add vs del ordering on the publish side for > that one. > > The other scenarios I see are related to update operations (add, > add_unique, add_replace, replace, del). If a sequence of these > operations is executed on the "observer" CPU, and expects to see the > effect of the sequence of "add" then "del" performed on the "publisher" > CPU in order, then, yes, an additional memory barrier would be required > to order add before del. > > The question here is: do we care about providing order of add before del > only for the sake of the other update operations running on another CPU > that would expect to see their effect in order ? I don't know, maybe. > > I guess the safest route would be to provide the ordering guarantee, > given that there exists a way to observe this and possibly care about > it. I wonder if it would be better to put the barrier after the > add/add_unique (success), or before the "del". > > Also, do you think a write barrier would be sufficient, or we should > keep full barriers ? A write barrier would be sufficient in the case where there were only two threads observing each other. A full memory barrier would be needed to prevent the assertion from firing in this sort of case (not sure that this is exactly right, but something like this): Initial contents: B, C T0: add A; del B T1: if (!lookup B) { add B; del C } T2: r1 = lookup C; smp_mb(); r2 = lookup A assert(lookup C || lookup A); Thanx, Paul > Thanks, > > Mathieu > > > > > Thanx, Paul > > > > > Thanks, > > > > > > Mathieu > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > Thanks, > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > > > > > Thoughts ? > > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > > > > > > Yep, makes sense. > > > > > > > > > > > > > > > > I'll add this documentation in the API. > > > > > > > > > > > > > > > > Thanks! > > > > > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > > > > > > > > > cds_lfht_is_node_deleted(): Not an update (let alone an atomic update), > > > > > > > > > no barriers. > > > > > > > > > > > > > > > > > > cds_lfht_resize(): Atomic update, but no return value, so no barrier > > > > > > > > > implied. > > > > > > > > > > > > > > > > > > cds_lfht_for_each(): Not an update (let alone an atomic update), > > > > > > > > > no barriers. > > > > > > > > > > > > > > > > > > cds_lfht_for_each_duplicate(): Ditto. > > > > > > > > > > > > > > > > > > cds_lfht_for_each_entry(): Ditto. > > > > > > > > > > > > > > > > > > cds_lfht_for_each_entry_duplicate(): Ditto. > > > > > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > > > > > > > > > > > I'm personally getting confident that the hash table API is clean > > > > > > > > > > enough, and the implementation well tested, but I'd like to have your > > > > > > > > > > thoughts on the readiness of the hash table for production use. > > > > > > > > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > > > -- > > > > > > > > > > Mathieu Desnoyers > > > > > > > > > > Operating System Efficiency R&D Consultant > > > > > > > > > > EfficiOS Inc. > > > > > > > > > > http://www.efficios.com > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > > > > rp mailing list > > > > > > > > > > rp at svcs.cs.pdx.edu > > > > > > > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > > > lttng-dev mailing list > > > > > > > > > lttng-dev at lists.lttng.org > > > > > > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > > > > > > > > > -- > > > > > > > > Mathieu Desnoyers > > > > > > > > Operating System Efficiency R&D Consultant > > > > > > > > EfficiOS Inc. > > > > > > > > http://www.efficios.com > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > > lttng-dev mailing list > > > > > > > > lttng-dev at lists.lttng.org > > > > > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > > > > > > > -- > > > > > > > Mathieu Desnoyers > > > > > > > Operating System Efficiency R&D Consultant > > > > > > > EfficiOS Inc. > > > > > > > http://www.efficios.com > > > > > > > > > > > > > > _______________________________________________ > > > > > > > rp mailing list > > > > > > > rp at svcs.cs.pdx.edu > > > > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > > > > > > > > > > > -- > > > > > Mathieu Desnoyers > > > > > Operating System Efficiency R&D Consultant > > > > > EfficiOS Inc. > > > > > http://www.efficios.com > > > > > > > > > > _______________________________________________ > > > > > rp mailing list > > > > > rp at svcs.cs.pdx.edu > > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > > > > > _______________________________________________ > > > > lttng-dev mailing list > > > > lttng-dev at lists.lttng.org > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > -- > > > Mathieu Desnoyers > > > Operating System Efficiency R&D Consultant > > > EfficiOS Inc. > > > http://www.efficios.com > > > > > > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > From mathieu.desnoyers at efficios.com Thu May 3 13:13:30 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 3 May 2012 13:13:30 -0400 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120502155430.GF2450@linux.vnet.ibm.com> References: <20120501144924.GB2441@linux.vnet.ibm.com> <20120501151215.GB24840@Krystal> <20120501152144.GA25061@Krystal> <20120501161337.GF2441@linux.vnet.ibm.com> <20120501174136.GA26609@Krystal> <20120501194713.GL2441@linux.vnet.ibm.com> <20120501210206.GA31952@Krystal> <20120501235007.GS2441@linux.vnet.ibm.com> <20120502041639.GA7857@Krystal> <20120502155430.GF2450@linux.vnet.ibm.com> Message-ID: <20120503171330.GA12234@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > On Wed, May 02, 2012 at 12:16:39AM -0400, Mathieu Desnoyers wrote: > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > On Tue, May 01, 2012 at 05:02:06PM -0400, Mathieu Desnoyers wrote: > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > On Tue, May 01, 2012 at 01:41:36PM -0400, Mathieu Desnoyers wrote: > > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > > > On Tue, May 01, 2012 at 11:21:44AM -0400, Mathieu Desnoyers wrote: > > > > > > > > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > > > > > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > > > > > > On Tue, May 01, 2012 at 10:16:09AM -0400, Mathieu Desnoyers wrote: > > > > > > > > > > > Hi! > > > > > > > > > > > > > > > > > > > > > > After 1 year of development, with the last 6-7 months spent polishing > > > > > > > > > > > the API and testing the implementation, I think it is getting about time > > > > > > > > > > > to release the RCU lock-free hash table in a new Userspace RCU version > > > > > > > > > > > (0.7). > > > > > > > > > > > > > > > > > > > > > > I recently described the guarantees provided by the hash table in more > > > > > > > > > > > detail, and created tests for the uniqueness guarantee for traversals > > > > > > > > > > > performed concurrently with add_unique and add_replace operations. I > > > > > > > > > > > also added test modes that create long hash chains, to test corner-cases > > > > > > > > > > > of the hash table. > > > > > > > > > > > > > > > > > > > > > > One small thing I wonder is whether we should document that the hash > > > > > > > > > > > table update operations imply full memory barriers ? > > > > > > > > > > > > > > > > > > > > The Linux kernel's rule seems good here -- if a hash-table operation is > > > > > > > > > > atomic and returns a value, it should imply a full barrier. So: > > > > > > > > > > > > > > > > > > > > cds_lfht_new(): No point in claiming barriers -- publishing the > > > > > > > > > > pointer to the hash table is where the barriers are important. > > > > > > > > > > > > > > > > > > > > cds_lfht_destroy(): Ditto. > > > > > > > > > > > > > > > > > > > > cds_lfht_lookup(): Not an update (let alone an atomic update), no barriers. > > > > > > > > > > > > > > > > > > > > cds_lfht_next_duplicate(): Ditto. > > > > > > > > > > > > > > > > > > > > cds_lfht_first(): Ditto. > > > > > > > > > > > > > > > > > > > > cds_lfht_next(): Ditto. > > > > > > > > > > > > > > > > > > > > cds_lfht_add(): Atomic update, but no return value, so no barrier > > > > > > > > > > implied. > > > > > > > > > > > > > > > > > > Yep, makes sense. We use cmpxchg internally to perform the update, but > > > > > > > > > it could make sense to eventually use a cmpxchg that has no memory > > > > > > > > > barriers to perform this update. So I agree on not providing a memory > > > > > > > > > barrier guarantee on the "add" operation, since it does not return any > > > > > > > > > value. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > cds_lfht_add_unique(): Atomic update that returns a value, so should > > > > > > > > > > imply a full memory barrier. > > > > > > > > > > > > > > > > > > add_unique is a bit special: > > > > > > > > > > > > > > > > > > - if it returns the node received as parameter, it means the add > > > > > > > > > succeeded, which imply an update, and thus a memory barrier. > > > > > > > > > > > > > > > > Hrm, thinking further: if we make the "add" operation not act as a > > > > > > > > full memory barrier, then the add_unique success should not act as a > > > > > > > > full mb neither. > > > > > > > > > > > > > > Think of it as being similar to the Linux kernel's atomic_inc() and > > > > > > > atomic_add_return() primitives. The latter guarantees memory barriers > > > > > > > and the former does not. > > > > > > > > > > > > I think add/add_unique vs atomic_inc/atomic_add_return are fundamentally > > > > > > different. > > > > > > > > > > > > atomic_inc: > > > > > > - input: increment > > > > > > - output: none > > > > > > - effect: increment target address value > > > > > > > > > > > > atomic_add_return: > > > > > > - input: increment > > > > > > - output: incremented value > > > > > > - effect: increment target address value, atomically reading the > > > > > > resulting value. > > > > > > > > > > > > hash table add: > > > > > > - input: new node to add > > > > > > - output: none > > > > > > - effect: atomically add the new node into the table > > > > > > > > > > > > hash table add_unique (success): > > > > > > - input: new node to add > > > > > > - output: (we just return whether the operation has succeeded) > > > > > > - effect: atomically add the new node into the table > > > > > > > > > > > > hash table add_unique (failure): > > > > > > - input: new node to try adding > > > > > > - output: (we just return whether the operation has succeeded) > > > > > > - effect: simple lookup (read) > > > > > > > > > > > > So as we see, the add_unique failure only performs a read. Adding a > > > > > > memory barrier before this read would require us to add a memory barrier > > > > > > also on the success path, which would degrade performance. The success > > > > > > path does: lookup failure, cmpxchg to add the node, retry if changed. > > > > > > Adding a memory barrier before the lookup would add an extra memory > > > > > > barrier in addition to the one located in the cmpxchg, and I don't think > > > > > > we want that overhead. > > > > > > > > > > Perhaps a better analogy is cmpxchg() in the Linux kernel. Some > > > > > architectures place the memory barrier before unconditionally, but place > > > > > a memory barrier after only if the cmpxchg() succeeds. Of course, > > > > > architectures for which the cmpxchg instruction implies a barrier > > > > > don't need any explicit memory-barrier instructions. > > > > > > > > > > I do see your point about the memory barrier in the failure case requiring > > > > > an additional memory barrier in the success case, however. > > > > > > > > > > > > > > - if it returns a different node than the one received as parameter, it > > > > > > > > > failed, and thus means that it only performed a lookup, so there is no > > > > > > > > > guarantee that a memory barrier has been executed. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > cds_lfht_add_replace(): Ditto. > > > > > > > > > > > > > > > > > > > > cds_lfht_replace(): Ditto. > > > > > > > > > > > > > > > > > > > > cds_lfht_del(): Ditto. > > > > > > > > > > > > > > > > One more point: "del" is similar to add_unique: if it succeeds, we > > > > > > > > execute a full memory barrier. If it fails, no memory barrier is > > > > > > > > guaranteed. But if we want to make the guarantees relax, we might not > > > > > > > > want to guarantee that a memory barrier is present in any of the "del" > > > > > > > > cases. > > > > > > > > > > > > > > > > In the end, the only primitives for which I think it really makes sense > > > > > > > > to provide memory barrier semantic is the add_replace and replace : they > > > > > > > > actually act as an higher-level "cmpxchg" over the hash table nodes. > > > > > > > > > > > > > > I believe that this should do the same -- memory barrier before, but no > > > > > > > memory barrier after on failure. > > > > > > > > > > > > > > Another approach is C++11, in which there are a couple of arguments to > > > > > > > the compare-and-swap primitive specifying the memory ordering constraints > > > > > > > for the success and failure cases, respectively. > > > > > > > > > > > > Hrm, I think adding this kind of flexibility might make the API too > > > > > > clobbered by details that "usual cases" don't care about. > > > > > > > > > > ;-) > > > > > > > > > > > > Unless you expect use cases with lots of failing cds_lfht_del() and > > > > > > > add_unique() calls, the performance difference should not be significant. > > > > > > > > > > > > The problem is that I expect very, very frequent failing add_unique > > > > > > calls for use-cases like Binary Decision Diagrams (BDD) creation. This > > > > > > is why I don't think it is appropriate to put memory barriers on the > > > > > > failure cases, as these should have no more overhead than a simple > > > > > > lookup. > > > > > > > > > > > > And if we choose not to provide memory barriers for add_unique failure, > > > > > > we should probably do the same for "del" to keep a consistent behavior > > > > > > over the API. > > > > > > > > > > > > Thoughts ? > > > > > > > > > > Given your BDD example, letting the failure cases avoid memory barriers > > > > > seems reasonable. If problems arise, the default interfaces can be > > > > > fully ordered with faster versions where the failure cases avoid memory > > > > > barriers. > > > > > > > > I think we agree on the failure cases of del and add_unique, which is > > > > good. > > > > > > > > Now, I'm thinking slightly further about the success cases of add, > > > > add_unique and del. > > > > > > > > Typically, when giving a node to add or add_unique for population into > > > > the hash table, we have to order the writes that initialize the node > > > > before its insertion into the hash table. So I think it would make sense > > > > to guarantee that we provide a memory barrier prior to add and > > > > add_unique (success) operations. > > > > > > > > For the "del" case, it's the other way around: if a deletion succeeds, > > > > we want to have a memory barrier between the removal flag write and the > > > > following "free()" of the element. So we need to ensure that there is a > > > > memory barrier after a successful deletion. > > > > > > > > If we think about it, the "add_replace" acts both as an "add" and "del": > > > > in all cases, we need to have a memory barrier before the add_replace, > > > > because we need to order the node initialization before the atomic > > > > insertion into the hash table, and we also need a memory barrier after, > > > > but only really in the case where add_replace replaced an old node, thus > > > > acting as a delete of that old node. > > > > > > > > Considering all this, the barrier semantic I'm proposing is: > > > > > > > > add: > > > > - full memory barrier before the insertion. > > > > > > > > add_unique: > > > > - success: full memory barrier before the insertion. > > > > - failure: no memory barrier. > > > > > > > > replace: > > > > - success: full memory barrier before the insertion, and after the > > > > removal of the old node. > > > > - failure: no memory barrier. > > > > > > > > add_replace: > > > > - returns an old node (replace): full memory barrier before the > > > > insertion, and after the removal of the old node. > > > > - returns NULL (add): full memory barrier before the insertion. > > > > > > > > del: > > > > - success: full memory barrier after the removal. > > > > - failure: no memory barrier. > > > > > > > > I think those are the minimal barriers we need to provide to ensure that > > > > users will not have to add barriers of their own to use the API. > > > > > > > > Thoughts ? > > > > > > This means that some other CPU might see an add followed by a del as > > > happening in the opposite order. Is that really OK? > > > > Here I suppose you are talking about add and del that touch different > > nodes, since add/del touching the same node would modify the same memory > > location, so both operations would be seen in the right order by the > > other processors. > > > > I guess the question here is: how does the remote CPU observe this ? > > Is it from a read-side traversal, or from update operations performed on > > the remote CPU ? Or from lookups of arbitrary key values ? Or from other > > update operations ? > > > > For read-side traversal, given the traversal within a single hash chain > > goes from newer nodes to older nodes, the sequence "add" then "del", > > adding a new node, then deleting an old one (e.g. from the same hash > > chain) first adds the new node to the beginning of the hash chain, and > > then removes the old node that is later in the chain (in traversal > > order). In this case, if the "del" is published before the "add", this > > is entirely equivalent to have a read-side traversal that misses the > > added node, but sees the effect of the "del". > > > > In terms of read-side traversal, what we seem to care about is more the > > "del" then "add" performed on different nodes (e.g. of the same hash > > chain): given that the "add" is at the beginning of the chain, and "del" > > is somewhere within the chain, a read-side traversal that observes the > > "add" would _always_ observe the effect of a prior "del". Thankfully, > > "del" then "add" is ordered in the scheme I propose, thanks to the > > memory barrier after "del" and also the one before "add". > > > > For traversal of the entire table (not just same hash chain), the > > traversal vs key order is random, so we cannot assume anything about the > > observation order of add/del of different keys. > > Indeed, I was thinking in terms of a pair of lookups separated by > smp_mb(). > > > If we perform two lookups of different keys, without explicit memory > > barriers between the lookups, we already have no guarantee whatsoever > > that the published information will be brought into the observer CPU in > > the right order: IOW, the lookups of different keys can be reordered. So > > I guess we don't care about add vs del ordering on the publish side for > > that one. > > > > The other scenarios I see are related to update operations (add, > > add_unique, add_replace, replace, del). If a sequence of these > > operations is executed on the "observer" CPU, and expects to see the > > effect of the sequence of "add" then "del" performed on the "publisher" > > CPU in order, then, yes, an additional memory barrier would be required > > to order add before del. > > > > The question here is: do we care about providing order of add before del > > only for the sake of the other update operations running on another CPU > > that would expect to see their effect in order ? I don't know, maybe. > > > > I guess the safest route would be to provide the ordering guarantee, > > given that there exists a way to observe this and possibly care about > > it. I wonder if it would be better to put the barrier after the > > add/add_unique (success), or before the "del". > > > > Also, do you think a write barrier would be sufficient, or we should > > keep full barriers ? > > A write barrier would be sufficient in the case where there were only > two threads observing each other. A full memory barrier would be needed > to prevent the assertion from firing in this sort of case (not sure that > this is exactly right, but something like this): > > Initial contents: B, C > > T0: add A; del B > T1: if (!lookup B) { add B; del C } > T2: r1 = lookup C; smp_mb(); r2 = lookup A > > assert(lookup C || lookup A); What you are bringing here as counter-example is, I think, transitivity. I'm trying to figure out how your example could fail, and I cannot see how. Follows a detail of the closest scenario I get to failing is the following, but it does not fail. After that, I'm proposing a different scenario, which I think will be more appropriate for the current topic. Attempted detail of your scenario: T0 T1 T2 add A wmb (add A globally observable) del B (del B globally observable) (add A NOT brought into cache) (del B brought into cache) read B (test false) add B wmb (add B globally observable) del C (del C globally observable) (add A NOT brought into cache) (del C brought into cache) read C -> not there. mb (add A brought into cache) read A -> there -> success. If I look at the "transitivity" section in Linux memory-barriers.txt, I notice that the example is mainly around using read barrier around loads rather than general barrier. Let's see if I can modify that example to come up with an example error case: Initial content: empty T0: add X T1: r1 = lookup X; smp_mb; r2 = lookup Y T2: add Y; r3 = lookup X assert( !(r1 && !r2 && !r3) ) The key thing here is that if the barrier in T2 after "add Y" is a smp_wmb rather than a smp_mb, this could allow the "r3 = lookup X" to be reordered before add Y, thus allowing the assertion to fail. I think it would be more intuitive for users if lookups vs updates performed on the same thread are ordered with full memory barriers. Given that we don't want to add extra barriers in read operations, it would make sense to guarantee full memory barriers before and after updates. So how about we use full memory barriers before and after each of: add, del (success), add_unique (success), replace, and add_replace ? If we ever want to relax those ordering guarantees, then we can always add new update APIs with a "weaker" ordering. Thoughts ? Thanks, Mathieu > > Thanx, Paul > > > Thanks, > > > > Mathieu > > > > > > > > Thanx, Paul > > > > > > > Thanks, > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > > > Thanks, > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > > > > > > > Thoughts ? > > > > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > > > > > > > > > Yep, makes sense. > > > > > > > > > > > > > > > > > > I'll add this documentation in the API. > > > > > > > > > > > > > > > > > > Thanks! > > > > > > > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > > > > > > > > > > > > cds_lfht_is_node_deleted(): Not an update (let alone an atomic update), > > > > > > > > > > no barriers. > > > > > > > > > > > > > > > > > > > > cds_lfht_resize(): Atomic update, but no return value, so no barrier > > > > > > > > > > implied. > > > > > > > > > > > > > > > > > > > > cds_lfht_for_each(): Not an update (let alone an atomic update), > > > > > > > > > > no barriers. > > > > > > > > > > > > > > > > > > > > cds_lfht_for_each_duplicate(): Ditto. > > > > > > > > > > > > > > > > > > > > cds_lfht_for_each_entry(): Ditto. > > > > > > > > > > > > > > > > > > > > cds_lfht_for_each_entry_duplicate(): Ditto. > > > > > > > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > > > > > > > > > > > > > I'm personally getting confident that the hash table API is clean > > > > > > > > > > > enough, and the implementation well tested, but I'd like to have your > > > > > > > > > > > thoughts on the readiness of the hash table for production use. > > > > > > > > > > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > > > > > -- > > > > > > > > > > > Mathieu Desnoyers > > > > > > > > > > > Operating System Efficiency R&D Consultant > > > > > > > > > > > EfficiOS Inc. > > > > > > > > > > > http://www.efficios.com > > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > > > > > rp mailing list > > > > > > > > > > > rp at svcs.cs.pdx.edu > > > > > > > > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > > > > lttng-dev mailing list > > > > > > > > > > lttng-dev at lists.lttng.org > > > > > > > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > > > > > > > > > > > -- > > > > > > > > > Mathieu Desnoyers > > > > > > > > > Operating System Efficiency R&D Consultant > > > > > > > > > EfficiOS Inc. > > > > > > > > > http://www.efficios.com > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > > > lttng-dev mailing list > > > > > > > > > lttng-dev at lists.lttng.org > > > > > > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > > > > > > > > > -- > > > > > > > > Mathieu Desnoyers > > > > > > > > Operating System Efficiency R&D Consultant > > > > > > > > EfficiOS Inc. > > > > > > > > http://www.efficios.com > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > > rp mailing list > > > > > > > > rp at svcs.cs.pdx.edu > > > > > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > > > > > > > > > > > > > > > -- > > > > > > Mathieu Desnoyers > > > > > > Operating System Efficiency R&D Consultant > > > > > > EfficiOS Inc. > > > > > > http://www.efficios.com > > > > > > > > > > > > _______________________________________________ > > > > > > rp mailing list > > > > > > rp at svcs.cs.pdx.edu > > > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > lttng-dev mailing list > > > > > lttng-dev at lists.lttng.org > > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > -- > > > > Mathieu Desnoyers > > > > Operating System Efficiency R&D Consultant > > > > EfficiOS Inc. > > > > http://www.efficios.com > > > > > > > > > > > > > _______________________________________________ > > > lttng-dev mailing list > > > lttng-dev at lists.lttng.org > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From paulmck at linux.vnet.ibm.com Thu May 3 13:47:06 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Thu, 3 May 2012 10:47:06 -0700 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120503171330.GA12234@Krystal> References: <20120501151215.GB24840@Krystal> <20120501152144.GA25061@Krystal> <20120501161337.GF2441@linux.vnet.ibm.com> <20120501174136.GA26609@Krystal> <20120501194713.GL2441@linux.vnet.ibm.com> <20120501210206.GA31952@Krystal> <20120501235007.GS2441@linux.vnet.ibm.com> <20120502041639.GA7857@Krystal> <20120502155430.GF2450@linux.vnet.ibm.com> <20120503171330.GA12234@Krystal> Message-ID: <20120503174706.GI2592@linux.vnet.ibm.com> On Thu, May 03, 2012 at 01:13:30PM -0400, Mathieu Desnoyers wrote: > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > On Wed, May 02, 2012 at 12:16:39AM -0400, Mathieu Desnoyers wrote: > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > On Tue, May 01, 2012 at 05:02:06PM -0400, Mathieu Desnoyers wrote: > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > > On Tue, May 01, 2012 at 01:41:36PM -0400, Mathieu Desnoyers wrote: > > > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > > > > On Tue, May 01, 2012 at 11:21:44AM -0400, Mathieu Desnoyers wrote: > > > > > > > > > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > > > > > > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > > > > > > > On Tue, May 01, 2012 at 10:16:09AM -0400, Mathieu Desnoyers wrote: > > > > > > > > > > > > Hi! > > > > > > > > > > > > > > > > > > > > > > > > After 1 year of development, with the last 6-7 months spent polishing > > > > > > > > > > > > the API and testing the implementation, I think it is getting about time > > > > > > > > > > > > to release the RCU lock-free hash table in a new Userspace RCU version > > > > > > > > > > > > (0.7). > > > > > > > > > > > > > > > > > > > > > > > > I recently described the guarantees provided by the hash table in more > > > > > > > > > > > > detail, and created tests for the uniqueness guarantee for traversals > > > > > > > > > > > > performed concurrently with add_unique and add_replace operations. I > > > > > > > > > > > > also added test modes that create long hash chains, to test corner-cases > > > > > > > > > > > > of the hash table. > > > > > > > > > > > > > > > > > > > > > > > > One small thing I wonder is whether we should document that the hash > > > > > > > > > > > > table update operations imply full memory barriers ? > > > > > > > > > > > > > > > > > > > > > > The Linux kernel's rule seems good here -- if a hash-table operation is > > > > > > > > > > > atomic and returns a value, it should imply a full barrier. So: > > > > > > > > > > > > > > > > > > > > > > cds_lfht_new(): No point in claiming barriers -- publishing the > > > > > > > > > > > pointer to the hash table is where the barriers are important. > > > > > > > > > > > > > > > > > > > > > > cds_lfht_destroy(): Ditto. > > > > > > > > > > > > > > > > > > > > > > cds_lfht_lookup(): Not an update (let alone an atomic update), no barriers. > > > > > > > > > > > > > > > > > > > > > > cds_lfht_next_duplicate(): Ditto. > > > > > > > > > > > > > > > > > > > > > > cds_lfht_first(): Ditto. > > > > > > > > > > > > > > > > > > > > > > cds_lfht_next(): Ditto. > > > > > > > > > > > > > > > > > > > > > > cds_lfht_add(): Atomic update, but no return value, so no barrier > > > > > > > > > > > implied. > > > > > > > > > > > > > > > > > > > > Yep, makes sense. We use cmpxchg internally to perform the update, but > > > > > > > > > > it could make sense to eventually use a cmpxchg that has no memory > > > > > > > > > > barriers to perform this update. So I agree on not providing a memory > > > > > > > > > > barrier guarantee on the "add" operation, since it does not return any > > > > > > > > > > value. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > cds_lfht_add_unique(): Atomic update that returns a value, so should > > > > > > > > > > > imply a full memory barrier. > > > > > > > > > > > > > > > > > > > > add_unique is a bit special: > > > > > > > > > > > > > > > > > > > > - if it returns the node received as parameter, it means the add > > > > > > > > > > succeeded, which imply an update, and thus a memory barrier. > > > > > > > > > > > > > > > > > > Hrm, thinking further: if we make the "add" operation not act as a > > > > > > > > > full memory barrier, then the add_unique success should not act as a > > > > > > > > > full mb neither. > > > > > > > > > > > > > > > > Think of it as being similar to the Linux kernel's atomic_inc() and > > > > > > > > atomic_add_return() primitives. The latter guarantees memory barriers > > > > > > > > and the former does not. > > > > > > > > > > > > > > I think add/add_unique vs atomic_inc/atomic_add_return are fundamentally > > > > > > > different. > > > > > > > > > > > > > > atomic_inc: > > > > > > > - input: increment > > > > > > > - output: none > > > > > > > - effect: increment target address value > > > > > > > > > > > > > > atomic_add_return: > > > > > > > - input: increment > > > > > > > - output: incremented value > > > > > > > - effect: increment target address value, atomically reading the > > > > > > > resulting value. > > > > > > > > > > > > > > hash table add: > > > > > > > - input: new node to add > > > > > > > - output: none > > > > > > > - effect: atomically add the new node into the table > > > > > > > > > > > > > > hash table add_unique (success): > > > > > > > - input: new node to add > > > > > > > - output: (we just return whether the operation has succeeded) > > > > > > > - effect: atomically add the new node into the table > > > > > > > > > > > > > > hash table add_unique (failure): > > > > > > > - input: new node to try adding > > > > > > > - output: (we just return whether the operation has succeeded) > > > > > > > - effect: simple lookup (read) > > > > > > > > > > > > > > So as we see, the add_unique failure only performs a read. Adding a > > > > > > > memory barrier before this read would require us to add a memory barrier > > > > > > > also on the success path, which would degrade performance. The success > > > > > > > path does: lookup failure, cmpxchg to add the node, retry if changed. > > > > > > > Adding a memory barrier before the lookup would add an extra memory > > > > > > > barrier in addition to the one located in the cmpxchg, and I don't think > > > > > > > we want that overhead. > > > > > > > > > > > > Perhaps a better analogy is cmpxchg() in the Linux kernel. Some > > > > > > architectures place the memory barrier before unconditionally, but place > > > > > > a memory barrier after only if the cmpxchg() succeeds. Of course, > > > > > > architectures for which the cmpxchg instruction implies a barrier > > > > > > don't need any explicit memory-barrier instructions. > > > > > > > > > > > > I do see your point about the memory barrier in the failure case requiring > > > > > > an additional memory barrier in the success case, however. > > > > > > > > > > > > > > > > - if it returns a different node than the one received as parameter, it > > > > > > > > > > failed, and thus means that it only performed a lookup, so there is no > > > > > > > > > > guarantee that a memory barrier has been executed. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > cds_lfht_add_replace(): Ditto. > > > > > > > > > > > > > > > > > > > > > > cds_lfht_replace(): Ditto. > > > > > > > > > > > > > > > > > > > > > > cds_lfht_del(): Ditto. > > > > > > > > > > > > > > > > > > One more point: "del" is similar to add_unique: if it succeeds, we > > > > > > > > > execute a full memory barrier. If it fails, no memory barrier is > > > > > > > > > guaranteed. But if we want to make the guarantees relax, we might not > > > > > > > > > want to guarantee that a memory barrier is present in any of the "del" > > > > > > > > > cases. > > > > > > > > > > > > > > > > > > In the end, the only primitives for which I think it really makes sense > > > > > > > > > to provide memory barrier semantic is the add_replace and replace : they > > > > > > > > > actually act as an higher-level "cmpxchg" over the hash table nodes. > > > > > > > > > > > > > > > > I believe that this should do the same -- memory barrier before, but no > > > > > > > > memory barrier after on failure. > > > > > > > > > > > > > > > > Another approach is C++11, in which there are a couple of arguments to > > > > > > > > the compare-and-swap primitive specifying the memory ordering constraints > > > > > > > > for the success and failure cases, respectively. > > > > > > > > > > > > > > Hrm, I think adding this kind of flexibility might make the API too > > > > > > > clobbered by details that "usual cases" don't care about. > > > > > > > > > > > > ;-) > > > > > > > > > > > > > > Unless you expect use cases with lots of failing cds_lfht_del() and > > > > > > > > add_unique() calls, the performance difference should not be significant. > > > > > > > > > > > > > > The problem is that I expect very, very frequent failing add_unique > > > > > > > calls for use-cases like Binary Decision Diagrams (BDD) creation. This > > > > > > > is why I don't think it is appropriate to put memory barriers on the > > > > > > > failure cases, as these should have no more overhead than a simple > > > > > > > lookup. > > > > > > > > > > > > > > And if we choose not to provide memory barriers for add_unique failure, > > > > > > > we should probably do the same for "del" to keep a consistent behavior > > > > > > > over the API. > > > > > > > > > > > > > > Thoughts ? > > > > > > > > > > > > Given your BDD example, letting the failure cases avoid memory barriers > > > > > > seems reasonable. If problems arise, the default interfaces can be > > > > > > fully ordered with faster versions where the failure cases avoid memory > > > > > > barriers. > > > > > > > > > > I think we agree on the failure cases of del and add_unique, which is > > > > > good. > > > > > > > > > > Now, I'm thinking slightly further about the success cases of add, > > > > > add_unique and del. > > > > > > > > > > Typically, when giving a node to add or add_unique for population into > > > > > the hash table, we have to order the writes that initialize the node > > > > > before its insertion into the hash table. So I think it would make sense > > > > > to guarantee that we provide a memory barrier prior to add and > > > > > add_unique (success) operations. > > > > > > > > > > For the "del" case, it's the other way around: if a deletion succeeds, > > > > > we want to have a memory barrier between the removal flag write and the > > > > > following "free()" of the element. So we need to ensure that there is a > > > > > memory barrier after a successful deletion. > > > > > > > > > > If we think about it, the "add_replace" acts both as an "add" and "del": > > > > > in all cases, we need to have a memory barrier before the add_replace, > > > > > because we need to order the node initialization before the atomic > > > > > insertion into the hash table, and we also need a memory barrier after, > > > > > but only really in the case where add_replace replaced an old node, thus > > > > > acting as a delete of that old node. > > > > > > > > > > Considering all this, the barrier semantic I'm proposing is: > > > > > > > > > > add: > > > > > - full memory barrier before the insertion. > > > > > > > > > > add_unique: > > > > > - success: full memory barrier before the insertion. > > > > > - failure: no memory barrier. > > > > > > > > > > replace: > > > > > - success: full memory barrier before the insertion, and after the > > > > > removal of the old node. > > > > > - failure: no memory barrier. > > > > > > > > > > add_replace: > > > > > - returns an old node (replace): full memory barrier before the > > > > > insertion, and after the removal of the old node. > > > > > - returns NULL (add): full memory barrier before the insertion. > > > > > > > > > > del: > > > > > - success: full memory barrier after the removal. > > > > > - failure: no memory barrier. > > > > > > > > > > I think those are the minimal barriers we need to provide to ensure that > > > > > users will not have to add barriers of their own to use the API. > > > > > > > > > > Thoughts ? > > > > > > > > This means that some other CPU might see an add followed by a del as > > > > happening in the opposite order. Is that really OK? > > > > > > Here I suppose you are talking about add and del that touch different > > > nodes, since add/del touching the same node would modify the same memory > > > location, so both operations would be seen in the right order by the > > > other processors. > > > > > > I guess the question here is: how does the remote CPU observe this ? > > > Is it from a read-side traversal, or from update operations performed on > > > the remote CPU ? Or from lookups of arbitrary key values ? Or from other > > > update operations ? > > > > > > For read-side traversal, given the traversal within a single hash chain > > > goes from newer nodes to older nodes, the sequence "add" then "del", > > > adding a new node, then deleting an old one (e.g. from the same hash > > > chain) first adds the new node to the beginning of the hash chain, and > > > then removes the old node that is later in the chain (in traversal > > > order). In this case, if the "del" is published before the "add", this > > > is entirely equivalent to have a read-side traversal that misses the > > > added node, but sees the effect of the "del". > > > > > > In terms of read-side traversal, what we seem to care about is more the > > > "del" then "add" performed on different nodes (e.g. of the same hash > > > chain): given that the "add" is at the beginning of the chain, and "del" > > > is somewhere within the chain, a read-side traversal that observes the > > > "add" would _always_ observe the effect of a prior "del". Thankfully, > > > "del" then "add" is ordered in the scheme I propose, thanks to the > > > memory barrier after "del" and also the one before "add". > > > > > > For traversal of the entire table (not just same hash chain), the > > > traversal vs key order is random, so we cannot assume anything about the > > > observation order of add/del of different keys. > > > > Indeed, I was thinking in terms of a pair of lookups separated by > > smp_mb(). > > > > > If we perform two lookups of different keys, without explicit memory > > > barriers between the lookups, we already have no guarantee whatsoever > > > that the published information will be brought into the observer CPU in > > > the right order: IOW, the lookups of different keys can be reordered. So > > > I guess we don't care about add vs del ordering on the publish side for > > > that one. > > > > > > The other scenarios I see are related to update operations (add, > > > add_unique, add_replace, replace, del). If a sequence of these > > > operations is executed on the "observer" CPU, and expects to see the > > > effect of the sequence of "add" then "del" performed on the "publisher" > > > CPU in order, then, yes, an additional memory barrier would be required > > > to order add before del. > > > > > > The question here is: do we care about providing order of add before del > > > only for the sake of the other update operations running on another CPU > > > that would expect to see their effect in order ? I don't know, maybe. > > > > > > I guess the safest route would be to provide the ordering guarantee, > > > given that there exists a way to observe this and possibly care about > > > it. I wonder if it would be better to put the barrier after the > > > add/add_unique (success), or before the "del". > > > > > > Also, do you think a write barrier would be sufficient, or we should > > > keep full barriers ? > > > > A write barrier would be sufficient in the case where there were only > > two threads observing each other. A full memory barrier would be needed > > to prevent the assertion from firing in this sort of case (not sure that > > this is exactly right, but something like this): > > > > Initial contents: B, C > > > > T0: add A; del B > > T1: if (!lookup B) { add B; del C } > > T2: r1 = lookup C; smp_mb(); r2 = lookup A > > > > assert(lookup C || lookup A); > > What you are bringing here as counter-example is, I think, transitivity. Yep! > I'm trying to figure out how your example could fail, and I cannot see > how. Follows a detail of the closest scenario I get to failing is the > following, but it does not fail. After that, I'm proposing a different > scenario, which I think will be more appropriate for the current topic. > > Attempted detail of your scenario: > > T0 T1 T2 > > add A > wmb > (add A globally > observable) Almost. All that this really guarantees is that if someone sees the "add B", they will also see the "add A". > del B > (del B globally > observable) > (add A NOT brought > into cache) > (del B brought into > cache) > read B > (test false) > add B > wmb > (add B globally > observable) > del C > (del C globally > observable) Here, if someone sees the "del C", they will see the "add B", and they also will have lost the opportunity to modify B before T1 reads from it and modifies it. > (add A NOT brought > into cache) > (del C brought into > cache) > read C -> not there. > mb > (add A brought > into cache) > read A -> there -> success. So we see that C is not there. We know that B would be there if we looked at it. But we don't look at B, we look at A. But the ordering back to T0's "add A" requires transitivity, which wmb does not guarantee. > If I look at the "transitivity" section in Linux memory-barriers.txt, I > notice that the example is mainly around using read barrier around loads > rather than general barrier. Let's see if I can modify that example to > come up with an example error case: > > Initial content: empty > > T0: add X > T1: r1 = lookup X; smp_mb; r2 = lookup Y > T2: add Y; r3 = lookup X > > assert( !(r1 && !r2 && !r3) ) > > The key thing here is that if the barrier in T2 after "add Y" is a > smp_wmb rather than a smp_mb, this could allow the "r3 = lookup X" to be > reordered before add Y, thus allowing the assertion to fail. Your example is simpler, and demonstrates the need just as well, so let's go with your example. > I think it would be more intuitive for users if lookups vs updates > performed on the same thread are ordered with full memory barriers. > Given that we don't want to add extra barriers in read operations, it > would make sense to guarantee full memory barriers before and after > updates. > > So how about we use full memory barriers before and after each of: add, > del (success), add_unique (success), replace, and add_replace ? If we > ever want to relax those ordering guarantees, then we can always add new > update APIs with a "weaker" ordering. > > Thoughts ? That line of reasoning makes a lot of sense to me! Thanx, Paul > Thanks, > > Mathieu > > > > > Thanx, Paul > > > > > Thanks, > > > > > > Mathieu > > > > > > > > > > > Thanx, Paul > > > > > > > > > Thanks, > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > > > > > > > > > Thoughts ? > > > > > > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Yep, makes sense. > > > > > > > > > > > > > > > > > > > > I'll add this documentation in the API. > > > > > > > > > > > > > > > > > > > > Thanks! > > > > > > > > > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > cds_lfht_is_node_deleted(): Not an update (let alone an atomic update), > > > > > > > > > > > no barriers. > > > > > > > > > > > > > > > > > > > > > > cds_lfht_resize(): Atomic update, but no return value, so no barrier > > > > > > > > > > > implied. > > > > > > > > > > > > > > > > > > > > > > cds_lfht_for_each(): Not an update (let alone an atomic update), > > > > > > > > > > > no barriers. > > > > > > > > > > > > > > > > > > > > > > cds_lfht_for_each_duplicate(): Ditto. > > > > > > > > > > > > > > > > > > > > > > cds_lfht_for_each_entry(): Ditto. > > > > > > > > > > > > > > > > > > > > > > cds_lfht_for_each_entry_duplicate(): Ditto. > > > > > > > > > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > > > > > > > > > > > > > > > I'm personally getting confident that the hash table API is clean > > > > > > > > > > > > enough, and the implementation well tested, but I'd like to have your > > > > > > > > > > > > thoughts on the readiness of the hash table for production use. > > > > > > > > > > > > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > > > > > > > > > > > Mathieu > > > > > > > > > > > > > > > > > > > > > > > > -- > > > > > > > > > > > > Mathieu Desnoyers > > > > > > > > > > > > Operating System Efficiency R&D Consultant > > > > > > > > > > > > EfficiOS Inc. > > > > > > > > > > > > http://www.efficios.com > > > > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > > > > > > rp mailing list > > > > > > > > > > > > rp at svcs.cs.pdx.edu > > > > > > > > > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > > > > > lttng-dev mailing list > > > > > > > > > > > lttng-dev at lists.lttng.org > > > > > > > > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > > > > > > > > > > > > > -- > > > > > > > > > > Mathieu Desnoyers > > > > > > > > > > Operating System Efficiency R&D Consultant > > > > > > > > > > EfficiOS Inc. > > > > > > > > > > http://www.efficios.com > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > > > > lttng-dev mailing list > > > > > > > > > > lttng-dev at lists.lttng.org > > > > > > > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > > > > > > > > > > > -- > > > > > > > > > Mathieu Desnoyers > > > > > > > > > Operating System Efficiency R&D Consultant > > > > > > > > > EfficiOS Inc. > > > > > > > > > http://www.efficios.com > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > > > > rp mailing list > > > > > > > > > rp at svcs.cs.pdx.edu > > > > > > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > -- > > > > > > > Mathieu Desnoyers > > > > > > > Operating System Efficiency R&D Consultant > > > > > > > EfficiOS Inc. > > > > > > > http://www.efficios.com > > > > > > > > > > > > > > _______________________________________________ > > > > > > > rp mailing list > > > > > > > rp at svcs.cs.pdx.edu > > > > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > > > > > > > > > > > > > _______________________________________________ > > > > > > lttng-dev mailing list > > > > > > lttng-dev at lists.lttng.org > > > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > > > > > -- > > > > > Mathieu Desnoyers > > > > > Operating System Efficiency R&D Consultant > > > > > EfficiOS Inc. > > > > > http://www.efficios.com > > > > > > > > > > > > > > > > > _______________________________________________ > > > > lttng-dev mailing list > > > > lttng-dev at lists.lttng.org > > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > > -- > > > Mathieu Desnoyers > > > Operating System Efficiency R&D Consultant > > > EfficiOS Inc. > > > http://www.efficios.com > > > > > > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > From alexandre.montplaisir at polymtl.ca Fri May 4 00:03:29 2012 From: alexandre.montplaisir at polymtl.ca (Alexandre Montplaisir) Date: Fri, 4 May 2012 00:03:29 -0400 Subject: [lttng-dev] [lttng-ust PATCH 1/2] Add Integer and Long tracepoint types to the Java interface Message-ID: <1336104210-3160-1-git-send-email-alexandre.montplaisir@polymtl.ca> Also added Javadoc comments to the .java file. Signed-off-by: Alexandre Montplaisir --- liblttng-ust-java/LTTngUst.c | 38 ++++++++++++++++---- liblttng-ust-java/LTTngUst.java | 67 ++++++++++++++++++++++++++++++++---- liblttng-ust-java/lttng_ust_java.h | 22 ++++++++++-- 3 files changed, 112 insertions(+), 15 deletions(-) diff --git a/liblttng-ust-java/LTTngUst.c b/liblttng-ust-java/LTTngUst.c index 3d23d6a..0bef89d 100644 --- a/liblttng-ust-java/LTTngUst.c +++ b/liblttng-ust-java/LTTngUst.c @@ -22,18 +22,44 @@ #define TRACEPOINT_CREATE_PROBES #include "lttng_ust_java.h" +JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointInt(JNIEnv *env, + jobject jobj, + jstring ev_name, + jint payload) +{ + jboolean iscopy; + const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy); + + tracepoint(lttng_ust_java, int_event, ev_name_cstr, payload); + + (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr); +} + +JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointLong(JNIEnv *env, + jobject jobj, + jstring ev_name, + jlong payload) +{ + jboolean iscopy; + const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy); + + tracepoint(lttng_ust_java, long_event, ev_name_cstr, payload); + + (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr); +} + JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointString(JNIEnv *env, jobject jobj, jstring ev_name, - jstring args) + jstring payload) { jboolean iscopy; - const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, - &iscopy); - const char *args_cstr = (*env)->GetStringUTFChars(env, args, &iscopy); + const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy); + const char *payload_cstr = (*env)->GetStringUTFChars(env, payload, &iscopy); - tracepoint(lttng_ust_java, string, ev_name_cstr, args_cstr); + tracepoint(lttng_ust_java, string_event, ev_name_cstr, payload_cstr); (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr); - (*env)->ReleaseStringUTFChars(env, args, args_cstr); + (*env)->ReleaseStringUTFChars(env, payload, payload_cstr); } + diff --git a/liblttng-ust-java/LTTngUst.java b/liblttng-ust-java/LTTngUst.java index 68ed120..f4bea32 100644 --- a/liblttng-ust-java/LTTngUst.java +++ b/liblttng-ust-java/LTTngUst.java @@ -1,5 +1,6 @@ -/* +/** * Copyright (C) 2011-2012 Mathieu Desnoyers + * Copyright (C) 2012 Alexandre Montplaisir * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,10 +19,64 @@ package org.lttng.ust; -public class LTTngUst { - public static native void tracepointString(String name, String arg); - static { - System.loadLibrary("lttng-ust-java"); - } +/** + * This class implements the the Java side of the LTTng-UST Java interface. + * + * First, make sure you have installed "liblttng-ust-java.so" where the linker + * can find it. You can then call LTTngUst.init() from your Java program to + * connect the methods exposed here to the native library. + * + * Because of limitations in the probe declaration, all trace events generated + * by this library will have "lttng_ust_java" for domain, and "_event" for + * event name in the CTF trace files. The "name" parameter will instead appear + * as the first element of the event's payload. + * + * @author Mathieu Desnoyers + * @author Alexandre Montplaisir + * + */ +public abstract class LTTngUst { + + /** + * Initialize the UST tracer. This should always be called first, before any + * tracepoint* method. + */ + public static void init() { + System.loadLibrary("lttng-ust-java"); //$NON-NLS-1$ + } + + /** + * Insert a tracepoint with a payload of type Integer. + * + * @param name + * The name assigned to this event. For best performance, this + * should be a statically-defined String, or a literal. + * @param payload + * The int payload + */ + public static native void tracepointInt(String name, int payload); + + /** + * Insert a tracepoint with a payload of type Long + * + * @param name + * The name assigned to this event. For best performance, this + * should be a statically-defined String, or a literal. + * @param payload + * The long payload + */ + public static native void tracepointLong(String name, long payload); + + /** + * Insert a tracepoint with a String payload. + * + * @param name + * The name assigned to this event. For best performance, this + * should be a statically-defined String, or a literal. + * @param payload + * The String payload + */ + public static native void tracepointString(String name, String payload); + } diff --git a/liblttng-ust-java/lttng_ust_java.h b/liblttng-ust-java/lttng_ust_java.h index 771d392..7cdbea5 100644 --- a/liblttng-ust-java/lttng_ust_java.h +++ b/liblttng-ust-java/lttng_ust_java.h @@ -24,11 +24,27 @@ #include -TRACEPOINT_EVENT(lttng_ust_java, string, - TP_ARGS(const char *, name, const char *, args), +TRACEPOINT_EVENT(lttng_ust_java, int_event, + TP_ARGS(const char *, name, int, payload), TP_FIELDS( ctf_string(name, name) - ctf_string(args, args) + ctf_integer(int, int_payload, payload) + ) +) + +TRACEPOINT_EVENT(lttng_ust_java, long_event, + TP_ARGS(const char *, name, long, payload), + TP_FIELDS( + ctf_string(name, name) + ctf_integer(long, long_payload, payload) + ) +) + +TRACEPOINT_EVENT(lttng_ust_java, string_event, + TP_ARGS(const char *, name, const char *, payload), + TP_FIELDS( + ctf_string(name, name) + ctf_string(string_payload, payload) ) ) -- 1.7.10 From alexandre.montplaisir at polymtl.ca Fri May 4 00:03:30 2012 From: alexandre.montplaisir at polymtl.ca (Alexandre Montplaisir) Date: Fri, 4 May 2012 00:03:30 -0400 Subject: [lttng-dev] [lttng-ust PATCH 2/2] Add "2x int" and "2x long" types to the Java interface In-Reply-To: <1336104210-3160-1-git-send-email-alexandre.montplaisir@polymtl.ca> References: <1336104210-3160-1-git-send-email-alexandre.montplaisir@polymtl.ca> Message-ID: <1336104210-3160-2-git-send-email-alexandre.montplaisir@polymtl.ca> Since we have to statically define all the available event types, offer types for two integers and two longs, which are relatively common use cases. Signed-off-by: Alexandre Montplaisir --- liblttng-ust-java/LTTngUst.c | 28 ++++++++++++++++++++++++++++ liblttng-ust-java/LTTngUst.java | 28 ++++++++++++++++++++++++++++ liblttng-ust-java/lttng_ust_java.h | 18 ++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/liblttng-ust-java/LTTngUst.c b/liblttng-ust-java/LTTngUst.c index 0bef89d..9ae3983 100644 --- a/liblttng-ust-java/LTTngUst.c +++ b/liblttng-ust-java/LTTngUst.c @@ -35,6 +35,20 @@ JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointInt(JNIEnv *env, (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr); } +JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointIntInt(JNIEnv *env, + jobject jobj, + jstring ev_name, + jint payload1, + jint payload2) +{ + jboolean iscopy; + const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy); + + tracepoint(lttng_ust_java, int_int_event, ev_name_cstr, payload1, payload2); + + (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr); +} + JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointLong(JNIEnv *env, jobject jobj, jstring ev_name, @@ -48,6 +62,20 @@ JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointLong(JNIEnv *env, (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr); } +JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointLongLong(JNIEnv *env, + jobject jobj, + jstring ev_name, + jlong payload1, + jlong payload2) +{ + jboolean iscopy; + const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy); + + tracepoint(lttng_ust_java, long_long_event, ev_name_cstr, payload1, payload2); + + (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr); +} + JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointString(JNIEnv *env, jobject jobj, jstring ev_name, diff --git a/liblttng-ust-java/LTTngUst.java b/liblttng-ust-java/LTTngUst.java index f4bea32..79ad97a 100644 --- a/liblttng-ust-java/LTTngUst.java +++ b/liblttng-ust-java/LTTngUst.java @@ -57,6 +57,20 @@ public abstract class LTTngUst { public static native void tracepointInt(String name, int payload); /** + * Insert a tracepoint with a payload consisting of two integers. + * + * @param name + * The name assigned to this event. For best performance, this + * should be a statically-defined String, or a literal. + * @param payload1 + * The first int payload + * @param payload2 + * The second int payload + */ + public static native void + tracepointIntInt(String name, int payload1, int payload2); + + /** * Insert a tracepoint with a payload of type Long * * @param name @@ -68,6 +82,20 @@ public abstract class LTTngUst { public static native void tracepointLong(String name, long payload); /** + * Insert a tracepoint with a payload consisting of two longs. + * + * @param name + * The name assigned to this event. For best performance, this + * should be a statically-defined String, or a literal. + * @param payload1 + * The first long payload + * @param payload2 + * The second long payload + */ + public static native void + tracepointLongLong(String name, long payload1, long payload2); + + /** * Insert a tracepoint with a String payload. * * @param name diff --git a/liblttng-ust-java/lttng_ust_java.h b/liblttng-ust-java/lttng_ust_java.h index 7cdbea5..7a8b391 100644 --- a/liblttng-ust-java/lttng_ust_java.h +++ b/liblttng-ust-java/lttng_ust_java.h @@ -32,6 +32,15 @@ TRACEPOINT_EVENT(lttng_ust_java, int_event, ) ) +TRACEPOINT_EVENT(lttng_ust_java, int_int_event, + TP_ARGS(const char *, name, int, payload1, int, payload2), + TP_FIELDS( + ctf_string(name, name) + ctf_integer(int, int_payload1, payload1) + ctf_integer(int, int_payload2, payload2) + ) +) + TRACEPOINT_EVENT(lttng_ust_java, long_event, TP_ARGS(const char *, name, long, payload), TP_FIELDS( @@ -40,6 +49,15 @@ TRACEPOINT_EVENT(lttng_ust_java, long_event, ) ) +TRACEPOINT_EVENT(lttng_ust_java, long_long_event, + TP_ARGS(const char *, name, long, payload1, long, payload2), + TP_FIELDS( + ctf_string(name, name) + ctf_integer(long, long_payload1, payload1) + ctf_integer(long, long_payload2, payload2) + ) +) + TRACEPOINT_EVENT(lttng_ust_java, string_event, TP_ARGS(const char *, name, const char *, payload), TP_FIELDS( -- 1.7.10 From mathieu.desnoyers at efficios.com Fri May 4 12:53:12 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 4 May 2012 12:53:12 -0400 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120503174706.GI2592@linux.vnet.ibm.com> References: <20120501152144.GA25061@Krystal> <20120501161337.GF2441@linux.vnet.ibm.com> <20120501174136.GA26609@Krystal> <20120501194713.GL2441@linux.vnet.ibm.com> <20120501210206.GA31952@Krystal> <20120501235007.GS2441@linux.vnet.ibm.com> <20120502041639.GA7857@Krystal> <20120502155430.GF2450@linux.vnet.ibm.com> <20120503171330.GA12234@Krystal> <20120503174706.GI2592@linux.vnet.ibm.com> Message-ID: <20120504165312.GA15996@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > On Thu, May 03, 2012 at 01:13:30PM -0400, Mathieu Desnoyers wrote: > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: [...] > > > > > > A write barrier would be sufficient in the case where there were only > > > two threads observing each other. A full memory barrier would be needed > > > to prevent the assertion from firing in this sort of case (not sure that > > > this is exactly right, but something like this): > > > > > > Initial contents: B, C > > > > > > T0: add A; del B > > > T1: if (!lookup B) { add B; del C } > > > T2: r1 = lookup C; smp_mb(); r2 = lookup A > > > > > > assert(lookup C || lookup A); > > > > What you are bringing here as counter-example is, I think, transitivity. > > Yep! > > > I'm trying to figure out how your example could fail, and I cannot see > > how. Follows a detail of the closest scenario I get to failing is the > > following, but it does not fail. After that, I'm proposing a different > > scenario, which I think will be more appropriate for the current topic. > > > > Attempted detail of your scenario: > > > > T0 T1 T2 > > > > add A > > wmb > > (add A globally > > observable) > > Almost. All that this really guarantees is that if someone sees > the "add B", they will also see the "add A". > > > del B > > (del B globally > > observable) > > (add A NOT brought > > into cache) > > (del B brought into > > cache) > > read B > > (test false) > > add B > > wmb > > (add B globally > > observable) > > del C > > (del C globally > > observable) > > Here, if someone sees the "del C", they will see the "add B", and > they also will have lost the opportunity to modify B before T1 > reads from it and modifies it. > > > (add A NOT brought > > into cache) > > (del C brought into > > cache) > > read C -> not there. > > mb > > (add A brought > > into cache) > > read A -> there -> success. > > So we see that C is not there. We know that B would be there if > we looked at it. But we don't look at B, we look at A. But the > ordering back to T0's "add A" requires transitivity, which wmb > does not guarantee. OK, got it! > > > If I look at the "transitivity" section in Linux memory-barriers.txt, I > > notice that the example is mainly around using read barrier around loads > > rather than general barrier. Let's see if I can modify that example to > > come up with an example error case: > > > > Initial content: empty > > > > T0: add X > > T1: r1 = lookup X; smp_mb; r2 = lookup Y > > T2: add Y; r3 = lookup X > > > > assert( !(r1 && !r2 && !r3) ) > > > > The key thing here is that if the barrier in T2 after "add Y" is a > > smp_wmb rather than a smp_mb, this could allow the "r3 = lookup X" to be > > reordered before add Y, thus allowing the assertion to fail. > > Your example is simpler, and demonstrates the need just as well, so > let's go with your example. > > > I think it would be more intuitive for users if lookups vs updates > > performed on the same thread are ordered with full memory barriers. > > Given that we don't want to add extra barriers in read operations, it > > would make sense to guarantee full memory barriers before and after > > updates. > > > > So how about we use full memory barriers before and after each of: add, > > del (success), add_unique (success), replace, and add_replace ? If we > > ever want to relax those ordering guarantees, then we can always add new > > update APIs with a "weaker" ordering. > > > > Thoughts ? > > That line of reasoning makes a lot of sense to me! Sounds good. Here is what I propose, thoughts ? diff --git a/urcu/rculfhash.h b/urcu/rculfhash.h index 2d8a310..2938e5e 100644 --- a/urcu/rculfhash.h +++ b/urcu/rculfhash.h @@ -203,6 +203,7 @@ void cds_lfht_count_nodes(struct cds_lfht *ht, * * Call with rcu_read_lock held. * Threads calling this API need to be registered RCU read-side threads. + * This function acts as a rcu_dereference() to read the node pointer. */ void cds_lfht_lookup(struct cds_lfht *ht, unsigned long hash, cds_lfht_match_fct match, const void *key, @@ -226,6 +227,7 @@ void cds_lfht_lookup(struct cds_lfht *ht, unsigned long hash, * node returned by a previous cds_lfht_next. * Call with rcu_read_lock held. * Threads calling this API need to be registered RCU read-side threads. + * This function acts as a rcu_dereference() to read the node pointer. */ void cds_lfht_next_duplicate(struct cds_lfht *ht, cds_lfht_match_fct match, const void *key, @@ -239,6 +241,7 @@ void cds_lfht_next_duplicate(struct cds_lfht *ht, * Output in "*iter". *iter->node set to NULL if table is empty. * Call with rcu_read_lock held. * Threads calling this API need to be registered RCU read-side threads. + * This function acts as a rcu_dereference() to read the node pointer. */ void cds_lfht_first(struct cds_lfht *ht, struct cds_lfht_iter *iter); @@ -252,6 +255,7 @@ void cds_lfht_first(struct cds_lfht *ht, struct cds_lfht_iter *iter); * pointing to the last table node. * Call with rcu_read_lock held. * Threads calling this API need to be registered RCU read-side threads. + * This function acts as a rcu_dereference() to read the node pointer. */ void cds_lfht_next(struct cds_lfht *ht, struct cds_lfht_iter *iter); @@ -264,6 +268,8 @@ void cds_lfht_next(struct cds_lfht *ht, struct cds_lfht_iter *iter); * This function supports adding redundant keys into the table. * Call with rcu_read_lock held. * Threads calling this API need to be registered RCU read-side threads. + * This function issues a full memory barrier before and after its + * atomic commit. */ void cds_lfht_add(struct cds_lfht *ht, unsigned long hash, struct cds_lfht_node *node); @@ -288,6 +294,12 @@ void cds_lfht_add(struct cds_lfht *ht, unsigned long hash, * to add keys into the table, no duplicated keys should ever be * observable in the table. The same guarantee apply for combination of * add_unique and add_replace (see below). + * + * Upon success, this function issues a full memory barrier before and + * after its atomic commit. Upon failure, this function acts like a + * simple lookup operation: it acts as a rcu_dereference() to read the + * node pointer. The failure case does not guarantee any other memory + * barrier. */ struct cds_lfht_node *cds_lfht_add_unique(struct cds_lfht *ht, unsigned long hash, @@ -321,6 +333,9 @@ struct cds_lfht_node *cds_lfht_add_unique(struct cds_lfht *ht, * schemes will never generate duplicated keys. It also allows us to * guarantee that a combination of add_replace and add_unique updates * will never generate duplicated keys. + * + * This function issues a full memory barrier before and after its + * atomic commit. */ struct cds_lfht_node *cds_lfht_add_replace(struct cds_lfht *ht, unsigned long hash, @@ -352,6 +367,10 @@ struct cds_lfht_node *cds_lfht_add_replace(struct cds_lfht *ht, * * The semantic of replacement vs lookups is the same as * cds_lfht_add_replace(). + * + * Upon success, this function issues a full memory barrier before and + * after its atomic commit. Upon failure, this function does not issue + * any memory barrier. */ int cds_lfht_replace(struct cds_lfht *ht, struct cds_lfht_iter *old_iter, @@ -377,6 +396,9 @@ int cds_lfht_replace(struct cds_lfht *ht, * After successful removal, a grace period must be waited for before * freeing the memory reserved for old node (which can be accessed with * cds_lfht_iter_get_node). + * Upon success, this function issues a full memory barrier before and + * after its atomic commit. Upon failure, this function does not issue + * any memory barrier. */ int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node); @@ -391,6 +413,7 @@ int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node); * function. * Call with rcu_read_lock held. * Threads calling this API need to be registered RCU read-side threads. + * This function does not issue any memory barrier. */ int cds_lfht_is_node_deleted(struct cds_lfht_node *node); @@ -400,6 +423,7 @@ int cds_lfht_is_node_deleted(struct cds_lfht_node *node); * @new_size: update to this hash table size. * * Threads calling this API need to be registered RCU read-side threads. + * This function does not (necessarily) issue memory barriers. */ void cds_lfht_resize(struct cds_lfht *ht, unsigned long new_size); @@ -407,6 +431,7 @@ void cds_lfht_resize(struct cds_lfht *ht, unsigned long new_size); * Note: it is safe to perform element removal (del), replacement, or * any hash table update operation during any of the following hash * table traversals. + * These functions act as rcu_dereference() to read the node pointers. */ #define cds_lfht_for_each(ht, iter, node) \ for (cds_lfht_first(ht, iter), \ Thanks, Mathieu -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From paulmck at linux.vnet.ibm.com Fri May 4 13:36:13 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Fri, 4 May 2012 10:36:13 -0700 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120504165312.GA15996@Krystal> References: <20120501161337.GF2441@linux.vnet.ibm.com> <20120501174136.GA26609@Krystal> <20120501194713.GL2441@linux.vnet.ibm.com> <20120501210206.GA31952@Krystal> <20120501235007.GS2441@linux.vnet.ibm.com> <20120502041639.GA7857@Krystal> <20120502155430.GF2450@linux.vnet.ibm.com> <20120503171330.GA12234@Krystal> <20120503174706.GI2592@linux.vnet.ibm.com> <20120504165312.GA15996@Krystal> Message-ID: <20120504173613.GI2411@linux.vnet.ibm.com> On Fri, May 04, 2012 at 12:53:12PM -0400, Mathieu Desnoyers wrote: > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > On Thu, May 03, 2012 at 01:13:30PM -0400, Mathieu Desnoyers wrote: > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > [...] > > > > > > > > A write barrier would be sufficient in the case where there were only > > > > two threads observing each other. A full memory barrier would be needed > > > > to prevent the assertion from firing in this sort of case (not sure that > > > > this is exactly right, but something like this): > > > > > > > > Initial contents: B, C > > > > > > > > T0: add A; del B > > > > T1: if (!lookup B) { add B; del C } > > > > T2: r1 = lookup C; smp_mb(); r2 = lookup A > > > > > > > > assert(lookup C || lookup A); > > > > > > What you are bringing here as counter-example is, I think, transitivity. > > > > Yep! > > > > > I'm trying to figure out how your example could fail, and I cannot see > > > how. Follows a detail of the closest scenario I get to failing is the > > > following, but it does not fail. After that, I'm proposing a different > > > scenario, which I think will be more appropriate for the current topic. > > > > > > Attempted detail of your scenario: > > > > > > T0 T1 T2 > > > > > > add A > > > wmb > > > (add A globally > > > observable) > > > > Almost. All that this really guarantees is that if someone sees > > the "add B", they will also see the "add A". > > > > > del B > > > (del B globally > > > observable) > > > (add A NOT brought > > > into cache) > > > (del B brought into > > > cache) > > > read B > > > (test false) > > > add B > > > wmb > > > (add B globally > > > observable) > > > del C > > > (del C globally > > > observable) > > > > Here, if someone sees the "del C", they will see the "add B", and > > they also will have lost the opportunity to modify B before T1 > > reads from it and modifies it. > > > > > (add A NOT brought > > > into cache) > > > (del C brought into > > > cache) > > > read C -> not there. > > > mb > > > (add A brought > > > into cache) > > > read A -> there -> success. > > > > So we see that C is not there. We know that B would be there if > > we looked at it. But we don't look at B, we look at A. But the > > ordering back to T0's "add A" requires transitivity, which wmb > > does not guarantee. > > OK, got it! > > > > > > If I look at the "transitivity" section in Linux memory-barriers.txt, I > > > notice that the example is mainly around using read barrier around loads > > > rather than general barrier. Let's see if I can modify that example to > > > come up with an example error case: > > > > > > Initial content: empty > > > > > > T0: add X > > > T1: r1 = lookup X; smp_mb; r2 = lookup Y > > > T2: add Y; r3 = lookup X > > > > > > assert( !(r1 && !r2 && !r3) ) > > > > > > The key thing here is that if the barrier in T2 after "add Y" is a > > > smp_wmb rather than a smp_mb, this could allow the "r3 = lookup X" to be > > > reordered before add Y, thus allowing the assertion to fail. > > > > Your example is simpler, and demonstrates the need just as well, so > > let's go with your example. > > > > > I think it would be more intuitive for users if lookups vs updates > > > performed on the same thread are ordered with full memory barriers. > > > Given that we don't want to add extra barriers in read operations, it > > > would make sense to guarantee full memory barriers before and after > > > updates. > > > > > > So how about we use full memory barriers before and after each of: add, > > > del (success), add_unique (success), replace, and add_replace ? If we > > > ever want to relax those ordering guarantees, then we can always add new > > > update APIs with a "weaker" ordering. > > > > > > Thoughts ? > > > > That line of reasoning makes a lot of sense to me! > > Sounds good. > > Here is what I propose, thoughts ? Just to make sure I understand -- the reason that the "del" functions say "no memory barrier" instead of "acts like rcu_dereference()" is that the "del" functions don't return anything. Assuming my understanding is correct: Reviewed-by: Paul E. McKenney Thanx, Paul > diff --git a/urcu/rculfhash.h b/urcu/rculfhash.h > index 2d8a310..2938e5e 100644 > --- a/urcu/rculfhash.h > +++ b/urcu/rculfhash.h > @@ -203,6 +203,7 @@ void cds_lfht_count_nodes(struct cds_lfht *ht, > * > * Call with rcu_read_lock held. > * Threads calling this API need to be registered RCU read-side threads. > + * This function acts as a rcu_dereference() to read the node pointer. > */ > void cds_lfht_lookup(struct cds_lfht *ht, unsigned long hash, > cds_lfht_match_fct match, const void *key, > @@ -226,6 +227,7 @@ void cds_lfht_lookup(struct cds_lfht *ht, unsigned long hash, > * node returned by a previous cds_lfht_next. > * Call with rcu_read_lock held. > * Threads calling this API need to be registered RCU read-side threads. > + * This function acts as a rcu_dereference() to read the node pointer. > */ > void cds_lfht_next_duplicate(struct cds_lfht *ht, > cds_lfht_match_fct match, const void *key, > @@ -239,6 +241,7 @@ void cds_lfht_next_duplicate(struct cds_lfht *ht, > * Output in "*iter". *iter->node set to NULL if table is empty. > * Call with rcu_read_lock held. > * Threads calling this API need to be registered RCU read-side threads. > + * This function acts as a rcu_dereference() to read the node pointer. > */ > void cds_lfht_first(struct cds_lfht *ht, struct cds_lfht_iter *iter); > > @@ -252,6 +255,7 @@ void cds_lfht_first(struct cds_lfht *ht, struct cds_lfht_iter *iter); > * pointing to the last table node. > * Call with rcu_read_lock held. > * Threads calling this API need to be registered RCU read-side threads. > + * This function acts as a rcu_dereference() to read the node pointer. > */ > void cds_lfht_next(struct cds_lfht *ht, struct cds_lfht_iter *iter); > > @@ -264,6 +268,8 @@ void cds_lfht_next(struct cds_lfht *ht, struct cds_lfht_iter *iter); > * This function supports adding redundant keys into the table. > * Call with rcu_read_lock held. > * Threads calling this API need to be registered RCU read-side threads. > + * This function issues a full memory barrier before and after its > + * atomic commit. > */ > void cds_lfht_add(struct cds_lfht *ht, unsigned long hash, > struct cds_lfht_node *node); > @@ -288,6 +294,12 @@ void cds_lfht_add(struct cds_lfht *ht, unsigned long hash, > * to add keys into the table, no duplicated keys should ever be > * observable in the table. The same guarantee apply for combination of > * add_unique and add_replace (see below). > + * > + * Upon success, this function issues a full memory barrier before and > + * after its atomic commit. Upon failure, this function acts like a > + * simple lookup operation: it acts as a rcu_dereference() to read the > + * node pointer. The failure case does not guarantee any other memory > + * barrier. > */ > struct cds_lfht_node *cds_lfht_add_unique(struct cds_lfht *ht, > unsigned long hash, > @@ -321,6 +333,9 @@ struct cds_lfht_node *cds_lfht_add_unique(struct cds_lfht *ht, > * schemes will never generate duplicated keys. It also allows us to > * guarantee that a combination of add_replace and add_unique updates > * will never generate duplicated keys. > + * > + * This function issues a full memory barrier before and after its > + * atomic commit. > */ > struct cds_lfht_node *cds_lfht_add_replace(struct cds_lfht *ht, > unsigned long hash, > @@ -352,6 +367,10 @@ struct cds_lfht_node *cds_lfht_add_replace(struct cds_lfht *ht, > * > * The semantic of replacement vs lookups is the same as > * cds_lfht_add_replace(). > + * > + * Upon success, this function issues a full memory barrier before and > + * after its atomic commit. Upon failure, this function does not issue > + * any memory barrier. > */ > int cds_lfht_replace(struct cds_lfht *ht, > struct cds_lfht_iter *old_iter, > @@ -377,6 +396,9 @@ int cds_lfht_replace(struct cds_lfht *ht, > * After successful removal, a grace period must be waited for before > * freeing the memory reserved for old node (which can be accessed with > * cds_lfht_iter_get_node). > + * Upon success, this function issues a full memory barrier before and > + * after its atomic commit. Upon failure, this function does not issue > + * any memory barrier. > */ > int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node); > > @@ -391,6 +413,7 @@ int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node); > * function. > * Call with rcu_read_lock held. > * Threads calling this API need to be registered RCU read-side threads. > + * This function does not issue any memory barrier. > */ > int cds_lfht_is_node_deleted(struct cds_lfht_node *node); > > @@ -400,6 +423,7 @@ int cds_lfht_is_node_deleted(struct cds_lfht_node *node); > * @new_size: update to this hash table size. > * > * Threads calling this API need to be registered RCU read-side threads. > + * This function does not (necessarily) issue memory barriers. > */ > void cds_lfht_resize(struct cds_lfht *ht, unsigned long new_size); > > @@ -407,6 +431,7 @@ void cds_lfht_resize(struct cds_lfht *ht, unsigned long new_size); > * Note: it is safe to perform element removal (del), replacement, or > * any hash table update operation during any of the following hash > * table traversals. > + * These functions act as rcu_dereference() to read the node pointers. > */ > #define cds_lfht_for_each(ht, iter, node) \ > for (cds_lfht_first(ht, iter), \ > > Thanks, > > Mathieu > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > rp mailing list > rp at svcs.cs.pdx.edu > http://svcs.cs.pdx.edu/mailman/listinfo/rp > From loris.degioanni at gmail.com Sat May 5 00:14:17 2012 From: loris.degioanni at gmail.com (Loris Degioanni) Date: Fri, 04 May 2012 21:14:17 -0700 Subject: [lttng-dev] beginner question Message-ID: <4FA4A919.3080808@gmail.com> I just installed the lttng package on a fresh Ubuntu 12 machine, and I'm following the tutorial at http://lttng.org/quickstart. The enable-event step fails with this error: # lttng enable-event sched_switch,sys_open -k kernel event sched_switch created in channel channel0 Error: Event sys_open: Enable kernel event failed (channel channel0, session mysession) Warning: Some command(s) went wrong What am I doing wrong? Loris From alexandre.montplaisir at polymtl.ca Sat May 5 00:31:59 2012 From: alexandre.montplaisir at polymtl.ca (Alexandre Montplaisir) Date: Sat, 05 May 2012 00:31:59 -0400 Subject: [lttng-dev] beginner question In-Reply-To: <4FA4A919.3080808@gmail.com> References: <4FA4A919.3080808@gmail.com> Message-ID: <4FA4AD3F.80400@polymtl.ca> On 12-05-05 12:14 AM, Loris Degioanni wrote: > I just installed the lttng package on a fresh Ubuntu 12 machine, and > I'm following the tutorial at http://lttng.org/quickstart. > The enable-event step fails with this error: > > # lttng enable-event sched_switch,sys_open -k > kernel event sched_switch created in channel channel0 > Error: Event sys_open: Enable kernel event failed (channel channel0, > session mysession) > Warning: Some command(s) went wrong > > What am I doing wrong? > > Loris Hi, Can you please paste the output of: # lttng list -k -- Alexandre Montplaisir DORSAL lab, ?cole Polytechnique de Montr?al From jdesfossez at efficios.com Sat May 5 00:42:46 2012 From: jdesfossez at efficios.com (Julien Desfossez) Date: Sat, 05 May 2012 00:42:46 -0400 Subject: [lttng-dev] beginner question In-Reply-To: <4FA4A919.3080808@gmail.com> References: <4FA4A919.3080808@gmail.com> Message-ID: <4FA4AFC6.80604@efficios.com> Hi, On 05/05/12 12:14 AM, Loris Degioanni wrote: > I just installed the lttng package on a fresh Ubuntu 12 machine, and I'm > following the tutorial at http://lttng.org/quickstart. > The enable-event step fails with this error: > > # lttng enable-event sched_switch,sys_open -k > kernel event sched_switch created in channel channel0 > Error: Event sys_open: Enable kernel event failed (channel channel0, > session mysession) > Warning: Some command(s) went wrong > > What am I doing wrong? As of now, you can't enable system calls tracing one by one (sys_open is a system call), it's either all of them or none. So if you want sched_switch and all the syscalls you have to do : lttng enable-event -k sched_switch lttng enable-event -k --syscall -a Have fun, Julien From alexandre.montplaisir at polymtl.ca Sat May 5 00:49:15 2012 From: alexandre.montplaisir at polymtl.ca (Alexandre Montplaisir) Date: Sat, 05 May 2012 00:49:15 -0400 Subject: [lttng-dev] beginner question In-Reply-To: <4FA4AFC6.80604@efficios.com> References: <4FA4A919.3080808@gmail.com> <4FA4AFC6.80604@efficios.com> Message-ID: <4FA4B14B.9070705@polymtl.ca> On 12-05-05 12:42 AM, Julien Desfossez wrote: > Hi, > > On 05/05/12 12:14 AM, Loris Degioanni wrote: >> I just installed the lttng package on a fresh Ubuntu 12 machine, and I'm >> following the tutorial at http://lttng.org/quickstart. >> The enable-event step fails with this error: >> >> # lttng enable-event sched_switch,sys_open -k >> kernel event sched_switch created in channel channel0 >> Error: Event sys_open: Enable kernel event failed (channel channel0, >> session mysession) >> Warning: Some command(s) went wrong >> >> What am I doing wrong? > As of now, you can't enable system calls tracing one by one (sys_open is > a system call), it's either all of them or none. > > So if you want sched_switch and all the syscalls you have to do : > lttng enable-event -k sched_switch > lttng enable-event -k --syscall -a Well, good to know I guess ;) I'll update the example on the website. Thanks for the catch Loris. Cheers, -- Alexandre Montplaisir DORSAL lab, ?cole Polytechnique de Montr?al From loris.degioanni at gmail.com Sat May 5 01:06:37 2012 From: loris.degioanni at gmail.com (Loris Degioanni) Date: Fri, 04 May 2012 22:06:37 -0700 Subject: [lttng-dev] beginner question In-Reply-To: <4FA4AFC6.80604@efficios.com> References: <4FA4A919.3080808@gmail.com> <4FA4AFC6.80604@efficios.com> Message-ID: <4FA4B55D.5050609@gmail.com> First of all, that worked. Thank you. So let's suppose I only want to track a handful of system calls, what's the most efficient way to filter out everything else? Loris On 5/4/2012 9:42 PM, Julien Desfossez wrote: > Hi, > > On 05/05/12 12:14 AM, Loris Degioanni wrote: >> I just installed the lttng package on a fresh Ubuntu 12 machine, and I'm >> following the tutorial at http://lttng.org/quickstart. >> The enable-event step fails with this error: >> >> # lttng enable-event sched_switch,sys_open -k >> kernel event sched_switch created in channel channel0 >> Error: Event sys_open: Enable kernel event failed (channel channel0, >> session mysession) >> Warning: Some command(s) went wrong >> >> What am I doing wrong? > > As of now, you can't enable system calls tracing one by one (sys_open is > a system call), it's either all of them or none. > > So if you want sched_switch and all the syscalls you have to do : > lttng enable-event -k sched_switch > lttng enable-event -k --syscall -a > > Have fun, > > Julien > From raphael.beamonte at polymtl.ca Sat May 5 01:33:48 2012 From: raphael.beamonte at polymtl.ca (Rapha?l Beamonte) Date: Sat, 5 May 2012 01:33:48 -0400 Subject: [lttng-dev] Lttng support for RT-Patched Linux Kernel 2.6.33 In-Reply-To: <47D610AD9C485E458630BA38C324D3B60113F9EC31CD@EXGMBX01.sasken.com> References: <47D610AD9C485E458630BA38C324D3B60113F9EC31CD@EXGMBX01.sasken.com> Message-ID: <-415305793772962384@unknownmsgid> Hi Pavan, Hi , I want to use LTTng on ARM processor running *Linux 2.6.33 kernel with real-time patches, **My quires are** * whether there?s an LTTng port which is compatible with an RT patched Kernel, If not what?s required to make it RT Patch compatible. Please kindly help me on this. Thanks In Advance, Pavan LTTng is already working on Linux-RT kernels. You don't need to do anything more than installing LTTng ! Rapha?l -------------- next part -------------- An HTML attachment was scrubbed... URL: From jdesfossez at efficios.com Sat May 5 01:54:55 2012 From: jdesfossez at efficios.com (Julien Desfossez) Date: Sat, 05 May 2012 01:54:55 -0400 Subject: [lttng-dev] beginner question In-Reply-To: <4FA4B55D.5050609@gmail.com> References: <4FA4A919.3080808@gmail.com> <4FA4AFC6.80604@efficios.com> <4FA4B55D.5050609@gmail.com> Message-ID: <4FA4C0AF.4010002@efficios.com> > First of all, that worked. Thank you. > > So let's suppose I only want to track a handful of system calls, what's > the most efficient way to filter out everything else? You can't filter at the source for now, you need to trace all system calls, so your filtering will be done at analysis time. If you are using babeltrace, you can just use grep on the output. For example : babeltrace /path/to/your/trace | grep -E "sched_switch|sys_open" I know that's not really pretty, but for now it is the only option. Soon the full-fledged trace viewers will allow a cleaner way to filter and eventually we'll be able to select exactly the syscalls we want. Hope this helps, Julien From mathieu.desnoyers at efficios.com Sat May 5 12:10:09 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sat, 5 May 2012 12:10:09 -0400 Subject: [lttng-dev] Lttng support for RT-Patched Linux Kernel 2.6.33 In-Reply-To: <-415305793772962384@unknownmsgid> References: <47D610AD9C485E458630BA38C324D3B60113F9EC31CD@EXGMBX01.sasken.com> <-415305793772962384@unknownmsgid> Message-ID: <20120505161009.GA20681@Krystal> * Rapha?l Beamonte (raphael.beamonte at polymtl.ca) wrote: > Hi Pavan, > > Hi , > > > > I want to use LTTng on ARM processor running *Linux 2.6.33 kernel with > real-time patches, **My quires are** * > > whether there?s an LTTng port which is compatible with an RT patched > Kernel, If not what?s required to make it RT Patch compatible. Please > kindly help me on this. > > > > Thanks In Advance, > > Pavan > > > LTTng is already working on Linux-RT kernels. You don't need to do anything > more than installing LTTng ! However, LTTng 2.0 supports only kernels 2.6.38 and more recent at this point. There are a couple of upstream commits you might need to backport to get it to work with 2.6.33. Yannick: I think you have those patches somewhere, can we publish them on the lttng.org website. If you can just send the tarball bundle in reply to this email, we'll take it from there. Best regards, Mathieu > > Rapha?l > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Sat May 5 14:22:12 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sat, 5 May 2012 14:22:12 -0400 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120504173613.GI2411@linux.vnet.ibm.com> References: <20120501174136.GA26609@Krystal> <20120501194713.GL2441@linux.vnet.ibm.com> <20120501210206.GA31952@Krystal> <20120501235007.GS2441@linux.vnet.ibm.com> <20120502041639.GA7857@Krystal> <20120502155430.GF2450@linux.vnet.ibm.com> <20120503171330.GA12234@Krystal> <20120503174706.GI2592@linux.vnet.ibm.com> <20120504165312.GA15996@Krystal> <20120504173613.GI2411@linux.vnet.ibm.com> Message-ID: <20120505182212.GA23461@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > On Fri, May 04, 2012 at 12:53:12PM -0400, Mathieu Desnoyers wrote: > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > On Thu, May 03, 2012 at 01:13:30PM -0400, Mathieu Desnoyers wrote: > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > [...] > > > > > > > > > > A write barrier would be sufficient in the case where there were only > > > > > two threads observing each other. A full memory barrier would be needed > > > > > to prevent the assertion from firing in this sort of case (not sure that > > > > > this is exactly right, but something like this): > > > > > > > > > > Initial contents: B, C > > > > > > > > > > T0: add A; del B > > > > > T1: if (!lookup B) { add B; del C } > > > > > T2: r1 = lookup C; smp_mb(); r2 = lookup A > > > > > > > > > > assert(lookup C || lookup A); > > > > > > > > What you are bringing here as counter-example is, I think, transitivity. > > > > > > Yep! > > > > > > > I'm trying to figure out how your example could fail, and I cannot see > > > > how. Follows a detail of the closest scenario I get to failing is the > > > > following, but it does not fail. After that, I'm proposing a different > > > > scenario, which I think will be more appropriate for the current topic. > > > > > > > > Attempted detail of your scenario: > > > > > > > > T0 T1 T2 > > > > > > > > add A > > > > wmb > > > > (add A globally > > > > observable) > > > > > > Almost. All that this really guarantees is that if someone sees > > > the "add B", they will also see the "add A". > > > > > > > del B > > > > (del B globally > > > > observable) > > > > (add A NOT brought > > > > into cache) > > > > (del B brought into > > > > cache) > > > > read B > > > > (test false) > > > > add B > > > > wmb > > > > (add B globally > > > > observable) > > > > del C > > > > (del C globally > > > > observable) > > > > > > Here, if someone sees the "del C", they will see the "add B", and > > > they also will have lost the opportunity to modify B before T1 > > > reads from it and modifies it. > > > > > > > (add A NOT brought > > > > into cache) > > > > (del C brought into > > > > cache) > > > > read C -> not there. > > > > mb > > > > (add A brought > > > > into cache) > > > > read A -> there -> success. > > > > > > So we see that C is not there. We know that B would be there if > > > we looked at it. But we don't look at B, we look at A. But the > > > ordering back to T0's "add A" requires transitivity, which wmb > > > does not guarantee. > > > > OK, got it! > > > > > > > > > If I look at the "transitivity" section in Linux memory-barriers.txt, I > > > > notice that the example is mainly around using read barrier around loads > > > > rather than general barrier. Let's see if I can modify that example to > > > > come up with an example error case: > > > > > > > > Initial content: empty > > > > > > > > T0: add X > > > > T1: r1 = lookup X; smp_mb; r2 = lookup Y > > > > T2: add Y; r3 = lookup X > > > > > > > > assert( !(r1 && !r2 && !r3) ) > > > > > > > > The key thing here is that if the barrier in T2 after "add Y" is a > > > > smp_wmb rather than a smp_mb, this could allow the "r3 = lookup X" to be > > > > reordered before add Y, thus allowing the assertion to fail. > > > > > > Your example is simpler, and demonstrates the need just as well, so > > > let's go with your example. > > > > > > > I think it would be more intuitive for users if lookups vs updates > > > > performed on the same thread are ordered with full memory barriers. > > > > Given that we don't want to add extra barriers in read operations, it > > > > would make sense to guarantee full memory barriers before and after > > > > updates. > > > > > > > > So how about we use full memory barriers before and after each of: add, > > > > del (success), add_unique (success), replace, and add_replace ? If we > > > > ever want to relax those ordering guarantees, then we can always add new > > > > update APIs with a "weaker" ordering. > > > > > > > > Thoughts ? > > > > > > That line of reasoning makes a lot of sense to me! > > > > Sounds good. > > > > Here is what I propose, thoughts ? > > Just to make sure I understand -- the reason that the "del" functions > say "no memory barrier" instead of "acts like rcu_dereference()" is > that the "del" functions don't return anything. Hrm, you bring an interesting point. I think we should change the two "rcu_dereference()" in _cds_lfht_del for "CMM_LOAD_SHARED()". The difference between the two is that CMM_LOAD_SHARED() does not imply a read barrier between the read and following uses of the data pointed to by the pointer read. Same thing for "cds_lfht_is_node_deleted": the rcu_dereference() should be changed for a CMM_LOAD_SHARED(), because we never use the loaded pointer as a pointer to other data. There are a few other locations where the pointer is only used for its flags. Here is what I propose: diff --git a/rculfhash.c b/rculfhash.c index b9f795f..6e27436 100644 --- a/rculfhash.c +++ b/rculfhash.c @@ -923,7 +923,7 @@ int _cds_lfht_replace(struct cds_lfht *ht, unsigned long size, bucket = lookup_bucket(ht, size, bit_reverse_ulong(old_node->reverse_hash)); _cds_lfht_gc_bucket(bucket, new_node); - assert(is_removed(rcu_dereference(old_node->next))); + assert(is_removed(CMM_LOAD_SHARED(old_node->next))); return 0; } @@ -1061,7 +1061,7 @@ int _cds_lfht_del(struct cds_lfht *ht, unsigned long size, * logical removal flag). Return -ENOENT if the node had * previously been removed. */ - next = rcu_dereference(node->next); + next = CMM_LOAD_SHARED(node->next); if (caa_unlikely(is_removed(next))) return -ENOENT; assert(!is_bucket(next)); @@ -1082,7 +1082,7 @@ int _cds_lfht_del(struct cds_lfht *ht, unsigned long size, bucket = lookup_bucket(ht, size, bit_reverse_ulong(node->reverse_hash)); _cds_lfht_gc_bucket(bucket, node); - assert(is_removed(rcu_dereference(node->next))); + assert(is_removed(CMM_LOAD_SHARED(node->next))); /* * Last phase: atomically exchange node->next with a version * having "REMOVAL_OWNER_FLAG" set. If the returned node->next @@ -1510,7 +1510,7 @@ void cds_lfht_lookup(struct cds_lfht *ht, unsigned long hash, } node = clear_flag(next); } - assert(!node || !is_bucket(rcu_dereference(node->next))); + assert(!node || !is_bucket(CMM_LOAD_SHARED(node->next))); iter->node = node; iter->next = next; } @@ -1543,7 +1543,7 @@ void cds_lfht_next_duplicate(struct cds_lfht *ht, cds_lfht_match_fct match, } node = clear_flag(next); } - assert(!node || !is_bucket(rcu_dereference(node->next))); + assert(!node || !is_bucket(CMM_LOAD_SHARED(node->next))); iter->node = node; iter->next = next; } @@ -1565,7 +1565,7 @@ void cds_lfht_next(struct cds_lfht *ht, struct cds_lfht_iter *iter) } node = clear_flag(next); } - assert(!node || !is_bucket(rcu_dereference(node->next))); + assert(!node || !is_bucket(CMM_LOAD_SHARED(node->next))); iter->node = node; iter->next = next; } @@ -1668,7 +1668,7 @@ int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node) int cds_lfht_is_node_deleted(struct cds_lfht_node *node) { - return is_removed(rcu_dereference(node->next)); + return is_removed(CMM_LOAD_SHARED(node->next)); } static If it's ok for you, I will first commit this change, and then commit the memory barrier documentation with your reviewed-by. Thanks! Mathieu > > Assuming my understanding is correct: > > Reviewed-by: Paul E. McKenney > > Thanx, Paul > > > diff --git a/urcu/rculfhash.h b/urcu/rculfhash.h > > index 2d8a310..2938e5e 100644 > > --- a/urcu/rculfhash.h > > +++ b/urcu/rculfhash.h > > @@ -203,6 +203,7 @@ void cds_lfht_count_nodes(struct cds_lfht *ht, > > * > > * Call with rcu_read_lock held. > > * Threads calling this API need to be registered RCU read-side threads. > > + * This function acts as a rcu_dereference() to read the node pointer. > > */ > > void cds_lfht_lookup(struct cds_lfht *ht, unsigned long hash, > > cds_lfht_match_fct match, const void *key, > > @@ -226,6 +227,7 @@ void cds_lfht_lookup(struct cds_lfht *ht, unsigned long hash, > > * node returned by a previous cds_lfht_next. > > * Call with rcu_read_lock held. > > * Threads calling this API need to be registered RCU read-side threads. > > + * This function acts as a rcu_dereference() to read the node pointer. > > */ > > void cds_lfht_next_duplicate(struct cds_lfht *ht, > > cds_lfht_match_fct match, const void *key, > > @@ -239,6 +241,7 @@ void cds_lfht_next_duplicate(struct cds_lfht *ht, > > * Output in "*iter". *iter->node set to NULL if table is empty. > > * Call with rcu_read_lock held. > > * Threads calling this API need to be registered RCU read-side threads. > > + * This function acts as a rcu_dereference() to read the node pointer. > > */ > > void cds_lfht_first(struct cds_lfht *ht, struct cds_lfht_iter *iter); > > > > @@ -252,6 +255,7 @@ void cds_lfht_first(struct cds_lfht *ht, struct cds_lfht_iter *iter); > > * pointing to the last table node. > > * Call with rcu_read_lock held. > > * Threads calling this API need to be registered RCU read-side threads. > > + * This function acts as a rcu_dereference() to read the node pointer. > > */ > > void cds_lfht_next(struct cds_lfht *ht, struct cds_lfht_iter *iter); > > > > @@ -264,6 +268,8 @@ void cds_lfht_next(struct cds_lfht *ht, struct cds_lfht_iter *iter); > > * This function supports adding redundant keys into the table. > > * Call with rcu_read_lock held. > > * Threads calling this API need to be registered RCU read-side threads. > > + * This function issues a full memory barrier before and after its > > + * atomic commit. > > */ > > void cds_lfht_add(struct cds_lfht *ht, unsigned long hash, > > struct cds_lfht_node *node); > > @@ -288,6 +294,12 @@ void cds_lfht_add(struct cds_lfht *ht, unsigned long hash, > > * to add keys into the table, no duplicated keys should ever be > > * observable in the table. The same guarantee apply for combination of > > * add_unique and add_replace (see below). > > + * > > + * Upon success, this function issues a full memory barrier before and > > + * after its atomic commit. Upon failure, this function acts like a > > + * simple lookup operation: it acts as a rcu_dereference() to read the > > + * node pointer. The failure case does not guarantee any other memory > > + * barrier. > > */ > > struct cds_lfht_node *cds_lfht_add_unique(struct cds_lfht *ht, > > unsigned long hash, > > @@ -321,6 +333,9 @@ struct cds_lfht_node *cds_lfht_add_unique(struct cds_lfht *ht, > > * schemes will never generate duplicated keys. It also allows us to > > * guarantee that a combination of add_replace and add_unique updates > > * will never generate duplicated keys. > > + * > > + * This function issues a full memory barrier before and after its > > + * atomic commit. > > */ > > struct cds_lfht_node *cds_lfht_add_replace(struct cds_lfht *ht, > > unsigned long hash, > > @@ -352,6 +367,10 @@ struct cds_lfht_node *cds_lfht_add_replace(struct cds_lfht *ht, > > * > > * The semantic of replacement vs lookups is the same as > > * cds_lfht_add_replace(). > > + * > > + * Upon success, this function issues a full memory barrier before and > > + * after its atomic commit. Upon failure, this function does not issue > > + * any memory barrier. > > */ > > int cds_lfht_replace(struct cds_lfht *ht, > > struct cds_lfht_iter *old_iter, > > @@ -377,6 +396,9 @@ int cds_lfht_replace(struct cds_lfht *ht, > > * After successful removal, a grace period must be waited for before > > * freeing the memory reserved for old node (which can be accessed with > > * cds_lfht_iter_get_node). > > + * Upon success, this function issues a full memory barrier before and > > + * after its atomic commit. Upon failure, this function does not issue > > + * any memory barrier. > > */ > > int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node); > > > > @@ -391,6 +413,7 @@ int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node); > > * function. > > * Call with rcu_read_lock held. > > * Threads calling this API need to be registered RCU read-side threads. > > + * This function does not issue any memory barrier. > > */ > > int cds_lfht_is_node_deleted(struct cds_lfht_node *node); > > > > @@ -400,6 +423,7 @@ int cds_lfht_is_node_deleted(struct cds_lfht_node *node); > > * @new_size: update to this hash table size. > > * > > * Threads calling this API need to be registered RCU read-side threads. > > + * This function does not (necessarily) issue memory barriers. > > */ > > void cds_lfht_resize(struct cds_lfht *ht, unsigned long new_size); > > > > @@ -407,6 +431,7 @@ void cds_lfht_resize(struct cds_lfht *ht, unsigned long new_size); > > * Note: it is safe to perform element removal (del), replacement, or > > * any hash table update operation during any of the following hash > > * table traversals. > > + * These functions act as rcu_dereference() to read the node pointers. > > */ > > #define cds_lfht_for_each(ht, iter, node) \ > > for (cds_lfht_first(ht, iter), \ > > > > Thanks, > > > > Mathieu > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > > > _______________________________________________ > > rp mailing list > > rp at svcs.cs.pdx.edu > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From ctuffli at gmail.com Sun May 6 01:17:02 2012 From: ctuffli at gmail.com (Chuck Tuffli) Date: Sat, 5 May 2012 22:17:02 -0700 Subject: [lttng-dev] tracing program flow Message-ID: Hi - I'm investigating the feasibility of replacing some home grown tracing code with LTTng and am looking for advice from others who have used LTTng to trace program flow (i.e. trace function entry and exit points). One of the strengths of LTTng seems to be the ability to selectively enable tracepoints of interest (much more useful than our all-or-nothing tracing). To get this type of capability, would I need to implement an entry and exit tracepoint for each function or is there a better approach? Any other best practices people would be willing to share? TIA. ---chuck From paulmck at linux.vnet.ibm.com Sun May 6 11:56:40 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Sun, 6 May 2012 08:56:40 -0700 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120505182212.GA23461@Krystal> References: <20120501194713.GL2441@linux.vnet.ibm.com> <20120501210206.GA31952@Krystal> <20120501235007.GS2441@linux.vnet.ibm.com> <20120502041639.GA7857@Krystal> <20120502155430.GF2450@linux.vnet.ibm.com> <20120503171330.GA12234@Krystal> <20120503174706.GI2592@linux.vnet.ibm.com> <20120504165312.GA15996@Krystal> <20120504173613.GI2411@linux.vnet.ibm.com> <20120505182212.GA23461@Krystal> Message-ID: <20120506155640.GJ2470@linux.vnet.ibm.com> On Sat, May 05, 2012 at 02:22:12PM -0400, Mathieu Desnoyers wrote: > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > On Fri, May 04, 2012 at 12:53:12PM -0400, Mathieu Desnoyers wrote: > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > On Thu, May 03, 2012 at 01:13:30PM -0400, Mathieu Desnoyers wrote: > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > [...] > > > > > > > > > > > > A write barrier would be sufficient in the case where there were only > > > > > > two threads observing each other. A full memory barrier would be needed > > > > > > to prevent the assertion from firing in this sort of case (not sure that > > > > > > this is exactly right, but something like this): > > > > > > > > > > > > Initial contents: B, C > > > > > > > > > > > > T0: add A; del B > > > > > > T1: if (!lookup B) { add B; del C } > > > > > > T2: r1 = lookup C; smp_mb(); r2 = lookup A > > > > > > > > > > > > assert(lookup C || lookup A); > > > > > > > > > > What you are bringing here as counter-example is, I think, transitivity. > > > > > > > > Yep! > > > > > > > > > I'm trying to figure out how your example could fail, and I cannot see > > > > > how. Follows a detail of the closest scenario I get to failing is the > > > > > following, but it does not fail. After that, I'm proposing a different > > > > > scenario, which I think will be more appropriate for the current topic. > > > > > > > > > > Attempted detail of your scenario: > > > > > > > > > > T0 T1 T2 > > > > > > > > > > add A > > > > > wmb > > > > > (add A globally > > > > > observable) > > > > > > > > Almost. All that this really guarantees is that if someone sees > > > > the "add B", they will also see the "add A". > > > > > > > > > del B > > > > > (del B globally > > > > > observable) > > > > > (add A NOT brought > > > > > into cache) > > > > > (del B brought into > > > > > cache) > > > > > read B > > > > > (test false) > > > > > add B > > > > > wmb > > > > > (add B globally > > > > > observable) > > > > > del C > > > > > (del C globally > > > > > observable) > > > > > > > > Here, if someone sees the "del C", they will see the "add B", and > > > > they also will have lost the opportunity to modify B before T1 > > > > reads from it and modifies it. > > > > > > > > > (add A NOT brought > > > > > into cache) > > > > > (del C brought into > > > > > cache) > > > > > read C -> not there. > > > > > mb > > > > > (add A brought > > > > > into cache) > > > > > read A -> there -> success. > > > > > > > > So we see that C is not there. We know that B would be there if > > > > we looked at it. But we don't look at B, we look at A. But the > > > > ordering back to T0's "add A" requires transitivity, which wmb > > > > does not guarantee. > > > > > > OK, got it! > > > > > > > > > > > > If I look at the "transitivity" section in Linux memory-barriers.txt, I > > > > > notice that the example is mainly around using read barrier around loads > > > > > rather than general barrier. Let's see if I can modify that example to > > > > > come up with an example error case: > > > > > > > > > > Initial content: empty > > > > > > > > > > T0: add X > > > > > T1: r1 = lookup X; smp_mb; r2 = lookup Y > > > > > T2: add Y; r3 = lookup X > > > > > > > > > > assert( !(r1 && !r2 && !r3) ) > > > > > > > > > > The key thing here is that if the barrier in T2 after "add Y" is a > > > > > smp_wmb rather than a smp_mb, this could allow the "r3 = lookup X" to be > > > > > reordered before add Y, thus allowing the assertion to fail. > > > > > > > > Your example is simpler, and demonstrates the need just as well, so > > > > let's go with your example. > > > > > > > > > I think it would be more intuitive for users if lookups vs updates > > > > > performed on the same thread are ordered with full memory barriers. > > > > > Given that we don't want to add extra barriers in read operations, it > > > > > would make sense to guarantee full memory barriers before and after > > > > > updates. > > > > > > > > > > So how about we use full memory barriers before and after each of: add, > > > > > del (success), add_unique (success), replace, and add_replace ? If we > > > > > ever want to relax those ordering guarantees, then we can always add new > > > > > update APIs with a "weaker" ordering. > > > > > > > > > > Thoughts ? > > > > > > > > That line of reasoning makes a lot of sense to me! > > > > > > Sounds good. > > > > > > Here is what I propose, thoughts ? > > > > Just to make sure I understand -- the reason that the "del" functions > > say "no memory barrier" instead of "acts like rcu_dereference()" is > > that the "del" functions don't return anything. > > Hrm, you bring an interesting point. I think we should change the two > "rcu_dereference()" in _cds_lfht_del for "CMM_LOAD_SHARED()". The > difference between the two is that CMM_LOAD_SHARED() does not imply a > read barrier between the read and following uses of the data pointed to > by the pointer read. > > Same thing for "cds_lfht_is_node_deleted": the rcu_dereference() should > be changed for a CMM_LOAD_SHARED(), because we never use the loaded > pointer as a pointer to other data. There are a few other locations > where the pointer is only used for its flags. > > Here is what I propose: > > diff --git a/rculfhash.c b/rculfhash.c > index b9f795f..6e27436 100644 > --- a/rculfhash.c > +++ b/rculfhash.c > @@ -923,7 +923,7 @@ int _cds_lfht_replace(struct cds_lfht *ht, unsigned long size, > bucket = lookup_bucket(ht, size, bit_reverse_ulong(old_node->reverse_hash)); > _cds_lfht_gc_bucket(bucket, new_node); > > - assert(is_removed(rcu_dereference(old_node->next))); > + assert(is_removed(CMM_LOAD_SHARED(old_node->next))); This is good. > return 0; > } > > @@ -1061,7 +1061,7 @@ int _cds_lfht_del(struct cds_lfht *ht, unsigned long size, > * logical removal flag). Return -ENOENT if the node had > * previously been removed. > */ > - next = rcu_dereference(node->next); > + next = CMM_LOAD_SHARED(node->next); > if (caa_unlikely(is_removed(next))) > return -ENOENT; > assert(!is_bucket(next)); As long as "next" is not dereferenced anywhere, this is good. Which appears to be the case. > @@ -1082,7 +1082,7 @@ int _cds_lfht_del(struct cds_lfht *ht, unsigned long size, > bucket = lookup_bucket(ht, size, bit_reverse_ulong(node->reverse_hash)); > _cds_lfht_gc_bucket(bucket, node); > > - assert(is_removed(rcu_dereference(node->next))); > + assert(is_removed(CMM_LOAD_SHARED(node->next))); This one is fine as well. > /* > * Last phase: atomically exchange node->next with a version > * having "REMOVAL_OWNER_FLAG" set. If the returned node->next > @@ -1510,7 +1510,7 @@ void cds_lfht_lookup(struct cds_lfht *ht, unsigned long hash, > } > node = clear_flag(next); > } > - assert(!node || !is_bucket(rcu_dereference(node->next))); > + assert(!node || !is_bucket(CMM_LOAD_SHARED(node->next))); As is this one. > iter->node = node; > iter->next = next; > } > @@ -1543,7 +1543,7 @@ void cds_lfht_next_duplicate(struct cds_lfht *ht, cds_lfht_match_fct match, > } > node = clear_flag(next); > } > - assert(!node || !is_bucket(rcu_dereference(node->next))); > + assert(!node || !is_bucket(CMM_LOAD_SHARED(node->next))); Same here. > iter->node = node; > iter->next = next; > } > @@ -1565,7 +1565,7 @@ void cds_lfht_next(struct cds_lfht *ht, struct cds_lfht_iter *iter) > } > node = clear_flag(next); > } > - assert(!node || !is_bucket(rcu_dereference(node->next))); > + assert(!node || !is_bucket(CMM_LOAD_SHARED(node->next))); And here. > iter->node = node; > iter->next = next; > } > @@ -1668,7 +1668,7 @@ int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node) > > int cds_lfht_is_node_deleted(struct cds_lfht_node *node) > { > - return is_removed(rcu_dereference(node->next)); > + return is_removed(CMM_LOAD_SHARED(node->next)); And also here. > } > > static > > If it's ok for you, I will first commit this change, and then commit the > memory barrier documentation with your reviewed-by. Looks good! Thanx, Paul > Thanks! > > Mathieu > > > > > Assuming my understanding is correct: > > > > Reviewed-by: Paul E. McKenney > > > > Thanx, Paul > > > > > diff --git a/urcu/rculfhash.h b/urcu/rculfhash.h > > > index 2d8a310..2938e5e 100644 > > > --- a/urcu/rculfhash.h > > > +++ b/urcu/rculfhash.h > > > @@ -203,6 +203,7 @@ void cds_lfht_count_nodes(struct cds_lfht *ht, > > > * > > > * Call with rcu_read_lock held. > > > * Threads calling this API need to be registered RCU read-side threads. > > > + * This function acts as a rcu_dereference() to read the node pointer. > > > */ > > > void cds_lfht_lookup(struct cds_lfht *ht, unsigned long hash, > > > cds_lfht_match_fct match, const void *key, > > > @@ -226,6 +227,7 @@ void cds_lfht_lookup(struct cds_lfht *ht, unsigned long hash, > > > * node returned by a previous cds_lfht_next. > > > * Call with rcu_read_lock held. > > > * Threads calling this API need to be registered RCU read-side threads. > > > + * This function acts as a rcu_dereference() to read the node pointer. > > > */ > > > void cds_lfht_next_duplicate(struct cds_lfht *ht, > > > cds_lfht_match_fct match, const void *key, > > > @@ -239,6 +241,7 @@ void cds_lfht_next_duplicate(struct cds_lfht *ht, > > > * Output in "*iter". *iter->node set to NULL if table is empty. > > > * Call with rcu_read_lock held. > > > * Threads calling this API need to be registered RCU read-side threads. > > > + * This function acts as a rcu_dereference() to read the node pointer. > > > */ > > > void cds_lfht_first(struct cds_lfht *ht, struct cds_lfht_iter *iter); > > > > > > @@ -252,6 +255,7 @@ void cds_lfht_first(struct cds_lfht *ht, struct cds_lfht_iter *iter); > > > * pointing to the last table node. > > > * Call with rcu_read_lock held. > > > * Threads calling this API need to be registered RCU read-side threads. > > > + * This function acts as a rcu_dereference() to read the node pointer. > > > */ > > > void cds_lfht_next(struct cds_lfht *ht, struct cds_lfht_iter *iter); > > > > > > @@ -264,6 +268,8 @@ void cds_lfht_next(struct cds_lfht *ht, struct cds_lfht_iter *iter); > > > * This function supports adding redundant keys into the table. > > > * Call with rcu_read_lock held. > > > * Threads calling this API need to be registered RCU read-side threads. > > > + * This function issues a full memory barrier before and after its > > > + * atomic commit. > > > */ > > > void cds_lfht_add(struct cds_lfht *ht, unsigned long hash, > > > struct cds_lfht_node *node); > > > @@ -288,6 +294,12 @@ void cds_lfht_add(struct cds_lfht *ht, unsigned long hash, > > > * to add keys into the table, no duplicated keys should ever be > > > * observable in the table. The same guarantee apply for combination of > > > * add_unique and add_replace (see below). > > > + * > > > + * Upon success, this function issues a full memory barrier before and > > > + * after its atomic commit. Upon failure, this function acts like a > > > + * simple lookup operation: it acts as a rcu_dereference() to read the > > > + * node pointer. The failure case does not guarantee any other memory > > > + * barrier. > > > */ > > > struct cds_lfht_node *cds_lfht_add_unique(struct cds_lfht *ht, > > > unsigned long hash, > > > @@ -321,6 +333,9 @@ struct cds_lfht_node *cds_lfht_add_unique(struct cds_lfht *ht, > > > * schemes will never generate duplicated keys. It also allows us to > > > * guarantee that a combination of add_replace and add_unique updates > > > * will never generate duplicated keys. > > > + * > > > + * This function issues a full memory barrier before and after its > > > + * atomic commit. > > > */ > > > struct cds_lfht_node *cds_lfht_add_replace(struct cds_lfht *ht, > > > unsigned long hash, > > > @@ -352,6 +367,10 @@ struct cds_lfht_node *cds_lfht_add_replace(struct cds_lfht *ht, > > > * > > > * The semantic of replacement vs lookups is the same as > > > * cds_lfht_add_replace(). > > > + * > > > + * Upon success, this function issues a full memory barrier before and > > > + * after its atomic commit. Upon failure, this function does not issue > > > + * any memory barrier. > > > */ > > > int cds_lfht_replace(struct cds_lfht *ht, > > > struct cds_lfht_iter *old_iter, > > > @@ -377,6 +396,9 @@ int cds_lfht_replace(struct cds_lfht *ht, > > > * After successful removal, a grace period must be waited for before > > > * freeing the memory reserved for old node (which can be accessed with > > > * cds_lfht_iter_get_node). > > > + * Upon success, this function issues a full memory barrier before and > > > + * after its atomic commit. Upon failure, this function does not issue > > > + * any memory barrier. > > > */ > > > int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node); > > > > > > @@ -391,6 +413,7 @@ int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node); > > > * function. > > > * Call with rcu_read_lock held. > > > * Threads calling this API need to be registered RCU read-side threads. > > > + * This function does not issue any memory barrier. > > > */ > > > int cds_lfht_is_node_deleted(struct cds_lfht_node *node); > > > > > > @@ -400,6 +423,7 @@ int cds_lfht_is_node_deleted(struct cds_lfht_node *node); > > > * @new_size: update to this hash table size. > > > * > > > * Threads calling this API need to be registered RCU read-side threads. > > > + * This function does not (necessarily) issue memory barriers. > > > */ > > > void cds_lfht_resize(struct cds_lfht *ht, unsigned long new_size); > > > > > > @@ -407,6 +431,7 @@ void cds_lfht_resize(struct cds_lfht *ht, unsigned long new_size); > > > * Note: it is safe to perform element removal (del), replacement, or > > > * any hash table update operation during any of the following hash > > > * table traversals. > > > + * These functions act as rcu_dereference() to read the node pointers. > > > */ > > > #define cds_lfht_for_each(ht, iter, node) \ > > > for (cds_lfht_first(ht, iter), \ > > > > > > Thanks, > > > > > > Mathieu > > > > > > -- > > > Mathieu Desnoyers > > > Operating System Efficiency R&D Consultant > > > EfficiOS Inc. > > > http://www.efficios.com > > > > > > _______________________________________________ > > > rp mailing list > > > rp at svcs.cs.pdx.edu > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > From alexandre.montplaisir at polymtl.ca Sun May 6 12:19:34 2012 From: alexandre.montplaisir at polymtl.ca (Alexandre Montplaisir) Date: Sun, 06 May 2012 12:19:34 -0400 Subject: [lttng-dev] tracing program flow In-Reply-To: References: Message-ID: <4FA6A496.9070101@polymtl.ca> On 12-05-06 01:17 AM, Chuck Tuffli wrote: > Hi - > > I'm investigating the feasibility of replacing some home grown tracing > code with LTTng and am looking for advice from others who have used > LTTng to trace program flow (i.e. trace function entry and exit > points). One of the strengths of LTTng seems to be the ability to > selectively enable tracepoints of interest (much more useful than our > all-or-nothing tracing). To get this type of capability, would I need > to implement an entry and exit tracepoint for each function or is > there a better approach? Any other best practices people would be > willing to share? TIA. Hi, For now you'd have to create a custom probe for each function entry and exit. There's a feature on the wishlist to use GCC hooks to automatically generate those probes [1]. The end result would be the same, but it would be much less tedious to do the instrumentation part. A Clang plugin was also mentioned previously [2], but I don't think anybody has tried it yet. [1] https://bugs.lttng.org/issues/39 [2] http://lists.lttng.org/pipermail/lttng-dev/2012-April/017787.html Hope this helps, -- Alexandre Montplaisir DORSAL lab, ?cole Polytechnique de Montr?al From mathieu.desnoyers at efficios.com Sun May 6 12:27:02 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 6 May 2012 12:27:02 -0400 Subject: [lttng-dev] tracing program flow In-Reply-To: <4FA6A496.9070101@polymtl.ca> References: <4FA6A496.9070101@polymtl.ca> Message-ID: <20120506162701.GB10374@Krystal> * Alexandre Montplaisir (alexandre.montplaisir at polymtl.ca) wrote: > On 12-05-06 01:17 AM, Chuck Tuffli wrote: > > Hi - > > > > I'm investigating the feasibility of replacing some home grown tracing > > code with LTTng and am looking for advice from others who have used > > LTTng to trace program flow (i.e. trace function entry and exit > > points). One of the strengths of LTTng seems to be the ability to > > selectively enable tracepoints of interest (much more useful than our > > all-or-nothing tracing). To get this type of capability, would I need > > to implement an entry and exit tracepoint for each function or is > > there a better approach? Any other best practices people would be > > willing to share? TIA. > > Hi, > > For now you'd have to create a custom probe for each function entry and > exit. > > There's a feature on the wishlist to use GCC hooks to automatically > generate those probes [1]. The end result would be the same, but it > would be much less tedious to do the instrumentation part. A Clang > plugin was also mentioned previously [2], but I don't think anybody has > tried it yet. Looking at how the Linux kernel implements function entry and exit tracing is relevant here: - kretprobes: using breakpoints, and boosted breakpoints. - function tracer: based on gcc mcount instrumentation, replaced at build time and runtime by nops/function call. Ideally at some point, we might want to reimplement those in user-space as a LTTng-UST library. Best regards, Mathieu > > > [1] https://bugs.lttng.org/issues/39 > [2] http://lists.lttng.org/pipermail/lttng-dev/2012-April/017787.html > > > Hope this helps, > > -- > Alexandre Montplaisir > DORSAL lab, > ?cole Polytechnique de Montr?al > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From Paul_Woegerer at mentor.com Mon May 7 03:56:35 2012 From: Paul_Woegerer at mentor.com (Woegerer, Paul) Date: Mon, 07 May 2012 09:56:35 +0200 Subject: [lttng-dev] lttng enable-channel options In-Reply-To: <4F96706F.1020803@mentor.com> References: <4F96706F.1020803@mentor.com> Message-ID: <4FA78033.9030106@mentor.com> Sorry that?s an old message I sent before I subscribed the lttng-dev mailing list. Please ignore. -- Paul On 04/24/2012 11:20 AM, Woegerer, Paul wrote: > Is there some way to make the userspace application block if the > buffer is full ? > > I'm thinking about something like: > > lttng enable-channel myblockingchannel --block > > I know I can increase the subbuf-size but sometimes this is not an > option (embedded targets with less RAM). > > --block would be a fine complement for the already existing options > --discard and --overwrite. > What do you think ? > > Thanks, > Paul > -- Paul Woegerer | SW Development Engineer Mentor Embedded(tm) | Prinz Eugen Stra?e 72/2/4, Vienna, 1040 Austria P 43.1.535991320 Nucleus? | Linux? | Android(tm) | Services | UI | Multi-OS Android is a trademark of Google Inc. Use of this trademark is subject to Google Permissions. Linux is the registered trademark of Linus Torvalds in the U.S. and other countries. From Fredrik_Oestman at mentor.com Mon May 7 04:08:53 2012 From: Fredrik_Oestman at mentor.com (Oestman, Fredrik) Date: Mon, 7 May 2012 08:08:53 +0000 Subject: [lttng-dev] tracing program flow In-Reply-To: References: Message-ID: <524C960C5DFC794E82BE548D825F05CF2833E250@EU-MBX-01.mgc.mentorg.com> Chuch Tuffli wrote: > I'm investigating the feasibility of replacing some home grown tracing > code with LTTng and am looking for advice from others who have used > LTTng to trace program flow (i.e. trace function entry and exit > points). One of the strengths of LTTng seems to be the ability to > selectively enable tracepoints of interest (much more useful than our > all-or-nothing tracing). To get this type of capability, would I need > to implement an entry and exit tracepoint for each function or is > there a better approach? Any other best practices people would be > willing to share? A customer had a similar problem. We used two different ways to instrument the code: full instrumentation using the GCC option -finstrument-functions and targeted instrumentation of a class of functions. Our experience: - Full instrumentation is very intrusive and inferior to sampling methods if you are only looking to profile the code - Full instrumentation is sometimes useful for verifying exact call sequences - Full instrumentation can also be used to find out which function is active at a specific point in time, when some other event occurs (trace correlation) - Using targeted instrumentation, we constructed a pulse train from the trace events, which could then be used to measure function execution times. This way, issues in the application could be found and then resolved. This was a real-time embedded system. We use our commercial trace display and analysis tool for analysis. I don't know what options there are in this respect. Cheers, Fredrik ?stman From Fredrik_Oestman at mentor.com Mon May 7 04:15:27 2012 From: Fredrik_Oestman at mentor.com (Oestman, Fredrik) Date: Mon, 7 May 2012 08:15:27 +0000 Subject: [lttng-dev] tracing program flow In-Reply-To: <4FA6A496.9070101@polymtl.ca> References: <4FA6A496.9070101@polymtl.ca> Message-ID: <524C960C5DFC794E82BE548D825F05CF2833E266@EU-MBX-01.mgc.mentorg.com> Alexandre Montplaisir wrote: > There's a feature on the wishlist to use GCC hooks to automatically > generate those probes [1]. The end result would be the same, but it > would be much less tedious to do the instrumentation part. A Clang > plugin was also mentioned previously [2], but I don't think anybody has > tried it yet. Providing functions to GCC containing LTTng tracepoints isn't that much of a problem. We found it useful to add the thread ID to the trace data provided by GCC so we could keep the threads apart. As far as I know, this has to be made in application code at the moment, since LTTng can add context trace information only to kernel events at the moment. We also have used the dynamic linker to add LTTng tracepoints to memory allocation and de-allocation functions as well as to the functions in the ptreads library. It can be done, but overhead is significant. Any road-map information for the ability of LTTng to add context information to user-space events? Cheers, Fredrik ?stman From laijs at cn.fujitsu.com Mon May 7 05:53:37 2012 From: laijs at cn.fujitsu.com (Lai Jiangshan) Date: Mon, 07 May 2012 17:53:37 +0800 Subject: [lttng-dev] [PATCH] rculfhash: use do {} while (0) for dbg_printf() Message-ID: <4FA79BA1.5050800@cn.fujitsu.com> found by clang(make CC=clang). avoid empty statement. ------------------------- if (condition) dbg_printf() /* forget ";", but compiler say nothing if dbg_printf() is empty */ statement; ------------------------- also add printf format check. (we can use gcc extention "__printf(1, 2)" to declare a dummy inline function to do the check, but I use "printf()" directly here) Signed-off-by: Lai Jiangshan --- diff --git a/rculfhash-internal.h b/rculfhash-internal.h index 284125a..d7cec95 100644 --- a/rculfhash-internal.h +++ b/rculfhash-internal.h @@ -25,11 +25,17 @@ */ #include +#include #ifdef DEBUG #define dbg_printf(fmt, args...) printf("[debug rculfhash] " fmt, ## args) #else -#define dbg_printf(fmt, args...) +#define dbg_printf(fmt, args...) \ +do { \ + /* do nothing but check printf format */ \ + if (0) \ + printf("[debug rculfhash] " fmt, ## args); \ +} while (0) #endif #if (CAA_BITS_PER_LONG == 32) From mathieu.desnoyers at efficios.com Mon May 7 10:53:22 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 7 May 2012 10:53:22 -0400 Subject: [lttng-dev] tracing program flow In-Reply-To: <524C960C5DFC794E82BE548D825F05CF2833E266@EU-MBX-01.mgc.mentorg.com> References: <4FA6A496.9070101@polymtl.ca> <524C960C5DFC794E82BE548D825F05CF2833E266@EU-MBX-01.mgc.mentorg.com> Message-ID: <20120507145322.GA30736@Krystal> * Oestman, Fredrik (Fredrik_Oestman at mentor.com) wrote: > Alexandre Montplaisir wrote: > > There's a feature on the wishlist to use GCC hooks to automatically > > generate those probes [1]. The end result would be the same, but it > > would be much less tedious to do the instrumentation part. A Clang > > plugin was also mentioned previously [2], but I don't think anybody has > > tried it yet. > > > Providing functions to GCC containing LTTng tracepoints isn't that > much of a problem. We found it useful to add the thread ID to the > trace data provided by GCC so we could keep the threads apart. As far > as I know, this has to be made in application code at the moment, > since LTTng can add context trace information only to kernel events at > the moment. The "vtid" context is also available in user-space traces. The list of user-space contexts currently available: vtid, vpid, pthread_id, procname. > > We also have used the dynamic linker to add LTTng tracepoints to > memory allocation and de-allocation functions as well as to the > functions in the ptreads library. It can be done, but overhead is > significant. > > Any road-map information for the ability of LTTng to add context > information to user-space events? Already available :) Thanks, Mathieu > > > Cheers, > > Fredrik ?stman > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon May 7 11:09:00 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 7 May 2012 11:09:00 -0400 Subject: [lttng-dev] [PATCH] rculfhash: use do {} while (0) for dbg_printf() In-Reply-To: <4FA79BA1.5050800@cn.fujitsu.com> References: <4FA79BA1.5050800@cn.fujitsu.com> Message-ID: <20120507150859.GB30924@Krystal> * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: > found by clang(make CC=clang). > > avoid empty statement. > ------------------------- > if (condition) > dbg_printf() /* forget ";", but compiler say nothing if dbg_printf() is empty */ > statement; merged, thanks! Mathieu > ------------------------- > > also add printf format check. > (we can use gcc extention "__printf(1, 2)" to declare a dummy inline function > to do the check, but I use "printf()" directly here) > > Signed-off-by: Lai Jiangshan > --- > diff --git a/rculfhash-internal.h b/rculfhash-internal.h > index 284125a..d7cec95 100644 > --- a/rculfhash-internal.h > +++ b/rculfhash-internal.h > @@ -25,11 +25,17 @@ > */ > > #include > +#include > > #ifdef DEBUG > #define dbg_printf(fmt, args...) printf("[debug rculfhash] " fmt, ## args) > #else > -#define dbg_printf(fmt, args...) > +#define dbg_printf(fmt, args...) \ > +do { \ > + /* do nothing but check printf format */ \ > + if (0) \ > + printf("[debug rculfhash] " fmt, ## args); \ > +} while (0) > #endif > > #if (CAA_BITS_PER_LONG == 32) > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon May 7 11:45:30 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 7 May 2012 11:45:30 -0400 Subject: [lttng-dev] [RFC PATCH] rculfhash: race between replace and del operations Message-ID: <20120507154530.GA31133@Krystal> Hi, I just found a race in the replace vs del operations in rculfhash. This would be introduced by commit: commit db00ccc36e7fb04ce8044fb1be7964acd1de6ae0 Author: Mathieu Desnoyers Date: Mon Dec 19 16:45:51 2011 -0500 rculfhash: Relax atomicity guarantees required by removal operation The atomicity guarantees for the removal operation do not need to be as strict as a cmpxchg. Use a uatomic_set followed by a xchg on a newly introduced "REMOVAL_OWNER_FLAG" to perform removal. Here is the race: Initially in hash table: A T0 T1 replace A by B del A read A->next -> check REMOVED flag, not set yet. read A->next -> check REMOVED flag, not set yet. cmpxchg A->next to set REMOVED flag -> cmpxchg succeeds uatomic_or to set REMOVED flag uatomic_xchg to atomically set the REMOVAL_OWNER flag -> first to set the flag. Replace returns node -> free(A) Del success -> free(A) With this race, we have a double-free. The problem with the replace code is that it does not set the "REMOVAL_OWNER" flag. Here is the fix I propose for this bug: diff --git a/rculfhash.c b/rculfhash.c index b26a690..e9cf062 100644 --- a/rculfhash.c +++ b/rculfhash.c @@ -735,12 +735,6 @@ int is_removed(struct cds_lfht_node *node) } static -struct cds_lfht_node *flag_removed(struct cds_lfht_node *node) -{ - return (struct cds_lfht_node *) (((unsigned long) node) | REMOVED_FLAG); -} - -static int is_bucket(struct cds_lfht_node *node) { return ((unsigned long) node) & BUCKET_FLAG; @@ -765,6 +759,12 @@ struct cds_lfht_node *flag_removal_owner(struct cds_lfht_node *node) } static +struct cds_lfht_node *flag_removed_or_removal_owner(struct cds_lfht_node *node) +{ + return (struct cds_lfht_node *) (((unsigned long) node) | REMOVED_FLAG | REMOVAL_OWNER_FLAG); +} + +static struct cds_lfht_node *get_end(void) { return (struct cds_lfht_node *) END_VALUE; @@ -894,6 +894,12 @@ int _cds_lfht_replace(struct cds_lfht *ht, unsigned long size, } assert(old_next == clear_flag(old_next)); assert(new_node != old_next); + /* + * REMOVAL_OWNER flag is _NEVER_ set before the REMOVED + * flag. It is either set atomically at the same time + * (replace) or after (del). + */ + assert(!is_removal_owner(old_next)); new_node->next = old_next; /* * Here is the whole trick for lock-free replace: we add @@ -906,10 +912,12 @@ int _cds_lfht_replace(struct cds_lfht *ht, unsigned long size, * the old node, but will not see the new one. * This is a replacement of a node with another node * that has the same value: we are therefore not - * removing a value from the hash table. + * removing a value from the hash table. We set both the + * REMOVED and REMOVAL_OWNER flags atomically so we own + * the node after successful cmpxchg. */ ret_next = uatomic_cmpxchg(&old_node->next, - old_next, flag_removed(new_node)); + old_next, flag_removed_or_removal_owner(new_node)); if (ret_next == old_next) break; /* We performed the replacement. */ old_next = ret_next; Thoughts ? Thanks, Mathieu -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon May 7 11:48:18 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 7 May 2012 11:48:18 -0400 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120506155640.GJ2470@linux.vnet.ibm.com> References: <20120501210206.GA31952@Krystal> <20120501235007.GS2441@linux.vnet.ibm.com> <20120502041639.GA7857@Krystal> <20120502155430.GF2450@linux.vnet.ibm.com> <20120503171330.GA12234@Krystal> <20120503174706.GI2592@linux.vnet.ibm.com> <20120504165312.GA15996@Krystal> <20120504173613.GI2411@linux.vnet.ibm.com> <20120505182212.GA23461@Krystal> <20120506155640.GJ2470@linux.vnet.ibm.com> Message-ID: <20120507154818.GA31544@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > On Sat, May 05, 2012 at 02:22:12PM -0400, Mathieu Desnoyers wrote: > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: [...] > > > Just to make sure I understand -- the reason that the "del" functions > > > say "no memory barrier" instead of "acts like rcu_dereference()" is > > > that the "del" functions don't return anything. > > > > Hrm, you bring an interesting point. I think we should change the two > > "rcu_dereference()" in _cds_lfht_del for "CMM_LOAD_SHARED()". The > > difference between the two is that CMM_LOAD_SHARED() does not imply a > > read barrier between the read and following uses of the data pointed to > > by the pointer read. > > > > Same thing for "cds_lfht_is_node_deleted": the rcu_dereference() should > > be changed for a CMM_LOAD_SHARED(), because we never use the loaded > > pointer as a pointer to other data. There are a few other locations > > where the pointer is only used for its flags. > > > > Here is what I propose: > > > > diff --git a/rculfhash.c b/rculfhash.c > > index b9f795f..6e27436 100644 > > --- a/rculfhash.c > > +++ b/rculfhash.c > > @@ -923,7 +923,7 @@ int _cds_lfht_replace(struct cds_lfht *ht, unsigned long size, > > bucket = lookup_bucket(ht, size, bit_reverse_ulong(old_node->reverse_hash)); > > _cds_lfht_gc_bucket(bucket, new_node); > > > > - assert(is_removed(rcu_dereference(old_node->next))); > > + assert(is_removed(CMM_LOAD_SHARED(old_node->next))); > > This is good. > > > return 0; > > } > > > > @@ -1061,7 +1061,7 @@ int _cds_lfht_del(struct cds_lfht *ht, unsigned long size, > > * logical removal flag). Return -ENOENT if the node had > > * previously been removed. > > */ > > - next = rcu_dereference(node->next); > > + next = CMM_LOAD_SHARED(node->next); > > if (caa_unlikely(is_removed(next))) > > return -ENOENT; > > assert(!is_bucket(next)); > > As long as "next" is not dereferenced anywhere, this is good. Which > appears to be the case. > > > @@ -1082,7 +1082,7 @@ int _cds_lfht_del(struct cds_lfht *ht, unsigned long size, > > bucket = lookup_bucket(ht, size, bit_reverse_ulong(node->reverse_hash)); > > _cds_lfht_gc_bucket(bucket, node); > > > > - assert(is_removed(rcu_dereference(node->next))); > > + assert(is_removed(CMM_LOAD_SHARED(node->next))); > > This one is fine as well. > > > /* > > * Last phase: atomically exchange node->next with a version > > * having "REMOVAL_OWNER_FLAG" set. If the returned node->next > > @@ -1510,7 +1510,7 @@ void cds_lfht_lookup(struct cds_lfht *ht, unsigned long hash, > > } > > node = clear_flag(next); > > } > > - assert(!node || !is_bucket(rcu_dereference(node->next))); > > + assert(!node || !is_bucket(CMM_LOAD_SHARED(node->next))); > > As is this one. > > > iter->node = node; > > iter->next = next; > > } > > @@ -1543,7 +1543,7 @@ void cds_lfht_next_duplicate(struct cds_lfht *ht, cds_lfht_match_fct match, > > } > > node = clear_flag(next); > > } > > - assert(!node || !is_bucket(rcu_dereference(node->next))); > > + assert(!node || !is_bucket(CMM_LOAD_SHARED(node->next))); > > Same here. > > > iter->node = node; > > iter->next = next; > > } > > @@ -1565,7 +1565,7 @@ void cds_lfht_next(struct cds_lfht *ht, struct cds_lfht_iter *iter) > > } > > node = clear_flag(next); > > } > > - assert(!node || !is_bucket(rcu_dereference(node->next))); > > + assert(!node || !is_bucket(CMM_LOAD_SHARED(node->next))); > > And here. > > > iter->node = node; > > iter->next = next; > > } > > @@ -1668,7 +1668,7 @@ int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node) > > > > int cds_lfht_is_node_deleted(struct cds_lfht_node *node) > > { > > - return is_removed(rcu_dereference(node->next)); > > + return is_removed(CMM_LOAD_SHARED(node->next)); > > And also here. > > > } > > > > static > > > > If it's ok for you, I will first commit this change, and then commit the > > memory barrier documentation with your reviewed-by. > > Looks good! OK, this change is committed as: commit a85eff522c253434a9c2b53d6c3a702842fb1d5d Author: Mathieu Desnoyers Date: Mon May 7 11:18:14 2012 -0400 rculfhash: replace unneeded rcu_dereference by CMM_LOAD_SHARED The difference between the two is that CMM_LOAD_SHARED() does not imply a read barrier between the read and following uses of the data pointed to by the pointer read. All sites that only use the pointer load for its bits (never dereference) don't need the read barrier implied by rcu_dereference. Reviewed-by: "Paul E. McKenney" Signed-off-by: Mathieu Desnoyers Thanks, Mathieu -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon May 7 12:10:55 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 7 May 2012 12:10:55 -0400 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120504173613.GI2411@linux.vnet.ibm.com> References: <20120501174136.GA26609@Krystal> <20120501194713.GL2441@linux.vnet.ibm.com> <20120501210206.GA31952@Krystal> <20120501235007.GS2441@linux.vnet.ibm.com> <20120502041639.GA7857@Krystal> <20120502155430.GF2450@linux.vnet.ibm.com> <20120503171330.GA12234@Krystal> <20120503174706.GI2592@linux.vnet.ibm.com> <20120504165312.GA15996@Krystal> <20120504173613.GI2411@linux.vnet.ibm.com> Message-ID: <20120507161055.GA31702@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > On Fri, May 04, 2012 at 12:53:12PM -0400, Mathieu Desnoyers wrote: [...] > Just to make sure I understand -- the reason that the "del" functions > say "no memory barrier" instead of "acts like rcu_dereference()" is > that the "del" functions don't return anything. > [...] > > @@ -391,6 +413,7 @@ int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node); > > * function. > > * Call with rcu_read_lock held. > > * Threads calling this API need to be registered RCU read-side threads. > > + * This function does not issue any memory barrier. > > */ One more question about the "del" memory ordering semantic. Following commit commit db00ccc36e7fb04ce8044fb1be7964acd1de6ae0 Author: Mathieu Desnoyers Date: Mon Dec 19 16:45:51 2011 -0500 rculfhash: Relax atomicity guarantees required by removal operation The atomicity guarantees for the removal operation do not need to be as strict as a cmpxchg. Use a uatomic_set followed by a xchg on a newly introduced "REMOVAL_OWNER_FLAG" to perform removal. Signed-off-by: Mathieu Desnoyers The "del" operation is performed in two steps: 1 - uatomic_or(), which sets the "REMOVED" flag (the actual tombstone) unconditionally into the node's next pointer. 2 - uatomic_xchg(), which atomically exchanges the old pointer with its current value (read) or'd with the REMOVAL_OWNER flag. The trick is that if the xchg returns a pointer with the REMOVAL_OWNER flag set, it means we are not the first thread to set this flag, so we should not free the node. However, if xchg returns a node without the REMOVAL_OWNER flag set, we are indeed the first to set it, so we should call free. Now regarding memory ordering semantics, should we consider the atomic action of "del" to apply when the "or" is called, or when the "xchg" is called ? Or should we simply document that the "del" effect on the node happens in two separate steps ? The way I see it, the actual effect of removal, as seen from RCU read traversal and lookup point of view, is observed as soon as the "REMOVED" tombstone is set, so I would think that the atomic publication of the removal is performed by the "or". However, we ensure full memory barriers around "xchg", but not usually around "or". Therefore, the current implementation does not issue a memory barrier before the "or", so we should either change our planned memory barrier documentation, or the implementation, to match. This would probably require creation of a cmm_smp_mb__before_uatomic_or(), so x86 does not end up issuing a useless memory barrer. Thoughts ? Thanks, Mathieu -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From jim.dumont at ericsson.com Mon May 7 14:05:42 2012 From: jim.dumont at ericsson.com (Jim Dumont) Date: Mon, 7 May 2012 14:05:42 -0400 Subject: [lttng-dev] RFC (v2) Streaming and reading traces over the network In-Reply-To: References: Message-ID: Couple of comments: If I understand correctly: Overload - nothing new will be implemented on the sender node (A), lttng-ust and lttng kerner traces will continue their existing buffering as usual. However, you will be introducing a receiving node (B) consumer which will have some overload support - to be added to RFC. Question - Do the A's and B's have one-to-one relationship? For every A there is a corresponding B, which means there are multiple B's on a single controller node - OR - does a single B handle multiple A's? Bandwidth - A's sessionD will have some bandwidth management support - e.g., max-bandwidth config param, then drop packets... Question - Per session bandwidth setting is required? This would not be the configured global setting, but something set at session creation? Thanks, /Jim -----Original Message----- From: lttng-dev-request at lists.lttng.org [mailto:lttng-dev-request at lists.lttng.org] Sent: April-20-12 13:24 To: lttng-dev at lists.lttng.org Subject: lttng-dev Digest, Vol 48, Issue 26 Send lttng-dev mailing list submissions to lttng-dev at lists.lttng.org To subscribe or unsubscribe via the World Wide Web, visit http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev or, via email, send a message with subject or body 'help' to lttng-dev-request at lists.lttng.org You can reach the person managing the list at lttng-dev-owner at lists.lttng.org When replying, please edit your Subject line so it is more specific than "Re: Contents of lttng-dev digest..." Today's Topics: 1. Re: RFC (v2) Streaming and reading traces over the network (Mathieu Desnoyers) ---------------------------------------------------------------------- Message: 1 Date: Fri, 20 Apr 2012 13:23:36 -0400 From: Mathieu Desnoyers To: Jim Dumont Cc: "lttng-dev at lists.lttng.org" Subject: Re: [lttng-dev] RFC (v2) Streaming and reading traces over the network Message-ID: <20120420172336.GA11277 at Krystal> Content-Type: text/plain; charset=us-ascii * Jim Dumont (jim.dumont at ericsson.com) wrote: [...] > -----Original Message----- > From: Jim Dumont > Sent: April-19-12 17:16 > To: 'lttng-dev at lists.lttng.org' > Subject: RE: lttng-dev Digest, Vol 48, Issue 22 > > Hey there, > > Was wondering if you are considering any specific > support/implementation with respect to overload handling, buffering, > bandwidth management...? > > I'm thinking this is of particular interest when streaming traces over > a network. > For buffering on the sender node (A), the tracer buffers (lttng-ust, lttng kernel tracer) are those doing the buffering. Given that in this initial phase, we don't plan on implementing proxy support, thinking about buffer size on the proxy consumer seems to be a bit too far ahead. For node B (the receiver consumer), it would be important to put maximum limits on how much data we keep in local buffers before we start dropping incoming data, so this should be added to the RFC. This would provide overload handling on the receiver node. The other item is bandwidth management. I think it should be failrly straightforward to have a configuration option for the sender node's sessiond that adds a "--max-bandwidth" limit or something like that, both globally and per-session. The sender would be responsible for keeping track of how much bandwidth it's using, and would drop trace data packets and their associated sync data if it notices that it's about to go beyond its cap. Thoughts ? Thanks, Mathieu > BR, > > /Jim. > > -----Original Message----- > From: lttng-dev-request at lists.lttng.org [mailto:lttng-dev-request at lists.lttng.org] > Sent: April-18-12 16:31 > To: lttng-dev at lists.lttng.org > Subject: lttng-dev Digest, Vol 48, Issue 22 > > Send lttng-dev mailing list submissions to > lttng-dev at lists.lttng.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > or, via email, send a message with subject or body 'help' to > lttng-dev-request at lists.lttng.org > > You can reach the person managing the list at > lttng-dev-owner at lists.lttng.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of lttng-dev digest..." > > > Today's Topics: > > 1. RFC (v2) Streaming and reading traces over the network > (Julien Desfossez) > 2. [RFC] Session Daemon Network Session (David Goulet) > 3. Re: Babeltrace Buffer Warning (Mathieu Desnoyers) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Wed, 18 Apr 2012 15:00:18 -0400 > From: Julien Desfossez > To: "lttng-dev at lists.lttng.org" > Cc: Mathieu Desnoyers , > dgoulet at efficios.com > Subject: [lttng-dev] RFC (v2) Streaming and reading traces over the > network > Message-ID: <4F8F0F42.9030605 at efficios.com> > Content-Type: text/plain; charset=ISO-8859-1 > > RFC - Streaming And Reading Traces Over The Network > > Author: Julien Desfossez > > Contributors: > * Mathieu Desnoyers > * David Goulet > > Version: > - v0.1: 26/03/2012 > * Initial proposal > - v0.2: 17/04/2012 > * First revision > > > Introduction > ------------ > > This RFC proposes a way for the LTTng kernel and user-space tracer to stream > traces over the network, and for a viewer to read traces while they are > being > generated. > > > Changelog > --------- > > The first version of this RFC was posted on march 26th 2012 on lttng-dev > mailing list, this version is a rewrite and adds more details about the > inner > working of the streaming protocol and clarifies the synchronization > operations. > > > Prerequisites/assumptions > ------------------------- > > - work over TCP and UDP > - play nicely with NAT > - trace data and control data are exchanged on different connections > and possibly on different protocols > - control data is mandatory and must use a reliable connection (TCP) > - trace packets (as defined in CTF) may arrive in any order when using > connection-less protocol. > > > Name convention > --------------- > > - A : the traced machine streaming trace data over the network to B > - B : the remote consumer, receiving data from A > - C : the viewer on B displaying the streamed trace to the user > - trace data : the multiplexed stream of trace streams > > > Creating a network session > -------------------------- > > The first step when creating a trace to stream over the network is to > create a > tracing session on A that contains all the information to reach B. The inner > details of this part are covered in a separate RFC from David Goulet, > lets just > say that it includes the IP/name of the receiving machine (B) as well as the > control and data ports/protocols. > > Once the session is started, A sends data to B over the control and data > paths. > The data path contains only trace data, the control path is streamed over a > reliable network protocol and contains the session information, indexes and > synchronization informations. > > When a network trace starts, A sends each of its streams to B over the > control path. The information associated with each stream is A's > hostname, the session name, each channel name, and each stream id. B > responds with a stream handle identifier, unique across B, for each > stream. > > B creates the folder hierarchy and acknowledges when it is ready, the trace > starts on A and the streaming begins. > > Upon CPU hotplug, which dynamically adds streams to A, a control message > is exchanged with B to send the new stream, along with hostname, > session name, stream id. B responds with a unique stream handle > identifier. > > > Trace packets encapsulation > --------------------------- > > The data network stream received by B contains all the trace streams > multiplexed. In order to write the data into the appropriate trace files and > ensure the data is written in order, a network header must be added by the > tracer. This header located in the CTF packet header contains the following > unsigned 64 bits identifiers : > > - #stream_handle : the stream handle unique identifier > - #seq : a sequence number relative to each stream > - #prev_seq : the previous sequence number to determine if a packet was > lost by > the network or the tracer > - #circuit_id : unique routing ID across all proxy, A, and B (unused for > now, set to 0). > > Apart from #seq which is generated by the tracer, the other identifiers are > inserted by the consumer on A before sending the packet. In order to do so > without having to copy the data, when the tracer generates a trace > packet, it > leaves an empty space at the position where those fields are located and > provides API/ABI calls to allow the consumer to find the offsets and > fill them > with the appropriate value. Then the packet is directly spliced over the > network. > > Note that the API/ABI calls to get the positions where to write the > stream id and prev_seq value are provided by the tracers and do _not_ > involve any interaction with a CTF reader. > > Note that circuit_id is present for future use in the case of routing > across proxy consumers. > > > Synchronization > --------------- > > In order to allow the trace viewer to display the traces without the risk of > receiving information belonging to a timestamp prior to the current > information (could be caused by low traffic streams), we have to define > a buffer flush frequency and a synchronization algorithm. > > In order to avoid sending empty trace data for inactive streams, the > consumer > on A is in charge of the synchronization information. At a predefined > frequency, the consumer must trigger a buffer flush, and for each stream it > must save the current sequence number. The trace packets are then sent > over the > network. During that time, the consumer generates a synchronization > packet to > send on the control path. This packet contains the sequence number for each > stream sampled before their last buffer flush. When B receives this packet, > it knows that it is safe to read the trace up to, and including, each > sequence number. If a stream is inactive and did not generate any trace > data since the last buffer flush, the last known sequence number is sent. > > > Receiving the trace data > ------------------------ > > On B, when trace packets arrive, they must be saved on disk. But since the > medium may not be considered reliable (UDP for example), packets may be > lost or > arrive in a different order. The trace data must be written in order on > disk. > When B receives a packet, it reads the stream handle (at fixed position > in the > packet) to determine in which trace file to write. Then, looking at the > sequence and previous sequence number, it can determine whether it must > queue > the packet (to wait for a previous packet to arrive) or if it can write > it to > disk. The previous packet ID (#prev_seq) is a way to detect if data has been > discarded by the tracer or by the network transport. When packets are not > received in consecutive order, B must assume that the missing packet(s) may > arrive later and stop writing trace data for this trace file until the > gap is > closed. UDP packets can be lost forever, so a threshold (number of packets > queued or timeout) must be defined to avoid waiting forever. When this > condition is reached, B can either discard the missing packet or ask for a > retransmission (if supported on A). > > > > ------------------------------ > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > End of lttng-dev Digest, Vol 48, Issue 22 > ***************************************** > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com ------------------------------ _______________________________________________ lttng-dev mailing list lttng-dev at lists.lttng.org http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev End of lttng-dev Digest, Vol 48, Issue 26 ***************************************** From dgoulet at efficios.com Mon May 7 15:17:59 2012 From: dgoulet at efficios.com (David Goulet) Date: Mon, 07 May 2012 15:17:59 -0400 Subject: [lttng-dev] RFC - LTTng Network Session and Snapshot v0.2 Message-ID: <4FA81FE7.10807@efficios.com> An embedded and charset-unspecified text was scrubbed... Name: sessiond-network-session.txt URL: From yannick.brosseau at polymtl.ca Mon May 7 15:18:28 2012 From: yannick.brosseau at polymtl.ca (Yannick Brosseau) Date: Mon, 07 May 2012 15:18:28 -0400 Subject: [lttng-dev] Lttng support for RT-Patched Linux Kernel 2.6.33 In-Reply-To: <20120505161009.GA20681@Krystal> References: <47D610AD9C485E458630BA38C324D3B60113F9EC31CD@EXGMBX01.sasken.com> <-415305793772962384@unknownmsgid> <20120505161009.GA20681@Krystal> Message-ID: <4FA82004.6080301@polymtl.ca> On 2012-05-05 12:10, Mathieu Desnoyers wrote: > * Rapha?l Beamonte (raphael.beamonte at polymtl.ca) wrote: >> Hi Pavan, >> >> Hi , >> >> >> >> I want to use LTTng on ARM processor running *Linux 2.6.33 kernel with >> real-time patches, **My quires are** * >> >> whether there?s an LTTng port which is compatible with an RT patched >> Kernel, If not what?s required to make it RT Patch compatible. Please >> kindly help me on this. >> >> >> >> Thanks In Advance, >> >> Pavan >> >> >> LTTng is already working on Linux-RT kernels. You don't need to do anything >> more than installing LTTng ! > However, LTTng 2.0 supports only kernels 2.6.38 and more recent at this > point. There are a couple of upstream commits you might need to backport > to get it to work with 2.6.33. > > Yannick: I think you have those patches somewhere, can we publish them > on the lttng.org website. If you can just send the tarball bundle in > reply to this email, we'll take it from there. Those patches do not work with the final version of LTTng 2.0. I started working on them, but now I need to do modifications into lttng-modules. Yannick From mathieu.desnoyers at efficios.com Mon May 7 15:20:44 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 7 May 2012 15:20:44 -0400 Subject: [lttng-dev] Lttng support for RT-Patched Linux Kernel 2.6.33 In-Reply-To: <4FA82004.6080301@polymtl.ca> References: <47D610AD9C485E458630BA38C324D3B60113F9EC31CD@EXGMBX01.sasken.com> <-415305793772962384@unknownmsgid> <20120505161009.GA20681@Krystal> <4FA82004.6080301@polymtl.ca> Message-ID: <20120507192044.GB4876@Krystal> * Yannick Brosseau (yannick.brosseau at polymtl.ca) wrote: > On 2012-05-05 12:10, Mathieu Desnoyers wrote: > > * Rapha?l Beamonte (raphael.beamonte at polymtl.ca) wrote: > >> Hi Pavan, > >> > >> Hi , > >> > >> > >> > >> I want to use LTTng on ARM processor running *Linux 2.6.33 kernel with > >> real-time patches, **My quires are** * > >> > >> whether there?s an LTTng port which is compatible with an RT patched > >> Kernel, If not what?s required to make it RT Patch compatible. Please > >> kindly help me on this. > >> > >> > >> > >> Thanks In Advance, > >> > >> Pavan > >> > >> > >> LTTng is already working on Linux-RT kernels. You don't need to do anything > >> more than installing LTTng ! > > However, LTTng 2.0 supports only kernels 2.6.38 and more recent at this > > point. There are a couple of upstream commits you might need to backport > > to get it to work with 2.6.33. > > > > Yannick: I think you have those patches somewhere, can we publish them > > on the lttng.org website. If you can just send the tarball bundle in > > reply to this email, we'll take it from there. > Those patches do not work with the final version of LTTng 2.0. I started > working on them, but now I need to do modifications into lttng-modules. Please post them as RFC, commenting that they do not fully work at the moment, so other people can work on it. Thanks, Mathieu -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon May 7 19:04:19 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 7 May 2012 19:04:19 -0400 Subject: [lttng-dev] [RFC PATCH] rculfhash: race between replace and del operations In-Reply-To: <20120507154530.GA31133@Krystal> References: <20120507154530.GA31133@Krystal> Message-ID: <20120507230419.GA8883@Krystal> * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > Hi, > > I just found a race in the replace vs del operations in rculfhash. This > would be introduced by commit: Just to show that I am not making this up, I came up with a test-case to reproduce it: test_urcu_hash 0 2 20 -A -s -M 1 -N 1 -O 1 (2 threads, doing replace/del, with a hash table that has only a single key for all values). After just a couple of seconds, either the program hangs, or, more often, I get: *** glibc detected *** /media/truecrypt1/compudj/doc/userspace-rcu/tests/.libs/test_urcu_hash: malloc(): memory corruption (fast): 0x00007ffff3a29e25 *** Program received signal SIGSEGV, Segmentation fault. With my fix below, the problem disappears. I'll push the fix into the master branch right away. Thanks, Mathieu > > commit db00ccc36e7fb04ce8044fb1be7964acd1de6ae0 > Author: Mathieu Desnoyers > Date: Mon Dec 19 16:45:51 2011 -0500 > > rculfhash: Relax atomicity guarantees required by removal operation > > The atomicity guarantees for the removal operation do not need to be as > strict as a cmpxchg. Use a uatomic_set followed by a xchg on a newly > introduced "REMOVAL_OWNER_FLAG" to perform removal. > > Here is the race: > > Initially in hash table: A > > T0 T1 > replace A by B > del A > read A->next > -> check REMOVED flag, not set yet. > read A->next > -> check REMOVED flag, not set yet. > cmpxchg A->next to set REMOVED flag > -> cmpxchg succeeds > uatomic_or to set REMOVED flag > uatomic_xchg to atomically set the REMOVAL_OWNER flag > -> first to set the flag. > Replace returns node -> free(A) Del success -> free(A) > > With this race, we have a double-free. > > The problem with the replace code is that it does not set the > "REMOVAL_OWNER" flag. Here is the fix I propose for this bug: > > diff --git a/rculfhash.c b/rculfhash.c > index b26a690..e9cf062 100644 > --- a/rculfhash.c > +++ b/rculfhash.c > @@ -735,12 +735,6 @@ int is_removed(struct cds_lfht_node *node) > } > > static > -struct cds_lfht_node *flag_removed(struct cds_lfht_node *node) > -{ > - return (struct cds_lfht_node *) (((unsigned long) node) | REMOVED_FLAG); > -} > - > -static > int is_bucket(struct cds_lfht_node *node) > { > return ((unsigned long) node) & BUCKET_FLAG; > @@ -765,6 +759,12 @@ struct cds_lfht_node *flag_removal_owner(struct cds_lfht_node *node) > } > > static > +struct cds_lfht_node *flag_removed_or_removal_owner(struct cds_lfht_node *node) > +{ > + return (struct cds_lfht_node *) (((unsigned long) node) | REMOVED_FLAG | REMOVAL_OWNER_FLAG); > +} > + > +static > struct cds_lfht_node *get_end(void) > { > return (struct cds_lfht_node *) END_VALUE; > @@ -894,6 +894,12 @@ int _cds_lfht_replace(struct cds_lfht *ht, unsigned long size, > } > assert(old_next == clear_flag(old_next)); > assert(new_node != old_next); > + /* > + * REMOVAL_OWNER flag is _NEVER_ set before the REMOVED > + * flag. It is either set atomically at the same time > + * (replace) or after (del). > + */ > + assert(!is_removal_owner(old_next)); > new_node->next = old_next; > /* > * Here is the whole trick for lock-free replace: we add > @@ -906,10 +912,12 @@ int _cds_lfht_replace(struct cds_lfht *ht, unsigned long size, > * the old node, but will not see the new one. > * This is a replacement of a node with another node > * that has the same value: we are therefore not > - * removing a value from the hash table. > + * removing a value from the hash table. We set both the > + * REMOVED and REMOVAL_OWNER flags atomically so we own > + * the node after successful cmpxchg. > */ > ret_next = uatomic_cmpxchg(&old_node->next, > - old_next, flag_removed(new_node)); > + old_next, flag_removed_or_removal_owner(new_node)); > if (ret_next == old_next) > break; /* We performed the replacement. */ > old_next = ret_next; > > Thoughts ? > > Thanks, > > Mathieu > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From paulmck at linux.vnet.ibm.com Tue May 8 14:40:40 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Tue, 8 May 2012 11:40:40 -0700 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120507161055.GA31702@Krystal> References: <20120501194713.GL2441@linux.vnet.ibm.com> <20120501210206.GA31952@Krystal> <20120501235007.GS2441@linux.vnet.ibm.com> <20120502041639.GA7857@Krystal> <20120502155430.GF2450@linux.vnet.ibm.com> <20120503171330.GA12234@Krystal> <20120503174706.GI2592@linux.vnet.ibm.com> <20120504165312.GA15996@Krystal> <20120504173613.GI2411@linux.vnet.ibm.com> <20120507161055.GA31702@Krystal> Message-ID: <20120508184040.GU21152@linux.vnet.ibm.com> On Mon, May 07, 2012 at 12:10:55PM -0400, Mathieu Desnoyers wrote: > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > On Fri, May 04, 2012 at 12:53:12PM -0400, Mathieu Desnoyers wrote: > [...] > > Just to make sure I understand -- the reason that the "del" functions > > say "no memory barrier" instead of "acts like rcu_dereference()" is > > that the "del" functions don't return anything. > > > [...] > > > @@ -391,6 +413,7 @@ int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node); > > > * function. > > > * Call with rcu_read_lock held. > > > * Threads calling this API need to be registered RCU read-side threads. > > > + * This function does not issue any memory barrier. > > > */ > > One more question about the "del" memory ordering semantic. Following > commit > > commit db00ccc36e7fb04ce8044fb1be7964acd1de6ae0 > Author: Mathieu Desnoyers > Date: Mon Dec 19 16:45:51 2011 -0500 > > rculfhash: Relax atomicity guarantees required by removal operation > > The atomicity guarantees for the removal operation do not need to be as > strict as a cmpxchg. Use a uatomic_set followed by a xchg on a newly > introduced "REMOVAL_OWNER_FLAG" to perform removal. > > Signed-off-by: Mathieu Desnoyers > > > The "del" operation is performed in two steps: > > 1 - uatomic_or(), which sets the "REMOVED" flag (the actual tombstone) > unconditionally into the node's next pointer. > 2 - uatomic_xchg(), which atomically exchanges the old pointer with > its current value (read) or'd with the REMOVAL_OWNER flag. The trick > is that if the xchg returns a pointer with the REMOVAL_OWNER flag > set, it means we are not the first thread to set this flag, so we > should not free the node. However, if xchg returns a node without > the REMOVAL_OWNER flag set, we are indeed the first to set it, so > we should call free. > > Now regarding memory ordering semantics, should we consider the atomic > action of "del" to apply when the "or" is called, or when the "xchg" is > called ? Or should we simply document that the "del" effect on the node > happens in two separate steps ? > > The way I see it, the actual effect of removal, as seen from RCU read > traversal and lookup point of view, is observed as soon as the "REMOVED" > tombstone is set, so I would think that the atomic publication of the > removal is performed by the "or". > > However, we ensure full memory barriers around "xchg", but not usually > around "or". Therefore, the current implementation does not issue a > memory barrier before the "or", so we should either change our planned > memory barrier documentation, or the implementation, to match. This > would probably require creation of a cmm_smp_mb__before_uatomic_or(), so > x86 does not end up issuing a useless memory barrer. My kneejerk reaction is that the "or" is really doing the deletion. Readers and other updaters care about the deletion, not about which CPU is going to do the free. Or did I misunderstand how this works? Thanx, Paul > Thoughts ? > > Thanks, > > Mathieu > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > rp mailing list > rp at svcs.cs.pdx.edu > http://svcs.cs.pdx.edu/mailman/listinfo/rp > From mathieu.desnoyers at efficios.com Tue May 8 14:48:27 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 8 May 2012 14:48:27 -0400 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120508184040.GU21152@linux.vnet.ibm.com> References: <20120501210206.GA31952@Krystal> <20120501235007.GS2441@linux.vnet.ibm.com> <20120502041639.GA7857@Krystal> <20120502155430.GF2450@linux.vnet.ibm.com> <20120503171330.GA12234@Krystal> <20120503174706.GI2592@linux.vnet.ibm.com> <20120504165312.GA15996@Krystal> <20120504173613.GI2411@linux.vnet.ibm.com> <20120507161055.GA31702@Krystal> <20120508184040.GU21152@linux.vnet.ibm.com> Message-ID: <20120508184827.GD29665@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > On Mon, May 07, 2012 at 12:10:55PM -0400, Mathieu Desnoyers wrote: > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > On Fri, May 04, 2012 at 12:53:12PM -0400, Mathieu Desnoyers wrote: > > [...] > > > Just to make sure I understand -- the reason that the "del" functions > > > say "no memory barrier" instead of "acts like rcu_dereference()" is > > > that the "del" functions don't return anything. > > > > > [...] > > > > @@ -391,6 +413,7 @@ int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node); > > > > * function. > > > > * Call with rcu_read_lock held. > > > > * Threads calling this API need to be registered RCU read-side threads. > > > > + * This function does not issue any memory barrier. > > > > */ > > > > One more question about the "del" memory ordering semantic. Following > > commit > > > > commit db00ccc36e7fb04ce8044fb1be7964acd1de6ae0 > > Author: Mathieu Desnoyers > > Date: Mon Dec 19 16:45:51 2011 -0500 > > > > rculfhash: Relax atomicity guarantees required by removal operation > > > > The atomicity guarantees for the removal operation do not need to be as > > strict as a cmpxchg. Use a uatomic_set followed by a xchg on a newly > > introduced "REMOVAL_OWNER_FLAG" to perform removal. > > > > Signed-off-by: Mathieu Desnoyers > > > > > > The "del" operation is performed in two steps: > > > > 1 - uatomic_or(), which sets the "REMOVED" flag (the actual tombstone) > > unconditionally into the node's next pointer. > > 2 - uatomic_xchg(), which atomically exchanges the old pointer with > > its current value (read) or'd with the REMOVAL_OWNER flag. The trick > > is that if the xchg returns a pointer with the REMOVAL_OWNER flag > > set, it means we are not the first thread to set this flag, so we > > should not free the node. However, if xchg returns a node without > > the REMOVAL_OWNER flag set, we are indeed the first to set it, so > > we should call free. > > > > Now regarding memory ordering semantics, should we consider the atomic > > action of "del" to apply when the "or" is called, or when the "xchg" is > > called ? Or should we simply document that the "del" effect on the node > > happens in two separate steps ? > > > > The way I see it, the actual effect of removal, as seen from RCU read > > traversal and lookup point of view, is observed as soon as the "REMOVED" > > tombstone is set, so I would think that the atomic publication of the > > removal is performed by the "or". > > > > However, we ensure full memory barriers around "xchg", but not usually > > around "or". Therefore, the current implementation does not issue a > > memory barrier before the "or", so we should either change our planned > > memory barrier documentation, or the implementation, to match. This > > would probably require creation of a cmm_smp_mb__before_uatomic_or(), so > > x86 does not end up issuing a useless memory barrer. > > My kneejerk reaction is that the "or" is really doing the deletion. > Readers and other updaters care about the deletion, not about which CPU > is going to do the free. > > Or did I misunderstand how this works? You got it right, this is how I see it too. However, in order to provide a full memory barrier before the "or", we'd need to add a cmm_smp_mb() before the "or" (I don't think we want to presume that our "or" operation issues full memory barriers on all architectures). However, on x86, the "lock; or" does issue a full memory barrier. So I think we should introduce a macro that can translate into a memory barrier on architectures that need it, and to nothing on x86. Thoughts ? Thanks, Mathieu > > Thanx, Paul > > > Thoughts ? > > > > Thanks, > > > > Mathieu > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > > > _______________________________________________ > > rp mailing list > > rp at svcs.cs.pdx.edu > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From paulmck at linux.vnet.ibm.com Tue May 8 14:50:48 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Tue, 8 May 2012 11:50:48 -0700 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120508184827.GD29665@Krystal> References: <20120501235007.GS2441@linux.vnet.ibm.com> <20120502041639.GA7857@Krystal> <20120502155430.GF2450@linux.vnet.ibm.com> <20120503171330.GA12234@Krystal> <20120503174706.GI2592@linux.vnet.ibm.com> <20120504165312.GA15996@Krystal> <20120504173613.GI2411@linux.vnet.ibm.com> <20120507161055.GA31702@Krystal> <20120508184040.GU21152@linux.vnet.ibm.com> <20120508184827.GD29665@Krystal> Message-ID: <20120508185048.GW21152@linux.vnet.ibm.com> On Tue, May 08, 2012 at 02:48:27PM -0400, Mathieu Desnoyers wrote: > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > On Mon, May 07, 2012 at 12:10:55PM -0400, Mathieu Desnoyers wrote: > > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > On Fri, May 04, 2012 at 12:53:12PM -0400, Mathieu Desnoyers wrote: > > > [...] > > > > Just to make sure I understand -- the reason that the "del" functions > > > > say "no memory barrier" instead of "acts like rcu_dereference()" is > > > > that the "del" functions don't return anything. > > > > > > > [...] > > > > > @@ -391,6 +413,7 @@ int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node); > > > > > * function. > > > > > * Call with rcu_read_lock held. > > > > > * Threads calling this API need to be registered RCU read-side threads. > > > > > + * This function does not issue any memory barrier. > > > > > */ > > > > > > One more question about the "del" memory ordering semantic. Following > > > commit > > > > > > commit db00ccc36e7fb04ce8044fb1be7964acd1de6ae0 > > > Author: Mathieu Desnoyers > > > Date: Mon Dec 19 16:45:51 2011 -0500 > > > > > > rculfhash: Relax atomicity guarantees required by removal operation > > > > > > The atomicity guarantees for the removal operation do not need to be as > > > strict as a cmpxchg. Use a uatomic_set followed by a xchg on a newly > > > introduced "REMOVAL_OWNER_FLAG" to perform removal. > > > > > > Signed-off-by: Mathieu Desnoyers > > > > > > > > > The "del" operation is performed in two steps: > > > > > > 1 - uatomic_or(), which sets the "REMOVED" flag (the actual tombstone) > > > unconditionally into the node's next pointer. > > > 2 - uatomic_xchg(), which atomically exchanges the old pointer with > > > its current value (read) or'd with the REMOVAL_OWNER flag. The trick > > > is that if the xchg returns a pointer with the REMOVAL_OWNER flag > > > set, it means we are not the first thread to set this flag, so we > > > should not free the node. However, if xchg returns a node without > > > the REMOVAL_OWNER flag set, we are indeed the first to set it, so > > > we should call free. > > > > > > Now regarding memory ordering semantics, should we consider the atomic > > > action of "del" to apply when the "or" is called, or when the "xchg" is > > > called ? Or should we simply document that the "del" effect on the node > > > happens in two separate steps ? > > > > > > The way I see it, the actual effect of removal, as seen from RCU read > > > traversal and lookup point of view, is observed as soon as the "REMOVED" > > > tombstone is set, so I would think that the atomic publication of the > > > removal is performed by the "or". > > > > > > However, we ensure full memory barriers around "xchg", but not usually > > > around "or". Therefore, the current implementation does not issue a > > > memory barrier before the "or", so we should either change our planned > > > memory barrier documentation, or the implementation, to match. This > > > would probably require creation of a cmm_smp_mb__before_uatomic_or(), so > > > x86 does not end up issuing a useless memory barrer. > > > > My kneejerk reaction is that the "or" is really doing the deletion. > > Readers and other updaters care about the deletion, not about which CPU > > is going to do the free. > > > > Or did I misunderstand how this works? > > You got it right, this is how I see it too. > > However, in order to provide a full memory barrier before the "or", we'd > need to add a cmm_smp_mb() before the "or" (I don't think we want to > presume that our "or" operation issues full memory barriers on all > architectures). > > However, on x86, the "lock; or" does issue a full memory barrier. So I > think we should introduce a macro that can translate into a memory > barrier on architectures that need it, and to nothing on x86. > > Thoughts ? Makes sense to me! Thanx, Paul > Thanks, > > Mathieu > > > > > Thanx, Paul > > > > > Thoughts ? > > > > > > Thanks, > > > > > > Mathieu > > > > > > -- > > > Mathieu Desnoyers > > > Operating System Efficiency R&D Consultant > > > EfficiOS Inc. > > > http://www.efficios.com > > > > > > _______________________________________________ > > > rp mailing list > > > rp at svcs.cs.pdx.edu > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > From fahad.usman at gmail.com Wed May 9 08:20:08 2012 From: fahad.usman at gmail.com (Fahad Usman) Date: Wed, 9 May 2012 17:20:08 +0500 Subject: [lttng-dev] problem starting trace on arm target Message-ID: Hi, I am trying to use lttng-modules on an arm target, but when I try to start tracing I get some errors like PERROR: sendmsg: Bad file descriptor [in lttcomm_send_unix_sock() at sessiond-comm.c:310] PERROR: send consumer channel: Bad file descriptor [in send_kconsumer_session_streams() at main.c:636] please see pastebin (http://pastebin.com/ivnvQWa2) for complete logs I am using Linux 2.6.38 on Freescale imx6 platform. Lttng-modules 2.0.2 and lttng-tools 2.0.1 -- Fahad From dgoulet at efficios.com Wed May 9 09:08:50 2012 From: dgoulet at efficios.com (David Goulet) Date: Wed, 09 May 2012 09:08:50 -0400 Subject: [lttng-dev] problem starting trace on arm target In-Reply-To: References: Message-ID: <4FAA6C62.8000500@efficios.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi Fahad, This is error is a bit peculiar... Can you provide the full log of the session daemon like so. (term1) # lttng-sessiond -vvv (term2) the rest of the commands adding -vvv to "lttng" command line. Thanks! David On 09/05/12 08:20 AM, Fahad Usman wrote: > Hi, I am trying to use lttng-modules on an arm target, but when I try to > start tracing I get some errors like PERROR: sendmsg: Bad file descriptor > [in lttcomm_send_unix_sock() at sessiond-comm.c:310] PERROR: send consumer > channel: Bad file descriptor [in send_kconsumer_session_streams() at > main.c:636] please see pastebin (http://pastebin.com/ivnvQWa2) for complete > logs > > I am using Linux 2.6.38 on Freescale imx6 platform. Lttng-modules 2.0.2 and > lttng-tools 2.0.1 > > -- Fahad > > _______________________________________________ lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQEcBAEBAgAGBQJPqmxeAAoJEELoaioR9I02cTcH/3cXaG82+xpXQ2dnjtYeCgic FOOtPtdHEcfECVDk05MO0uc7fk5EJa1Am6cv4QXZJdO39qEpFOLe/iilRc0aXakr BKOcekqt4o804cru3sVTRiE87+TgsA9hpdWEBtaN1ykU2IIxRzmcahM56l/MFAwz +BT7x3Z1EGWUN7iOYMg26uLHHaXSnBgnZ0ZIbJ6rhJJ4NTOjJKZ69e/aTTkBTs5r YMCvd4orI4kY1DB8aP/HmsylIW7DRuS1a0gghQS/e9ELdJop2sld3gxjpat88CNN OAW+KJEWwhCVdTcOEyaGHR5SiEIH88U954GPkBZu3ifk3OkRIS6cpuDEt+DfMkE= =fZcW -----END PGP SIGNATURE----- From gijae.chang at gmail.com Wed May 9 09:55:36 2012 From: gijae.chang at gmail.com (GJ Chang) Date: Wed, 9 May 2012 22:55:36 +0900 Subject: [lttng-dev] Is it possible profiling android ice-cream ( > kernel 3.0) with LTTng 2.0 ? Message-ID: Hello im GJ and new of LTTng and Im trying to profiling kernel in android with LTTng 2.0. so i build up LTTng modules and got belows lttng-ring-buffer-client-discard.ko lttng-ring-buffer-client-mmap-discard.ko lttng-ring-buffer-client-mmap-overwrite.ko lttng/lttng-ring-buffer-client-overwrite.ko lttng/lttng-ring-buffer-metadata-client.ko lttng/lttng-ring-buffer-metadata-mmap-client.ko lttng/lttng-statedump.ko lttng/lttng-tracer.ko and i tried to insert modules to android kernel (actually im using galaxy nexus) but i only can insert "lttng/lttng-statedump.ko" not others I believed LTTng 2.0 is working on android (ice-crean cuz it has kernel 3.0) But now, im not sure about it :( So. I really want to ask you that Is it possible to use LTTng 2.0 on Android? and Did anyone success to do this? (not about previous LTT version) If so, please let me know. and i will really appreciate it if you shows kind of manuals or web pages. Thank you. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mathieu.desnoyers at efficios.com Wed May 9 10:16:36 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 9 May 2012 10:16:36 -0400 Subject: [lttng-dev] [rp] [RFC] Readiness for URCU release with RCU lock-free hash table In-Reply-To: <20120508185048.GW21152@linux.vnet.ibm.com> References: <20120502041639.GA7857@Krystal> <20120502155430.GF2450@linux.vnet.ibm.com> <20120503171330.GA12234@Krystal> <20120503174706.GI2592@linux.vnet.ibm.com> <20120504165312.GA15996@Krystal> <20120504173613.GI2411@linux.vnet.ibm.com> <20120507161055.GA31702@Krystal> <20120508184040.GU21152@linux.vnet.ibm.com> <20120508184827.GD29665@Krystal> <20120508185048.GW21152@linux.vnet.ibm.com> Message-ID: <20120509141636.GA22193@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > On Tue, May 08, 2012 at 02:48:27PM -0400, Mathieu Desnoyers wrote: > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > On Mon, May 07, 2012 at 12:10:55PM -0400, Mathieu Desnoyers wrote: > > > > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > On Fri, May 04, 2012 at 12:53:12PM -0400, Mathieu Desnoyers wrote: > > > > [...] > > > > > Just to make sure I understand -- the reason that the "del" functions > > > > > say "no memory barrier" instead of "acts like rcu_dereference()" is > > > > > that the "del" functions don't return anything. > > > > > > > > > [...] > > > > > > @@ -391,6 +413,7 @@ int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node); > > > > > > * function. > > > > > > * Call with rcu_read_lock held. > > > > > > * Threads calling this API need to be registered RCU read-side threads. > > > > > > + * This function does not issue any memory barrier. > > > > > > */ > > > > > > > > One more question about the "del" memory ordering semantic. Following > > > > commit > > > > > > > > commit db00ccc36e7fb04ce8044fb1be7964acd1de6ae0 > > > > Author: Mathieu Desnoyers > > > > Date: Mon Dec 19 16:45:51 2011 -0500 > > > > > > > > rculfhash: Relax atomicity guarantees required by removal operation > > > > > > > > The atomicity guarantees for the removal operation do not need to be as > > > > strict as a cmpxchg. Use a uatomic_set followed by a xchg on a newly > > > > introduced "REMOVAL_OWNER_FLAG" to perform removal. > > > > > > > > Signed-off-by: Mathieu Desnoyers > > > > > > > > > > > > The "del" operation is performed in two steps: > > > > > > > > 1 - uatomic_or(), which sets the "REMOVED" flag (the actual tombstone) > > > > unconditionally into the node's next pointer. > > > > 2 - uatomic_xchg(), which atomically exchanges the old pointer with > > > > its current value (read) or'd with the REMOVAL_OWNER flag. The trick > > > > is that if the xchg returns a pointer with the REMOVAL_OWNER flag > > > > set, it means we are not the first thread to set this flag, so we > > > > should not free the node. However, if xchg returns a node without > > > > the REMOVAL_OWNER flag set, we are indeed the first to set it, so > > > > we should call free. > > > > > > > > Now regarding memory ordering semantics, should we consider the atomic > > > > action of "del" to apply when the "or" is called, or when the "xchg" is > > > > called ? Or should we simply document that the "del" effect on the node > > > > happens in two separate steps ? > > > > > > > > The way I see it, the actual effect of removal, as seen from RCU read > > > > traversal and lookup point of view, is observed as soon as the "REMOVED" > > > > tombstone is set, so I would think that the atomic publication of the > > > > removal is performed by the "or". > > > > > > > > However, we ensure full memory barriers around "xchg", but not usually > > > > around "or". Therefore, the current implementation does not issue a > > > > memory barrier before the "or", so we should either change our planned > > > > memory barrier documentation, or the implementation, to match. This > > > > would probably require creation of a cmm_smp_mb__before_uatomic_or(), so > > > > x86 does not end up issuing a useless memory barrer. > > > > > > My kneejerk reaction is that the "or" is really doing the deletion. > > > Readers and other updaters care about the deletion, not about which CPU > > > is going to do the free. > > > > > > Or did I misunderstand how this works? > > > > You got it right, this is how I see it too. > > > > However, in order to provide a full memory barrier before the "or", we'd > > need to add a cmm_smp_mb() before the "or" (I don't think we want to > > presume that our "or" operation issues full memory barriers on all > > architectures). > > > > However, on x86, the "lock; or" does issue a full memory barrier. So I > > think we should introduce a macro that can translate into a memory > > barrier on architectures that need it, and to nothing on x86. > > > > Thoughts ? > > Makes sense to me! Allright, committed the following. I end up using "cmm_smp_mb__before_uatomic_*". commit 7b783f818175cd92d98f78e761331f306ff406a5 Author: Mathieu Desnoyers Date: Tue May 8 17:12:20 2012 -0400 rculfhash: document implied memory barriers We choose to provide full memory barriers before and after successful hash table update operations. Eventually, new API with weaker semantic can be added, but let's make the basic API as fool-proof as possible. Signed-off-by: Mathieu Desnoyers Reviewed-by: "Paul E. McKenney" commit 196f4fab9bf26c48bc318ac2ff985469c4f62c7e Author: Mathieu Desnoyers Date: Tue May 8 17:09:46 2012 -0400 rculfhash: Ensure future-proof memory barrier semantic consistency Use cmm_smp_mb__before_uatomic_or() prior to the uatomic_or() in _rcu_lfht_del() to ensure correct memory barrier semantic when we relax (in the future) the barrier implementation of some architectures. Signed-off-by: Mathieu Desnoyers commit 42e83919d54e7dc45d11b99a957b436403d16b68 Author: Mathieu Desnoyers Date: Tue May 8 17:07:03 2012 -0400 API cleanup: use "uatomic_*" in cmm_smp_mb__ API Signed-off-by: Mathieu Desnoyers commit 2812a2d2cfdfeea621768de1a0216bc1549a4902 Author: Mathieu Desnoyers Date: Tue May 8 16:47:28 2012 -0400 uatomic: add memory barrier API for and/or/add/sub/inc/sub Implement: cmm_smp_mb__before_and, cmm_smp_mb__after_and cmm_smp_mb__before_or, cmm_smp_mb__after_or cmm_smp_mb__before_add, cmm_smp_mb__after_add cmm_smp_mb__before_sub, cmm_smp_mb__after_sub cmm_smp_mb__before_inc, cmm_smp_mb__after_inc cmm_smp_mb__before_dec, cmm_smp_mb__after_dec For generic and x86. These currently translate into simple compiler barriers on all architectures, but the and/or/add/sub/inc/dec uatomics do not provide memory ordering guarantees (only uatomic_add_return, uatomic_sub_return, uatomic_xchg, and uatomic_cmpxchg provides full memory barrier guarantees before and after the atomic operations). Signed-off-by: Mathieu Desnoyers Thanks, Mathieu > > Thanx, Paul > > > Thanks, > > > > Mathieu > > > > > > > > Thanx, Paul > > > > > > > Thoughts ? > > > > > > > > Thanks, > > > > > > > > Mathieu > > > > > > > > -- > > > > Mathieu Desnoyers > > > > Operating System Efficiency R&D Consultant > > > > EfficiOS Inc. > > > > http://www.efficios.com > > > > > > > > _______________________________________________ > > > > rp mailing list > > > > rp at svcs.cs.pdx.edu > > > > http://svcs.cs.pdx.edu/mailman/listinfo/rp > > > > > > > > > > > > > _______________________________________________ > > > lttng-dev mailing list > > > lttng-dev at lists.lttng.org > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From fahad.usman at gmail.com Wed May 9 11:30:35 2012 From: fahad.usman at gmail.com (Fahad Usman) Date: Wed, 9 May 2012 20:30:35 +0500 Subject: [lttng-dev] problem starting trace on arm target In-Reply-To: <4FAA6C62.8000500@efficios.com> References: <4FAA6C62.8000500@efficios.com> Message-ID: Hi David, here are the logs on the two terminals, Term1: http://pastebin.com/dYGCrGcb Term2: http://pastebin.com/4XCn4Asv Please let me know if you want any other info from me. -- Fahad On Wed, May 9, 2012 at 6:08 PM, David Goulet wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > Hi Fahad, > > This is error is a bit peculiar... > > Can you provide the full log of the session daemon like so. > > (term1) # lttng-sessiond -vvv > > (term2) the rest of the commands adding -vvv to "lttng" command line. > > Thanks! > David > > On 09/05/12 08:20 AM, Fahad Usman wrote: >> Hi, I am trying to use lttng-modules on an arm target, but when I try to >> start tracing I get some errors like PERROR: sendmsg: Bad file descriptor >> [in lttcomm_send_unix_sock() at sessiond-comm.c:310] PERROR: send consumer >> channel: Bad file descriptor [in send_kconsumer_session_streams() at >> main.c:636] please see pastebin (http://pastebin.com/ivnvQWa2) for complete >> logs >> >> I am using Linux 2.6.38 on Freescale imx6 platform. Lttng-modules 2.0.2 and >> lttng-tools 2.0.1 >> >> -- Fahad >> >> _______________________________________________ lttng-dev mailing list >> lttng-dev at lists.lttng.org >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v1.4.12 (GNU/Linux) > > iQEcBAEBAgAGBQJPqmxeAAoJEELoaioR9I02cTcH/3cXaG82+xpXQ2dnjtYeCgic > FOOtPtdHEcfECVDk05MO0uc7fk5EJa1Am6cv4QXZJdO39qEpFOLe/iilRc0aXakr > BKOcekqt4o804cru3sVTRiE87+TgsA9hpdWEBtaN1ykU2IIxRzmcahM56l/MFAwz > +BT7x3Z1EGWUN7iOYMg26uLHHaXSnBgnZ0ZIbJ6rhJJ4NTOjJKZ69e/aTTkBTs5r > YMCvd4orI4kY1DB8aP/HmsylIW7DRuS1a0gghQS/e9ELdJop2sld3gxjpat88CNN > OAW+KJEWwhCVdTcOEyaGHR5SiEIH88U954GPkBZu3ifk3OkRIS6cpuDEt+DfMkE= > =fZcW > -----END PGP SIGNATURE----- From frew at cs.stanford.edu Wed May 9 12:43:58 2012 From: frew at cs.stanford.edu (Fred Wulff) Date: Wed, 9 May 2012 09:43:58 -0700 Subject: [lttng-dev] Is it possible profiling android ice-cream ( > kernel 3.0) with LTTng 2.0 ? In-Reply-To: References: Message-ID: On Wed, May 9, 2012 at 6:55 AM, GJ Chang wrote: > Hello im GJ and new of LTTng > and Im trying to profiling kernel in android with LTTng 2.0. > so i build up LTTng modules and got belows > > lttng-ring-buffer-client-discard.ko > lttng-ring-buffer-client-mmap-discard.ko > lttng-ring-buffer-client-mmap-overwrite.ko > lttng/lttng-ring-buffer-client-overwrite.ko > lttng/lttng-ring-buffer-metadata-client.ko > lttng/lttng-ring-buffer-metadata-mmap-client.ko > lttng/lttng-statedump.ko > lttng/lttng-tracer.ko > > and i tried to insert modules to android kernel (actually im using galaxy > nexus) > but i only can insert "lttng/lttng-statedump.ko" not others > I don't know about Android specifically, but I'm guessing your problem is that you're not inserting the kernel modules built in subdirectories. The canonical way to do that is using depmod (see the README for instructions), but if that doesn't work on Android, an ordering that works for installing all of the modules is: insmod probes/lttng-types.ko insmod probes/lttng-kretprobes.ko insmod probes/lttng-kprobes.ko insmod probes/lttng-ftrace.ko insmod lib/lttng-lib-ring-buffer.ko insmod lttng-statedump.ko insmod lttng-tracer.ko insmod probes/lttng-probe-timer.ko insmod probes/lttng-probe-statedump.ko insmod probes/lttng-probe-signal.ko insmod probes/lttng-probe-sched.ko insmod probes/lttng-probe-lttng.ko insmod probes/lttng-probe-kvm.ko insmod probes/lttng-probe-irq.ko insmod probes/lttng-probe-block.ko insmod lttng-ring-buffer-metadata-mmap-client.ko insmod lttng-ring-buffer-metadata-client.ko insmod lttng-ring-buffer-client-overwrite.ko insmod lttng-ring-buffer-client-mmap-overwrite.ko insmod lttng-ring-buffer-client-mmap-discard.ko insmod lttng-ring-buffer-client-discard.ko -------------- next part -------------- An HTML attachment was scrubbed... URL: From francis.giraldeau at gmail.com Wed May 9 13:31:28 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Wed, 9 May 2012 19:31:28 +0200 Subject: [lttng-dev] [PATCH] Create kernel events by writing to proc file Message-ID: <1336584688-20303-1-git-send-email-francis.giraldeau@gmail.com> This feature allow to write events in the kernel trace stream by writing to the file /proc/lttng_user_event. The content is written unmodified to the trace as string type. The maximum string length saved per event is 256 bytes. The event type and the proc file are accessibles when the module lttng-user-event is loaded. This is a prototype implementation. The final implementation should avoid the temp copy of the string on the kernel stack. --- Makefile | 1 + instrumentation/events/lttng-module/lttng.h | 19 +++ probes/Makefile | 1 + probes/lttng-user-event.c | 159 +++++++++++++++++++++++++++ 4 files changed, 180 insertions(+), 0 deletions(-) create mode 100644 probes/lttng-user-event.c diff --git a/Makefile b/Makefile index dfa0792..6bd203d 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,7 @@ lttng-tracer-objs := lttng-events.o lttng-abi.o \ obj-m += lttng-statedump.o lttng-statedump-objs := lttng-statedump-impl.o wrapper/irqdesc.o +lttng-user-event-objs := lttng-user-event.o ifneq ($(CONFIG_HAVE_SYSCALL_TRACEPOINTS),) lttng-tracer-objs += lttng-syscalls.o diff --git a/instrumentation/events/lttng-module/lttng.h b/instrumentation/events/lttng-module/lttng.h index 6f3d6d1..9da3c7e 100644 --- a/instrumentation/events/lttng-module/lttng.h +++ b/instrumentation/events/lttng-module/lttng.h @@ -6,6 +6,8 @@ #include +#define LTTNG_UEVENT_SIZE 256 + TRACE_EVENT(lttng_metadata, TP_PROTO(const char *str), @@ -28,6 +30,23 @@ TRACE_EVENT(lttng_metadata, TP_printk("") ) +TRACE_EVENT(lttng_uevent, + + TP_PROTO(char *str), + + TP_ARGS(str), + + TP_STRUCT__entry( + __array_text( char, text, LTTNG_UEVENT_SIZE ) + ), + + TP_fast_assign( + tp_memcpy(text, str, LTTNG_UEVENT_SIZE) + ), + + TP_printk("text=%s", __entry->text) +) + #endif /* _TRACE_LTTNG_H */ /* This part must be outside protection */ diff --git a/probes/Makefile b/probes/Makefile index 698a9c9..31ac769 100644 --- a/probes/Makefile +++ b/probes/Makefile @@ -14,6 +14,7 @@ obj-m += lttng-probe-sched.o obj-m += lttng-probe-irq.o obj-m += lttng-probe-signal.o obj-m += lttng-probe-timer.o +obj-m += lttng-user-event.o obj-m += lttng-probe-statedump.o diff --git a/probes/lttng-user-event.c b/probes/lttng-user-event.c new file mode 100644 index 0000000..d3b66e6 --- /dev/null +++ b/probes/lttng-user-event.c @@ -0,0 +1,159 @@ +/* + * lttng-user-event.c + * + * Copyright (C) 2006 Mathieu Desnoyers + * + * 2012-05-08 Ported to lttng 2 by Francis Giraldeau + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* is there a prefered include order? */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../instrumentation/events/lttng-module/lttng.h" + +DEFINE_TRACE(lttng_uevent); + +#define LTTNG_UEVENT_FILE "lttng_user_event" + +struct proc_dir_entry *lttng_root; +static struct proc_dir_entry *write_file; + +/** + * write_event - write a userspace string into the trace system + * @file: file pointer + * @user_buf: user string + * @count: length to copy, including the final NULL + * @ppos: unused + * + * Copy a string into a trace event "user_event". Pins pages in memory to avoid + * intermediate copy. + * + * On success, returns the number of bytes copied from the source. + * + * Inspired from tracing_mark_write implementation from Steven Rostedt and + * Ingo Molnar. + */ +static +ssize_t write_event(struct file *file, const char __user *user_buf, + size_t count, loff_t *fpos) +{ + char tmp[LTTNG_UEVENT_SIZE]; + unsigned long addr = (unsigned long)user_buf; + struct page *pages[2]; + int nr_pages = 1; + void *page1, *page2; + ssize_t written; + int offset, ret, len; + + if (count >= LTTNG_UEVENT_SIZE) + count = LTTNG_UEVENT_SIZE - 1; + + BUILD_BUG_ON(LTTNG_UEVENT_SIZE >= PAGE_SIZE); + + if ((addr & PAGE_MASK) != ((addr + count) & PAGE_MASK)) + nr_pages = 2; + + offset = addr & (PAGE_SIZE - 1); + addr &= PAGE_MASK; + + ret = get_user_pages_fast(addr, nr_pages, 0, pages); + if (ret < nr_pages) { + while (--ret >= 0) + put_page(pages[ret]); + written = -EFAULT; + goto out; + } + + page1 = kmap_atomic(pages[0]); + if (nr_pages == 2) + page2 = kmap_atomic(pages[1]); + + if (nr_pages == 2) { + len = PAGE_SIZE - offset; + memcpy(tmp, page1 + offset, len); + memcpy(tmp + len, page2, count - len); + } else + memcpy(tmp, page1 + offset, count); + + /* make sure the string is null terminated */ + tmp[count] = '\0'; + trace_lttng_uevent(tmp); + written = count; + + if (nr_pages == 2) + kunmap_atomic(page2); + kunmap_atomic(page1); + while (nr_pages > 0) + put_page(pages[--nr_pages]); + out: + return written; +} + +static const struct file_operations write_file_ops = { + .owner = THIS_MODULE, + .write = write_event +}; + +static int __init lttng_user_event_init(void) +{ + int err = 0; + + /* lttng is already a file with the current abi, not a directory */ + /* + lttng_root = proc_mkdir("lttng", NULL); + if (lttng_root == NULL) + return -ENOMEM; + */ + write_file = create_proc_entry(LTTNG_UEVENT_FILE, 0644, lttng_root); + if (!write_file) { + err = -ENOENT; + goto err_procfs; + } + write_file->proc_fops = &write_file_ops; + write_file->mode = S_IFREG | S_IWUGO; + write_file->uid = 0; + write_file->gid = 0; + return err; + +err_procfs: + remove_proc_entry(LTTNG_UEVENT_FILE, lttng_root); + return err; +} + +static void __exit lttng_user_event_exit(void) +{ + remove_proc_entry(LTTNG_UEVENT_FILE, lttng_root); + printk(KERN_INFO "/proc/%s removed\n", LTTNG_UEVENT_FILE); +} + +module_init(lttng_user_event_init); +module_exit(lttng_user_event_exit); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Francis Giraldeau "); +MODULE_DESCRIPTION("Append custom events to kernel trace from userspace"); -- 1.7.5.4 From mathieu.desnoyers at efficios.com Wed May 9 14:04:24 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 9 May 2012 14:04:24 -0400 Subject: [lttng-dev] [PATCH] Create kernel events by writing to proc file In-Reply-To: <1336584688-20303-1-git-send-email-francis.giraldeau@gmail.com> References: <1336584688-20303-1-git-send-email-francis.giraldeau@gmail.com> Message-ID: <20120509180424.GA26203@Krystal> * Francis Giraldeau (francis.giraldeau at gmail.com) wrote: > This feature allow to write events in the kernel trace stream by writing to the > file /proc/lttng_user_event. The content is written unmodified to the trace as > string type. The maximum string length saved per event is 256 bytes. The event > type and the proc file are accessibles when the module lttng-user-event is > loaded. > > This is a prototype implementation. The final implementation should avoid the > temp copy of the string on the kernel stack. > --- > Makefile | 1 + > instrumentation/events/lttng-module/lttng.h | 19 +++ > probes/Makefile | 1 + > probes/lttng-user-event.c | 159 +++++++++++++++++++++++++++ > 4 files changed, 180 insertions(+), 0 deletions(-) > create mode 100644 probes/lttng-user-event.c > > diff --git a/Makefile b/Makefile > index dfa0792..6bd203d 100644 > --- a/Makefile > +++ b/Makefile > @@ -24,6 +24,7 @@ lttng-tracer-objs := lttng-events.o lttng-abi.o \ > > obj-m += lttng-statedump.o > lttng-statedump-objs := lttng-statedump-impl.o wrapper/irqdesc.o > +lttng-user-event-objs := lttng-user-event.o > > ifneq ($(CONFIG_HAVE_SYSCALL_TRACEPOINTS),) > lttng-tracer-objs += lttng-syscalls.o > diff --git a/instrumentation/events/lttng-module/lttng.h b/instrumentation/events/lttng-module/lttng.h > index 6f3d6d1..9da3c7e 100644 > --- a/instrumentation/events/lttng-module/lttng.h > +++ b/instrumentation/events/lttng-module/lttng.h > @@ -6,6 +6,8 @@ > > #include > > +#define LTTNG_UEVENT_SIZE 256 > + > TRACE_EVENT(lttng_metadata, > > TP_PROTO(const char *str), > @@ -28,6 +30,23 @@ TRACE_EVENT(lttng_metadata, > TP_printk("") > ) > > +TRACE_EVENT(lttng_uevent, > + > + TP_PROTO(char *str), > + > + TP_ARGS(str), > + > + TP_STRUCT__entry( > + __array_text( char, text, LTTNG_UEVENT_SIZE ) > + ), > + > + TP_fast_assign( > + tp_memcpy(text, str, LTTNG_UEVENT_SIZE) FYI, we have __string_from_user and tp_copy_string_from_user for that (you won't have to do the copy). > + ), > + > + TP_printk("text=%s", __entry->text) > +) > + > #endif /* _TRACE_LTTNG_H */ > > /* This part must be outside protection */ > diff --git a/probes/Makefile b/probes/Makefile > index 698a9c9..31ac769 100644 > --- a/probes/Makefile > +++ b/probes/Makefile > @@ -14,6 +14,7 @@ obj-m += lttng-probe-sched.o > obj-m += lttng-probe-irq.o > obj-m += lttng-probe-signal.o > obj-m += lttng-probe-timer.o > +obj-m += lttng-user-event.o > > obj-m += lttng-probe-statedump.o > > diff --git a/probes/lttng-user-event.c b/probes/lttng-user-event.c > new file mode 100644 > index 0000000..d3b66e6 > --- /dev/null > +++ b/probes/lttng-user-event.c > @@ -0,0 +1,159 @@ > +/* > + * lttng-user-event.c > + * > + * Copyright (C) 2006 Mathieu Desnoyers > + * > + * 2012-05-08 Ported to lttng 2 by Francis Giraldeau > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. This file should be GPLv2, as below one function states that it is inspired from tracing_mark_write in the Linux kernel, which is licensed GPLv2. Or simply reimplement write_event: it will become _trivial_ with the proper zero-copy approach hinted at above. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +/* is there a prefered include order? */ nope > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "../instrumentation/events/lttng-module/lttng.h" > + > +DEFINE_TRACE(lttng_uevent); > + > +#define LTTNG_UEVENT_FILE "lttng_user_event" > + > +struct proc_dir_entry *lttng_root; static. > +static struct proc_dir_entry *write_file; > + > +/** > + * write_event - write a userspace string into the trace system > + * @file: file pointer > + * @user_buf: user string > + * @count: length to copy, including the final NULL > + * @ppos: unused > + * > + * Copy a string into a trace event "user_event". Pins pages in memory to avoid > + * intermediate copy. > + * > + * On success, returns the number of bytes copied from the source. > + * > + * Inspired from tracing_mark_write implementation from Steven Rostedt and > + * Ingo Molnar. > + */ > +static > +ssize_t write_event(struct file *file, const char __user *user_buf, > + size_t count, loff_t *fpos) > +{ > + char tmp[LTTNG_UEVENT_SIZE]; > + unsigned long addr = (unsigned long)user_buf; > + struct page *pages[2]; > + int nr_pages = 1; > + void *page1, *page2; > + ssize_t written; > + int offset, ret, len; > + > + if (count >= LTTNG_UEVENT_SIZE) > + count = LTTNG_UEVENT_SIZE - 1; > + > + BUILD_BUG_ON(LTTNG_UEVENT_SIZE >= PAGE_SIZE); > + > + if ((addr & PAGE_MASK) != ((addr + count) & PAGE_MASK)) > + nr_pages = 2; > + > + offset = addr & (PAGE_SIZE - 1); > + addr &= PAGE_MASK; > + > + ret = get_user_pages_fast(addr, nr_pages, 0, pages); > + if (ret < nr_pages) { > + while (--ret >= 0) > + put_page(pages[ret]); > + written = -EFAULT; > + goto out; > + } > + > + page1 = kmap_atomic(pages[0]); > + if (nr_pages == 2) > + page2 = kmap_atomic(pages[1]); > + > + if (nr_pages == 2) { > + len = PAGE_SIZE - offset; > + memcpy(tmp, page1 + offset, len); > + memcpy(tmp + len, page2, count - len); > + } else > + memcpy(tmp, page1 + offset, count); > + > + /* make sure the string is null terminated */ > + tmp[count] = '\0'; > + trace_lttng_uevent(tmp); > + written = count; > + > + if (nr_pages == 2) > + kunmap_atomic(page2); > + kunmap_atomic(page1); > + while (nr_pages > 0) > + put_page(pages[--nr_pages]); > + out: > + return written; > +} > + > +static const struct file_operations write_file_ops = { > + .owner = THIS_MODULE, > + .write = write_event > +}; > + > +static int __init lttng_user_event_init(void) > +{ > + int err = 0; > + > + /* lttng is already a file with the current abi, not a directory */ > + /* > + lttng_root = proc_mkdir("lttng", NULL); why do you mkdir lttng ? It conflicts with /proc/lttng. Thanks, Mathieu > + if (lttng_root == NULL) > + return -ENOMEM; > + */ > + write_file = create_proc_entry(LTTNG_UEVENT_FILE, 0644, lttng_root); > + if (!write_file) { > + err = -ENOENT; > + goto err_procfs; > + } > + write_file->proc_fops = &write_file_ops; > + write_file->mode = S_IFREG | S_IWUGO; > + write_file->uid = 0; > + write_file->gid = 0; > + return err; > + > +err_procfs: > + remove_proc_entry(LTTNG_UEVENT_FILE, lttng_root); > + return err; > +} > + > +static void __exit lttng_user_event_exit(void) > +{ > + remove_proc_entry(LTTNG_UEVENT_FILE, lttng_root); > + printk(KERN_INFO "/proc/%s removed\n", LTTNG_UEVENT_FILE); > +} > + > +module_init(lttng_user_event_init); > +module_exit(lttng_user_event_exit); > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Francis Giraldeau "); > +MODULE_DESCRIPTION("Append custom events to kernel trace from userspace"); > -- > 1.7.5.4 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From ettore at ettoredelnegro.me Wed May 9 20:51:55 2012 From: ettore at ettoredelnegro.me (Ettore Del Negro) Date: Thu, 10 May 2012 02:51:55 +0200 Subject: [lttng-dev] UST lttng enable-event output improvement Message-ID: <4FAB112B.9040801@ettoredelnegro.me> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello, i have a simple question which may lead to a small user experience improvement: > lttng create tsession Session tsession created. Traces will be written in .../lttng-traces/tsession-20120510-015819 > lttng enable-channel tchan -u -s tsession --subbuf-size=1024 UST channel tchan enabled for session tsession a message stating that buffer size is set to a value different than default would be nice > lttng enable-channel tchan -u -s tsession --subbuf-size=1022 UST channel tchan enabled for session tsession What happens? Is it set to a value not power of 2? Is it set to the default value? (i guess the latter). The help says: - --subbuf-size SIZE Subbuffer size in bytes (default: 4096, kernel default: 262144) Needs to be a power of 2 for kernel and ust tracers Thanks, Ettore -----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2.0.17 (Darwin) Comment: GPGTools - http://gpgtools.org Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iQIcBAEBAgAGBQJPqxEqAAoJEBroCbr/OjsafdAQAKKabbxxbEaX5KojAZe5Fqfz YqCweqj1k6EutxNl2MOEZNVTHpOMQVUZ6qtzvkrHndSA/yDUpWH1ivT70bIewjn5 SKQfu9OWhlhQR3W5CfHDHb4eE/38dzvkYc+AkS/VlH1gMD3NtWLeIF7BCPytmYKY XXaISNOZ5r9eL3Td5yOxNn8w3TsJfe54xVfuAY7CUD/nDovhKufFgyLF9QyrTLX1 xp5NZMNSrLDlbL4AWw6y96TKJacmzUp066RYD01cjnqNt6bIyxRGjePXZUsLtpfG +oHAct8PeKgYCtId6HJ6f5SbRfYrwX/aLQk3W1o8Ba9MvRb52LE2j29WpS1NJhcp LpQHZL6OOQFbXaTfqMI3pfhxi/TqT12wkxxPG3AYR5gxzovvOuAlknzlfjrzDnCs WK0PNA1++tPtgBSHl6cwcbNVW33KqIoEuG1wI7gVY/pJosvCXoSadra+TYatIhW7 rd53Z7G+P9jxU9Aq9nR/obATI2RSObSGAtLTHMTsYlTPB/e1TpC07CeHtgS0yUdP FpOuVkchOYt1FgO9CF7t7ndQGP0mLZscxWYKlvj2U15uQhHEzbk5YAuAtjbYoH/0 7bu1kDc3r+3Ll/6eynFJ3JzTd+6vQ+BQht8ulif+vUF1qkEB8XxPhwbXxKRWpf+S rG9FUiDO86ndDwHe5UjR =Q2pu -----END PGP SIGNATURE----- From francis.giraldeau at gmail.com Thu May 10 09:36:34 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Thu, 10 May 2012 15:36:34 +0200 Subject: [lttng-dev] [PATCH] Create kernel events by writing to proc file In-Reply-To: <20120509180424.GA26203@Krystal> References: <1336584688-20303-1-git-send-email-francis.giraldeau@gmail.com> <20120509180424.GA26203@Krystal> Message-ID: <1336656994.10772.12.camel@blob> Le mercredi 09 mai 2012 ? 14:04 -0400, Mathieu Desnoyers a ?crit : > * Francis Giraldeau (francis.giraldeau at gmail.com) wrote: > > This feature allow to write events in the kernel trace stream by writing to the > > file /proc/lttng_user_event. The content is written unmodified to the trace as > > string type. The maximum string length saved per event is 256 bytes. The event > > type and the proc file are accessibles when the module lttng-user-event is > > loaded. > > > > This is a prototype implementation. The final implementation should avoid the > > temp copy of the string on the kernel stack. > > --- > > Makefile | 1 + > > instrumentation/events/lttng-module/lttng.h | 19 +++ > > probes/Makefile | 1 + > > probes/lttng-user-event.c | 159 +++++++++++++++++++++++++++ > > 4 files changed, 180 insertions(+), 0 deletions(-) > > create mode 100644 probes/lttng-user-event.c > > > > diff --git a/Makefile b/Makefile > > index dfa0792..6bd203d 100644 > > --- a/Makefile > > +++ b/Makefile > > @@ -24,6 +24,7 @@ lttng-tracer-objs := lttng-events.o lttng-abi.o \ > > > > obj-m += lttng-statedump.o > > lttng-statedump-objs := lttng-statedump-impl.o wrapper/irqdesc.o > > +lttng-user-event-objs := lttng-user-event.o > > > > ifneq ($(CONFIG_HAVE_SYSCALL_TRACEPOINTS),) > > lttng-tracer-objs += lttng-syscalls.o > > diff --git a/instrumentation/events/lttng-module/lttng.h b/instrumentation/events/lttng-module/lttng.h > > index 6f3d6d1..9da3c7e 100644 > > --- a/instrumentation/events/lttng-module/lttng.h > > +++ b/instrumentation/events/lttng-module/lttng.h > > @@ -6,6 +6,8 @@ > > > > #include > > > > +#define LTTNG_UEVENT_SIZE 256 > > + > > TRACE_EVENT(lttng_metadata, > > > > TP_PROTO(const char *str), > > @@ -28,6 +30,23 @@ TRACE_EVENT(lttng_metadata, > > TP_printk("") > > ) > > > > +TRACE_EVENT(lttng_uevent, > > + > > + TP_PROTO(char *str), > > + > > + TP_ARGS(str), > > + > > + TP_STRUCT__entry( > > + __array_text( char, text, LTTNG_UEVENT_SIZE ) > > + ), > > + > > + TP_fast_assign( > > + tp_memcpy(text, str, LTTNG_UEVENT_SIZE) > > FYI, we have __string_from_user and tp_copy_string_from_user for that > (you won't have to do the copy). Ok, did an experiment to compare TP, see next message. > > + * This library is free software; you can redistribute it and/or > > + * modify it under the terms of the GNU Lesser General Public > > + * License as published by the Free Software Foundation; only > > + * version 2.1 of the License. > > This file should be GPLv2, as below one function states that it is > inspired from tracing_mark_write in the Linux kernel, which is licensed > GPLv2. Or simply reimplement write_event: it will become _trivial_ with > the proper zero-copy approach hinted at above. Ok, will take that into account for the final version. > > +struct proc_dir_entry *lttng_root; > > static. Removed anyway... > > + /* lttng is already a file with the current abi, not a directory */ > > + /* > > + lttng_root = proc_mkdir("lttng", NULL); > > why do you mkdir lttng ? It conflicts with /proc/lttng. Yeah, that's why it was disabled. I removed it. It would have been great if /proc/lttng was a directory, because then all related files could have been added into it. (ex: /proc/lttng/control, /proc/lttng/user_event, etc.) I guess that, since old clients uses /proc/lttng, it's cast in stone, isn't? Francis From francis.giraldeau at gmail.com Thu May 10 09:38:05 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Thu, 10 May 2012 15:38:05 +0200 Subject: [lttng-dev] [PATCH] Experiments to use other tp facilities Message-ID: <1336657085-18362-1-git-send-email-francis.giraldeau@gmail.com> Added two functions to test how to write string events: * Using tp_copy_string_from_user * can't enforce string length * can't enforce '\0' at EOL * can't return the number of bytes written to the caller * Using tp_memcpy_from_user * can't enforce '\0' at EOL * this TP doesn't show-up with lttng list -k, maybe miss usage of the TRACE_EVENT macro? Also, adding a small script to quickly test experiments with various files. --- do-user-event-experiment.sh | 15 ++++ instrumentation/events/lttng-module/lttng.h | 34 +++++++++ probes/lttng-user-event.c | 97 +++++++++++++++++++++----- 3 files changed, 127 insertions(+), 19 deletions(-) create mode 100755 do-user-event-experiment.sh diff --git a/do-user-event-experiment.sh b/do-user-event-experiment.sh new file mode 100755 index 0000000..d41d8e4 --- /dev/null +++ b/do-user-event-experiment.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +rmmod lttng-user-event +modprobe lttng-user-event +lttng create test +lttng enable-event lttng_uevent_memcpy -k +lttng enable-event lttng_uevent_cfu -k +lttng enable-event lttng_uevent -k +lttng start +echo -n "bidon" > /proc/lttng_user_event +echo -n "bidon" > /proc/lttng_user_event_cfu +echo -n "bidon" > /proc/lttng_user_event_memcpy +lttng stop +lttng view +lttng destroy diff --git a/instrumentation/events/lttng-module/lttng.h b/instrumentation/events/lttng-module/lttng.h index 9da3c7e..e505c21 100644 --- a/instrumentation/events/lttng-module/lttng.h +++ b/instrumentation/events/lttng-module/lttng.h @@ -47,6 +47,40 @@ TRACE_EVENT(lttng_uevent, TP_printk("text=%s", __entry->text) ) +TRACE_EVENT(lttng_uevent_cfu, + + TP_PROTO(const char *str), + + TP_ARGS(str), + + TP_STRUCT__entry( + __string_from_user( str, str ) + ), + + TP_fast_assign( + tp_copy_string_from_user(str, str) + ), + + TP_printk() +) + +TRACE_EVENT(lttng_uevent_memcpy, + + TP_PROTO(const char *str, size_t len), + + TP_ARGS(str, len), + + TP_STRUCT__entry( + __string( text, str ) + ), + + TP_fast_assign( + tp_memcpy_from_user(text, str, len) + ), + + TP_printk("text=%s", __entry->text) +) + #endif /* _TRACE_LTTNG_H */ /* This part must be outside protection */ diff --git a/probes/lttng-user-event.c b/probes/lttng-user-event.c index d3b66e6..db45ad4 100644 --- a/probes/lttng-user-event.c +++ b/probes/lttng-user-event.c @@ -8,7 +8,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; only - * version 2.1 of the License. + * version 2 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -37,11 +37,12 @@ #include "../instrumentation/events/lttng-module/lttng.h" DEFINE_TRACE(lttng_uevent); +DEFINE_TRACE(lttng_uevent_cfu); +DEFINE_TRACE(lttng_uevent_memcpy); #define LTTNG_UEVENT_FILE "lttng_user_event" - -struct proc_dir_entry *lttng_root; -static struct proc_dir_entry *write_file; +#define LTTNG_UEVENT_FILE_CFU "lttng_user_event_cfu" +#define LTTNG_UEVENT_FILE_MEMCPY "lttng_user_event_memcpy" /** * write_event - write a userspace string into the trace system @@ -114,41 +115,99 @@ ssize_t write_event(struct file *file, const char __user *user_buf, return written; } +/* CFU stands for Copy From User */ +static +ssize_t write_event_copy_from_user(struct file *file, const char __user *user_buf, + size_t count, loff_t *fpos) +{ + /* How do we know how much data is written? Otherwise, + * this function can't return the appropriate value. + * + * If the user string is not null-terminated, + * then could it leak info beyong the string? : yes + * + * Assuming the userspace string is well formated + * seems not appropriate. + */ + trace_lttng_uevent_cfu(user_buf); + return count; +} + +static +ssize_t write_event_memcpy(struct file *file, const char __user *user_buf, + size_t count, loff_t *fpos) +{ + if (count >= LTTNG_UEVENT_SIZE) + count = LTTNG_UEVENT_SIZE - 1; + + /* + * still unable to enforce null terminated string + * userspace won't be happy if we change their buffers in-place + */ + trace_lttng_uevent_memcpy(user_buf, count); + return count; +} + static const struct file_operations write_file_ops = { .owner = THIS_MODULE, .write = write_event }; -static int __init lttng_user_event_init(void) +static const struct file_operations write_file_cfu_ops = { + .owner = THIS_MODULE, + .write = write_event_copy_from_user +}; + +static const struct file_operations write_file_memcpy_ops = { + .owner = THIS_MODULE, + .write = write_event_memcpy +}; + +static int init_proc_entry(char *name, const struct file_operations *fops) { - int err = 0; + struct proc_dir_entry *write_file; - /* lttng is already a file with the current abi, not a directory */ - /* - lttng_root = proc_mkdir("lttng", NULL); - if (lttng_root == NULL) - return -ENOMEM; - */ - write_file = create_proc_entry(LTTNG_UEVENT_FILE, 0644, lttng_root); + write_file = create_proc_entry(name, 0644, NULL); if (!write_file) { - err = -ENOENT; - goto err_procfs; + return -ENOENT; } - write_file->proc_fops = &write_file_ops; + write_file->proc_fops = fops; write_file->mode = S_IFREG | S_IWUGO; write_file->uid = 0; write_file->gid = 0; + return 0; +} + +static int __init lttng_user_event_init(void) +{ + int err = 0; + + if ((err = init_proc_entry(LTTNG_UEVENT_FILE, &write_file_ops)) < 0) + goto err_1; + if ((err = init_proc_entry(LTTNG_UEVENT_FILE_CFU, &write_file_cfu_ops)) < 0) + goto err_2; + if ((err = init_proc_entry(LTTNG_UEVENT_FILE_MEMCPY, &write_file_memcpy_ops)) < 0) + goto err_3; + return err; -err_procfs: - remove_proc_entry(LTTNG_UEVENT_FILE, lttng_root); + err_3: + remove_proc_entry(LTTNG_UEVENT_FILE_MEMCPY, NULL); + err_2: + remove_proc_entry(LTTNG_UEVENT_FILE_CFU, NULL); + err_1: + remove_proc_entry(LTTNG_UEVENT_FILE, NULL); return err; } static void __exit lttng_user_event_exit(void) { - remove_proc_entry(LTTNG_UEVENT_FILE, lttng_root); + remove_proc_entry(LTTNG_UEVENT_FILE, NULL); printk(KERN_INFO "/proc/%s removed\n", LTTNG_UEVENT_FILE); + remove_proc_entry(LTTNG_UEVENT_FILE_CFU, NULL); + printk(KERN_INFO "/proc/%s removed\n", LTTNG_UEVENT_FILE_CFU); + remove_proc_entry(LTTNG_UEVENT_FILE_MEMCPY, NULL); + printk(KERN_INFO "/proc/%s removed\n", LTTNG_UEVENT_FILE_MEMCPY); } module_init(lttng_user_event_init); -- 1.7.5.4 From david.goulet at polymtl.ca Thu May 10 10:43:22 2012 From: david.goulet at polymtl.ca (David Goulet) Date: Thu, 10 May 2012 10:43:22 -0400 Subject: [lttng-dev] problem starting trace on arm target In-Reply-To: References: <4FAA6C62.8000500@efficios.com> Message-ID: <4FABD40A.6070504@polymtl.ca> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi Fahad, So, it seems you don't have a consumer installed on your system that the sessiond can access: DEBUG3: Looking for a kernel consumer at these locations: [in spawn_consumerd() at main.c:1678] DEBUG3: 1) [in spawn_consumerd() at main.c:1679] DEBUG3: 2) /usr/lib/lttng/libexec/lttng-consumerd [in spawn_consumerd() at main.c:1680] DEBUG3: 3) /usr/lib/lttng/libexec/lttng-consumerd [in spawn_consumerd() at main.c:1681] PERROR: kernel start consumer exec: No such file or directory [in spawn_consumerd() at main.c:1795] Also I'm starting to believe that you might have a memory limit problem since you are hitting this: PERROR: sendmsg: Bad file descriptor [in lttcomm_send_unix_sock() at sessiond-comm.c:310] PERROR: send consumer channel: Bad file descriptor [in send_kconsumer_session_streams() at main.c:636] PERROR: ioctl start session: No buffer space available [in kernel_start_session() at kernel.c:397] Because of that, the kernel start session command on the tracer fails... Can you validate that you have enough memory during the commands ? Moving the lttng-consumerd at the right location will at least help a bit :) Thanks! David On 09/05/12 11:30 AM, Fahad Usman wrote: > Hi David, here are the logs on the two terminals, Term1: > http://pastebin.com/dYGCrGcb Term2: http://pastebin.com/4XCn4Asv > > Please let me know if you want any other info from me. > > -- Fahad > > > On Wed, May 9, 2012 at 6:08 PM, David Goulet wrote: > Hi Fahad, > > This is error is a bit peculiar... > > Can you provide the full log of the session daemon like so. > > (term1) # lttng-sessiond -vvv > > (term2) the rest of the commands adding -vvv to "lttng" command line. > > Thanks! David > > On 09/05/12 08:20 AM, Fahad Usman wrote: >>>> Hi, I am trying to use lttng-modules on an arm target, but when I try >>>> to start tracing I get some errors like PERROR: sendmsg: Bad file >>>> descriptor [in lttcomm_send_unix_sock() at sessiond-comm.c:310] >>>> PERROR: send consumer channel: Bad file descriptor [in >>>> send_kconsumer_session_streams() at main.c:636] please see pastebin >>>> (http://pastebin.com/ivnvQWa2) for complete logs >>>> >>>> I am using Linux 2.6.38 on Freescale imx6 platform. Lttng-modules >>>> 2.0.2 and lttng-tools 2.0.1 >>>> >>>> -- Fahad >>>> >>>> _______________________________________________ lttng-dev mailing >>>> list lttng-dev at lists.lttng.org >>>> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > _______________________________________________ lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQEcBAEBAgAGBQJPq9QGAAoJEELoaioR9I02N0YH/17EdVFGWkhP+kqZJznvmv6/ +MebU8HiguKhpqYVcGjS4xw9HAR2hn3oZGAiIQSjbaDO1rhI9xWzguj+dq2gi3B4 9yjk7c6mfKMs09yqMdoWkQOmCCmnlazYZpjE0iqQxMhUC84hoPB+sBZDWBfA9nOX UD/bNkNGZOk8+vaYN+twNeB/7iNdsgISeUwaZ/5GgfJ+lCp7YAY/QaF8EVyH3DP4 upXlyhQZoSqogmtnFJxRbhTgio/P9Z9mxwc/k5GqKypBAqI9BcXvuxwgsg6rLNMW ixbGGzN/fPKn6lGW8Xv96YHFxTU1ZvC+TY06YFk3cV0amdOjkS8tOwZF/4A2K3g= =Zj2o -----END PGP SIGNATURE----- From yannick.brosseau at gmail.com Thu May 10 10:43:50 2012 From: yannick.brosseau at gmail.com (Yannick Brosseau) Date: Thu, 10 May 2012 10:43:50 -0400 Subject: [lttng-dev] Using lttng 2.0 with a kernel 2.6.32 (CentOS 6) Message-ID: <4FABD426.6050908@gmail.com> Hi All, By backporting patches to the 2.6.32 kernel and modifying the current lttng-modules, I've manage to get lttng 2.0 work on a CentOS 6 installation. It's a redhat kernel so it already contains several modification, so theses changes might not be sufficient to make it work on a vanilla 2.6.32 kernel. But it's a start. The only problem I've left is that all syscalls appears as sys_unknown. The make it works: The tree patches and the RPM specs file to make it work with the CentOS 6 kernel: http://www.dorsal.polymtl.ca/~ybrosseau/lttng2.0-2.6.32/ Modification to lttng-modules, based on the latest stable 2.0: http://git.dorsal.polymtl.ca/~ybrosseau?p=lttng-modules-2.6.32.git;a=summary I hope this could be useful. Yannick From david.goulet at polymtl.ca Thu May 10 10:46:21 2012 From: david.goulet at polymtl.ca (David Goulet) Date: Thu, 10 May 2012 10:46:21 -0400 Subject: [lttng-dev] UST lttng enable-event output improvement In-Reply-To: <4FAB112B.9040801@ettoredelnegro.me> References: <4FAB112B.9040801@ettoredelnegro.me> Message-ID: <4FABD4BD.40205@polymtl.ca> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hey, We have right now an opened bug about this exact issue. We will soon fix this and, as you said, help considerably the user experience with subbuffer size :) Thanks for the report! Cheers David On 09/05/12 08:51 PM, Ettore Del Negro wrote: > Hello, i have a simple question which may lead to a small user experience > improvement: > >> lttng create tsession > Session tsession created. Traces will be written in > .../lttng-traces/tsession-20120510-015819 >> lttng enable-channel tchan -u -s tsession --subbuf-size=1024 > UST channel tchan enabled for session tsession > > a message stating that buffer size is set to a value different than default > would be nice > >> lttng enable-channel tchan -u -s tsession --subbuf-size=1022 > UST channel tchan enabled for session tsession > > What happens? Is it set to a value not power of 2? Is it set to the default > value? (i guess the latter). The help says: --subbuf-size SIZE Subbuffer > size in bytes (default: 4096, kernel default: 262144) Needs to be a power > of 2 for kernel and ust tracers > > Thanks, Ettore > > _______________________________________________ lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQEcBAEBAgAGBQJPq9S8AAoJEELoaioR9I02qNMH/AyJRkxVVvubARNbTq5UeNXx qMpeYeKsr7s+S0MEAOSFK7LVaI/TfR9wS6NGWJGGcC/PIvBRu77+GibLXphwaYL4 RGUKVw2L3/kBG6DFTQHM1lLNYTZYrDhwrd+eS3IlK5Pdjr9qQjsjvJ/NUu8BxXId XNHu8sev6+AgkWM9r1r9pkSgi4vsUnDJ76CyXgmR02mE/ta5+6xh4rs2mizIqBkQ M7A5Gybp2nj0/NYACikBqlzZh+UFhDdNK4VEUwPidqawjsdEV9k+ljr8fhW0zoGF fTukBVjjBFfvgkmf5ghsID4MmlTGh+tezAdhBd5pDKDfUk/tHDcyPRmErBXQJE4= =1ZgS -----END PGP SIGNATURE----- From Sylvain.Sauvage at sepura.com Thu May 10 11:25:26 2012 From: Sylvain.Sauvage at sepura.com (Sylvain Sauvage) Date: Thu, 10 May 2012 16:25:26 +0100 Subject: [lttng-dev] Using LTTng on Linux Kernel 2.6.33.7-rt29 Message-ID: <7B12C7CF8EB6734F9C50A406CD99BED20EE28518@mail01b> Hi everyone, We are using a Linux 2.6.33.7 with RT patches version rt29. It is my understanding that the latest versions of LTTng 2.0 do no longer support kernels before 2.6.38. As it is not an option for us to move up to a more recent Kernel, we would like to use the most recent LTTng that is compatible. Could anyone advise the best starting LTTng version that would be compatible with that Kernel? The processor we use is an ARM OMAP-L138 (based on the ARMv5 core). Are there any patches to use (or port) provide the trace clock functionality? >From the compatibility list here: http://git.lttng.org/?p=lttv.git;a=blob_plain;f=doc/developer/lttng-lttv -compatibility.html;hb=HEAD, it seems that we could start from 0.216 or 0.217. Please let me know what version you would recommend and suggest extra patches (related to rt29 or to OMAPL138). Thanks in advance. Kind Regards, Sylvain Sylvain Sauvage Software DA Sepura plc Radio House, St Andrew's Road Cambridge, CB4 1GR, UK T: +44 (0) 1223 877263 F: +44 (0) 1223 879000 www.sepura.com The information in this email is confidential. It is intended solely for the addressee. Access to this email by anyone else is unauthorised. If you are not the intended recipient, any disclosure, copying, or distribution is prohibited and may be unlawful. If you have received this email in error please delete it immediately and contact commercial at sepura.com. Sepura plc. Registered Office: Radio House, St Andrew?s Road, Cambridge, CB4 1GR, England. Registered in England and Wales. Registration Number 4353801 -------------- next part -------------- An HTML attachment was scrubbed... URL: From mathieu.desnoyers at efficios.com Thu May 10 11:41:26 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 10 May 2012 11:41:26 -0400 Subject: [lttng-dev] [PATCH] Create kernel events by writing to proc file In-Reply-To: <1336656994.10772.12.camel@blob> References: <1336584688-20303-1-git-send-email-francis.giraldeau@gmail.com> <20120509180424.GA26203@Krystal> <1336656994.10772.12.camel@blob> Message-ID: <20120510154126.GA18347@Krystal> * Francis Giraldeau (francis.giraldeau at gmail.com) wrote: > Le mercredi 09 mai 2012 ? 14:04 -0400, Mathieu Desnoyers a ?crit : > > * Francis Giraldeau (francis.giraldeau at gmail.com) wrote: > > > This feature allow to write events in the kernel trace stream by writing to the > > > file /proc/lttng_user_event. The content is written unmodified to the trace as > > > string type. The maximum string length saved per event is 256 bytes. The event > > > type and the proc file are accessibles when the module lttng-user-event is > > > loaded. > > > > > > This is a prototype implementation. The final implementation should avoid the > > > temp copy of the string on the kernel stack. > > > --- > > > Makefile | 1 + > > > instrumentation/events/lttng-module/lttng.h | 19 +++ > > > probes/Makefile | 1 + > > > probes/lttng-user-event.c | 159 +++++++++++++++++++++++++++ > > > 4 files changed, 180 insertions(+), 0 deletions(-) > > > create mode 100644 probes/lttng-user-event.c > > > > > > diff --git a/Makefile b/Makefile > > > index dfa0792..6bd203d 100644 > > > --- a/Makefile > > > +++ b/Makefile > > > @@ -24,6 +24,7 @@ lttng-tracer-objs := lttng-events.o lttng-abi.o \ > > > > > > obj-m += lttng-statedump.o > > > lttng-statedump-objs := lttng-statedump-impl.o wrapper/irqdesc.o > > > +lttng-user-event-objs := lttng-user-event.o > > > > > > ifneq ($(CONFIG_HAVE_SYSCALL_TRACEPOINTS),) > > > lttng-tracer-objs += lttng-syscalls.o > > > diff --git a/instrumentation/events/lttng-module/lttng.h b/instrumentation/events/lttng-module/lttng.h > > > index 6f3d6d1..9da3c7e 100644 > > > --- a/instrumentation/events/lttng-module/lttng.h > > > +++ b/instrumentation/events/lttng-module/lttng.h > > > @@ -6,6 +6,8 @@ > > > > > > #include > > > > > > +#define LTTNG_UEVENT_SIZE 256 > > > + > > > TRACE_EVENT(lttng_metadata, > > > > > > TP_PROTO(const char *str), > > > @@ -28,6 +30,23 @@ TRACE_EVENT(lttng_metadata, > > > TP_printk("") > > > ) > > > > > > +TRACE_EVENT(lttng_uevent, > > > + > > > + TP_PROTO(char *str), > > > + > > > + TP_ARGS(str), > > > + > > > + TP_STRUCT__entry( > > > + __array_text( char, text, LTTNG_UEVENT_SIZE ) > > > + ), > > > + > > > + TP_fast_assign( > > > + tp_memcpy(text, str, LTTNG_UEVENT_SIZE) > > > > FYI, we have __string_from_user and tp_copy_string_from_user for that > > (you won't have to do the copy). > > Ok, did an experiment to compare TP, see next message. > > > > + * This library is free software; you can redistribute it and/or > > > + * modify it under the terms of the GNU Lesser General Public > > > + * License as published by the Free Software Foundation; only > > > + * version 2.1 of the License. > > > > This file should be GPLv2, as below one function states that it is > > inspired from tracing_mark_write in the Linux kernel, which is licensed > > GPLv2. Or simply reimplement write_event: it will become _trivial_ with > > the proper zero-copy approach hinted at above. > > Ok, will take that into account for the final version. > > > > +struct proc_dir_entry *lttng_root; > > > > static. > > Removed anyway... > > > > + /* lttng is already a file with the current abi, not a directory */ > > > + /* > > > + lttng_root = proc_mkdir("lttng", NULL); > > > > why do you mkdir lttng ? It conflicts with /proc/lttng. > > Yeah, that's why it was disabled. I removed it. It would have been great > if /proc/lttng was a directory, because then all related files could > have been added into it. > (ex: /proc/lttng/control, /proc/lttng/user_event, etc.) I guess that, > since old clients uses /proc/lttng, it's cast in stone, isn't? Yep. The design guide-line of this lttng ABI is that only a single file is exported to user-space. ioctl are then used on this file to create anonymous file descriptors. Hrm. One thing we could do is to implement write() operation onto that file to tunnel user-space tracing data directly through the /proc/lttng file. Thoughts ? Mathieu > > Francis > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From francis.giraldeau at gmail.com Thu May 10 11:44:28 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Thu, 10 May 2012 17:44:28 +0200 Subject: [lttng-dev] [PATCH] Adding makefile target for preprocessor Message-ID: <1336664668-27713-1-git-send-email-francis.giraldeau@gmail.com> By specifying .i target, it runs gcc preprocessor for that file. Example: make myfile.i will read myfile.c and output preprocessor to myfile.i --- Makefile | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/Makefile b/Makefile index 6bd203d..bab6e7c 100644 --- a/Makefile +++ b/Makefile @@ -56,4 +56,6 @@ modules_install: clean: $(MAKE) -C $(KERNELDIR) M=$(PWD) clean +%.i: %.c + $(MAKE) -C $(KERNELDIR) M=$(PWD) $@ endif -- 1.7.5.4 From ettore at ettoredelnegro.me Thu May 10 16:34:34 2012 From: ettore at ettoredelnegro.me (Ettore Del Negro) Date: Thu, 10 May 2012 22:34:34 +0200 Subject: [lttng-dev] UST tracepoint() NULL pointer argument handling In-Reply-To: <4FABD4BD.40205@polymtl.ca> References: <4FAB112B.9040801@ettoredelnegro.me> <4FABD4BD.40205@polymtl.ca> Message-ID: <4FAC265A.1080105@ettoredelnegro.me> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Thanks David for your reply, next time (i.e. now) i will check the bug tracker first! I noticed that passing a NULL (string) pointer to a tracepoint()'s argument is not handled properly (i.e not supposed to happen). It causes the program to SIGSEV because of strlen( NULL ) in ust-tracepoint-event.h:271 . I tried some trivial patching like - - __event_len += __dynamic_len[__dynamic_len_idx++] = strlen(_src) + 1; + __event_len += __dynamic_len[__dynamic_len_idx++] = (_src == NULL ? 1 : strlen(_src) + 1); but then lib_ring_buffer_do_copy causes a SIGSEV because of memcpy( .., NULL, .. ), so i assume a NULL pointer is not expected at all. Is there any particular reason to not handle a NULL pointer? That could save the developer a ternary statement on theorically every string argument given to tracepoint() and, most importantly, the application from crash because of LTTng. Thanks, Ettore On 10/5/2012 4:46 PM, David Goulet wrote: > Hey, > > We have right now an opened bug about this exact issue. We will soon fix this and, as you said, > help considerably the user experience with subbuffer size :) > > Thanks for the report! > > Cheers David > > On 09/05/12 08:51 PM, Ettore Del Negro wrote: >> Hello, i have a simple question which may lead to a small user experience improvement: > >>> lttng create tsession >> Session tsession created. Traces will be written in >> .../lttng-traces/tsession-20120510-015819 >>> lttng enable-channel tchan -u -s tsession --subbuf-size=1024 >> UST channel tchan enabled for session tsession > >> a message stating that buffer size is set to a value different than default would be nice > >>> lttng enable-channel tchan -u -s tsession --subbuf-size=1022 >> UST channel tchan enabled for session tsession > >> What happens? Is it set to a value not power of 2? Is it set to the default value? (i guess >> the latter). The help says: --subbuf-size SIZE Subbuffer size in bytes (default: 4096, >> kernel default: 262144) Needs to be a power of 2 for kernel and ust tracers > >> Thanks, Ettore > >> _______________________________________________ lttng-dev mailing list >> lttng-dev at lists.lttng.org http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2.0.17 (Darwin) Comment: GPGTools - http://gpgtools.org Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iQIcBAEBAgAGBQJPrCZaAAoJEBroCbr/OjsadOkP/3D69W4daouFhhsWFWHUZdfz aWa1jWK1oTqSzI1aU8+wZA+XD0eV/qMiAVQWMguI9+/C9uI0qndWasaF6wZMH7h9 jFhoKzUssqMnSz6iIXQCYhdMm9v5z0NU+kKw3xnmlX4Wfxzn9wjzN1F62B/LwBiw slESKP72pRKMuigcUyUod1+C3Ddhl2odO/I091zHT3dYxA3qhLZL2sPKkR3I12YJ cP8+p4bii7rowAhUSt57dzU0V1k+yZUvvEvqvvuVFrjlf171kmy05f//Xm6npFxU Br4y/WFLg0Lf41uXRGMf0FFoXiWHPxgXpDc4vEYIjL3iHKn+JhYBxlZkw0YGPYbI G9kBw7TQogZrAxMkKL6djzuTTP/Ic/7GRqhiWP2kJrqdLI/zjobZLCy5YUOLYeZp 6iGUoZR2qMhCxpOAQuU226WuWaQmhwr3oFq5Eo602SQB58lBFqTFG+O8+rwZ+iQQ sc9MJb6Ov6WeQBzstbnQHnj1MVfbOcyz9bsztuyiMzbZ+JGk1OeDsl5sGlwzf5GP KLIukByYLvLH+7VIN2qIvIJyWQ5LobCkHjLVdMuCVgVGvemEYbt3bMaup+8acyjM +9FKw3HQER5RH7GazQylxGd9C7iV29bCWBAj2wFmh98YgWJ6V7uA73f3etpmAD0x 8ASlJci0JJVDPy8RN0hP =ds7n -----END PGP SIGNATURE----- From fahad.usman at gmail.com Fri May 11 07:48:57 2012 From: fahad.usman at gmail.com (Fahad Usman) Date: Fri, 11 May 2012 16:48:57 +0500 Subject: [lttng-dev] problem starting trace on arm target In-Reply-To: <4FABD40A.6070504@polymtl.ca> References: <4FAA6C62.8000500@efficios.com> <4FABD40A.6070504@polymtl.ca> Message-ID: Hi David, Thanks for the help. lttng-consumerd binary was actually not present at that path. I have placed it and now its working I can start tracing without any problems. Actually I was using open embedded (www.openembedded.org) framework to build lttng and other stuff. lttng-consumerd binary is now moved to a path that's not very common, I had to add a rule to explicitly include consumerd into the file system. The memory related problems still occur randomly, I am trying to find a definitive way to reproduce it thanks for your support and sorry for making noise about something that was not actually a problem with lttng -- Fahad On Thu, May 10, 2012 at 7:43 PM, David Goulet wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > Hi Fahad, > > So, it seems you don't have a consumer installed on your system that the > sessiond can access: > > DEBUG3: Looking for a kernel consumer at these locations: [in > spawn_consumerd() at main.c:1678] > DEBUG3: ? ? ? ? 1) ?[in spawn_consumerd() at main.c:1679] > DEBUG3: ? ? ? ? 2) /usr/lib/lttng/libexec/lttng-consumerd [in > spawn_consumerd() at main.c:1680] > DEBUG3: ? ? ? ? 3) /usr/lib/lttng/libexec/lttng-consumerd [in > spawn_consumerd() at main.c:1681] > PERROR: kernel start consumer exec: No such file or directory [in > spawn_consumerd() at main.c:1795] > > Also I'm starting to believe that you might have a memory limit problem since > you are hitting this: > > PERROR: sendmsg: Bad file descriptor [in lttcomm_send_unix_sock() at > sessiond-comm.c:310] > PERROR: send consumer channel: Bad file descriptor [in > send_kconsumer_session_streams() at main.c:636] > PERROR: ioctl start session: No buffer space available [in > kernel_start_session() at kernel.c:397] > > Because of that, the kernel start session command on the tracer fails... Can > you validate that you have enough memory during the commands ? > > Moving the lttng-consumerd at the right location will at least help a bit :) > > Thanks! > David > > On 09/05/12 11:30 AM, Fahad Usman wrote: >> Hi David, here are the logs on the two terminals, Term1: >> http://pastebin.com/dYGCrGcb Term2: http://pastebin.com/4XCn4Asv >> >> Please let me know if you want any other info from me. >> >> -- Fahad >> >> >> On Wed, May 9, 2012 at 6:08 PM, David Goulet wrote: >> Hi Fahad, >> >> This is error is a bit peculiar... >> >> Can you provide the full log of the session daemon like so. >> >> (term1) # lttng-sessiond -vvv >> >> (term2) the rest of the commands adding -vvv to "lttng" command line. >> >> Thanks! David >> >> On 09/05/12 08:20 AM, Fahad Usman wrote: >>>>> Hi, I am trying to use lttng-modules on an arm target, but when I try >>>>> to start tracing I get some errors like PERROR: sendmsg: Bad file >>>>> descriptor [in lttcomm_send_unix_sock() at sessiond-comm.c:310] >>>>> PERROR: send consumer channel: Bad file descriptor [in >>>>> send_kconsumer_session_streams() at main.c:636] please see pastebin >>>>> (http://pastebin.com/ivnvQWa2) for complete logs >>>>> >>>>> I am using Linux 2.6.38 on Freescale imx6 platform. Lttng-modules >>>>> 2.0.2 and lttng-tools 2.0.1 >>>>> >>>>> -- Fahad >>>>> >>>>> _______________________________________________ lttng-dev mailing >>>>> list lttng-dev at lists.lttng.org >>>>> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev >> >> _______________________________________________ lttng-dev mailing list >> lttng-dev at lists.lttng.org >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v1.4.12 (GNU/Linux) > > iQEcBAEBAgAGBQJPq9QGAAoJEELoaioR9I02N0YH/17EdVFGWkhP+kqZJznvmv6/ > +MebU8HiguKhpqYVcGjS4xw9HAR2hn3oZGAiIQSjbaDO1rhI9xWzguj+dq2gi3B4 > 9yjk7c6mfKMs09yqMdoWkQOmCCmnlazYZpjE0iqQxMhUC84hoPB+sBZDWBfA9nOX > UD/bNkNGZOk8+vaYN+twNeB/7iNdsgISeUwaZ/5GgfJ+lCp7YAY/QaF8EVyH3DP4 > upXlyhQZoSqogmtnFJxRbhTgio/P9Z9mxwc/k5GqKypBAqI9BcXvuxwgsg6rLNMW > ixbGGzN/fPKn6lGW8Xv96YHFxTU1ZvC+TY06YFk3cV0amdOjkS8tOwZF/4A2K3g= > =Zj2o > -----END PGP SIGNATURE----- From david.goulet at polymtl.ca Fri May 11 12:24:57 2012 From: david.goulet at polymtl.ca (David Goulet) Date: Fri, 11 May 2012 12:24:57 -0400 Subject: [lttng-dev] problem starting trace on arm target In-Reply-To: References: <4FAA6C62.8000500@efficios.com> <4FABD40A.6070504@polymtl.ca> Message-ID: <4FAD3D59.2040501@polymtl.ca> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Glad you fixed the problem! It's no problem, don't hesitate to report problem you can't solve. It helps us improve usability in some case or make things more user friendly. Cheers! David On 11/05/12 07:48 AM, Fahad Usman wrote: > Hi David, Thanks for the help. lttng-consumerd binary was actually not > present at that path. I have placed it and now its working I can start > tracing without any problems. Actually I was using open embedded > (www.openembedded.org) framework to build lttng and other stuff. > lttng-consumerd binary is now moved to a path that's not very common, I had > to add a rule to explicitly include consumerd into the file system. > > The memory related problems still occur randomly, I am trying to find a > definitive way to reproduce it > > thanks for your support and sorry for making noise about something that was > not actually a problem with lttng -- Fahad > > > On Thu, May 10, 2012 at 7:43 PM, David Goulet > wrote: Hi Fahad, > > So, it seems you don't have a consumer installed on your system that the > sessiond can access: > > DEBUG3: Looking for a kernel consumer at these locations: [in > spawn_consumerd() at main.c:1678] DEBUG3: 1) [in spawn_consumerd() > at main.c:1679] DEBUG3: 2) /usr/lib/lttng/libexec/lttng-consumerd > [in spawn_consumerd() at main.c:1680] DEBUG3: 3) > /usr/lib/lttng/libexec/lttng-consumerd [in spawn_consumerd() at > main.c:1681] PERROR: kernel start consumer exec: No such file or directory > [in spawn_consumerd() at main.c:1795] > > Also I'm starting to believe that you might have a memory limit problem > since you are hitting this: > > PERROR: sendmsg: Bad file descriptor [in lttcomm_send_unix_sock() at > sessiond-comm.c:310] PERROR: send consumer channel: Bad file descriptor > [in send_kconsumer_session_streams() at main.c:636] PERROR: ioctl start > session: No buffer space available [in kernel_start_session() at > kernel.c:397] > > Because of that, the kernel start session command on the tracer fails... > Can you validate that you have enough memory during the commands ? > > Moving the lttng-consumerd at the right location will at least help a bit > :) > > Thanks! David > > On 09/05/12 11:30 AM, Fahad Usman wrote: >>>> Hi David, here are the logs on the two terminals, Term1: >>>> http://pastebin.com/dYGCrGcb Term2: http://pastebin.com/4XCn4Asv >>>> >>>> Please let me know if you want any other info from me. >>>> >>>> -- Fahad >>>> >>>> >>>> On Wed, May 9, 2012 at 6:08 PM, David Goulet >>>> wrote: Hi Fahad, >>>> >>>> This is error is a bit peculiar... >>>> >>>> Can you provide the full log of the session daemon like so. >>>> >>>> (term1) # lttng-sessiond -vvv >>>> >>>> (term2) the rest of the commands adding -vvv to "lttng" command >>>> line. >>>> >>>> Thanks! David >>>> >>>> On 09/05/12 08:20 AM, Fahad Usman wrote: >>>>>>> Hi, I am trying to use lttng-modules on an arm target, but when >>>>>>> I try to start tracing I get some errors like PERROR: sendmsg: >>>>>>> Bad file descriptor [in lttcomm_send_unix_sock() at >>>>>>> sessiond-comm.c:310] PERROR: send consumer channel: Bad file >>>>>>> descriptor [in send_kconsumer_session_streams() at main.c:636] >>>>>>> please see pastebin (http://pastebin.com/ivnvQWa2) for complete >>>>>>> logs >>>>>>> >>>>>>> I am using Linux 2.6.38 on Freescale imx6 platform. >>>>>>> Lttng-modules 2.0.2 and lttng-tools 2.0.1 >>>>>>> >>>>>>> -- Fahad >>>>>>> >>>>>>> _______________________________________________ lttng-dev >>>>>>> mailing list lttng-dev at lists.lttng.org >>>>>>> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev >>>> >>>> _______________________________________________ lttng-dev mailing >>>> list lttng-dev at lists.lttng.org >>>> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQEcBAEBAgAGBQJPrT1ZAAoJEELoaioR9I022fgH/R75RcC57BA0NwXGGEBY4Run 2CwGpeEw9gb6lSSr6rM9Z/HBmsbQ71J0ecOWohg9fZ3xb+vDcT8csVB0Lnlb1+Pr wSVLQpT3OALrLQJmQPt3ucAqpTQaILoU4h8JjKKhuzfXQbKl/bpPzZ1NLmLLYAWF ODahqK5k/Nikm4G+MsFu9+5K6cBmlDTu6qcXIBoxfSWCzJEcFpjz7MAno78bXS34 ymFwnUKbwbYuZCWK/rR+TtknWC9KeXMylheLrb5QNtEEkiSafeZnZO+uOJirLrR3 /xhaKj0gvNylGKaZvxyD6+VaPH/2GmAzupiwbTWHUxSXywjh/z82ZRm6DdJxeHU= =zLWd -----END PGP SIGNATURE----- From ettore at ettoredelnegro.me Fri May 11 22:32:18 2012 From: ettore at ettoredelnegro.me (Ettore Del Negro) Date: Sat, 12 May 2012 04:32:18 +0200 Subject: [lttng-dev] UST lttng enable-event output improvement In-Reply-To: <4FABD4BD.40205@polymtl.ca> References: <4FAB112B.9040801@ettoredelnegro.me> <4FABD4BD.40205@polymtl.ca> Message-ID: <4FADCBB2.2080609@ettoredelnegro.me> https://bugs.lttng.org/issues/228 https://bugs.lttng.org/issues/235 The attached patch should do it. Ettore On 10/5/2012 4:46 PM, David Goulet wrote: > Hey, > > We have right now an opened bug about this exact issue. We will soon fix this > and, as you said, help considerably the user experience with subbuffer size :) > > Thanks for the report! > > Cheers > David > > On 09/05/12 08:51 PM, Ettore Del Negro wrote: >> Hello, i have a simple question which may lead to a small user experience >> improvement: > >>> lttng create tsession >> Session tsession created. Traces will be written in >> .../lttng-traces/tsession-20120510-015819 >>> lttng enable-channel tchan -u -s tsession --subbuf-size=1024 >> UST channel tchan enabled for session tsession > >> a message stating that buffer size is set to a value different than default >> would be nice > >>> lttng enable-channel tchan -u -s tsession --subbuf-size=1022 >> UST channel tchan enabled for session tsession > >> What happens? Is it set to a value not power of 2? Is it set to the default >> value? (i guess the latter). The help says: --subbuf-size SIZE Subbuffer >> size in bytes (default: 4096, kernel default: 262144) Needs to be a power >> of 2 for kernel and ust tracers > >> Thanks, Ettore > >> _______________________________________________ lttng-dev mailing list >> lttng-dev at lists.lttng.org >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -------------- next part -------------- diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index f621fa8..7d83119 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -236,7 +236,7 @@ struct lttng_event { #define LTTNG_CHANNEL_ATTR_PADDING1 LTTNG_SYMBOL_NAME_LEN + 32 struct lttng_channel_attr { int overwrite; /* 1: overwrite, 0: discard */ - uint64_t subbuf_size; /* bytes */ + uint64_t subbuf_size; /* bytes, power of 2 */ uint64_t num_subbuf; /* power of 2 */ unsigned int switch_timer_interval; /* usec */ unsigned int read_timer_interval; /* usec */ diff --git a/src/bin/lttng/commands/enable_channels.c b/src/bin/lttng/commands/enable_channels.c index 9b5f8d6..4d3eb15 100644 --- a/src/bin/lttng/commands/enable_channels.c +++ b/src/bin/lttng/commands/enable_channels.c @@ -68,8 +68,8 @@ static struct poptOption long_options[] = { #endif {"discard", 0, POPT_ARG_NONE, 0, OPT_DISCARD, 0, 0}, {"overwrite", 0, POPT_ARG_NONE, 0, OPT_OVERWRITE, 0, 0}, - {"subbuf-size", 0, POPT_ARG_DOUBLE, 0, OPT_SUBBUF_SIZE, 0, 0}, - {"num-subbuf", 0, POPT_ARG_INT, 0, OPT_NUM_SUBBUF, 0, 0}, + {"subbuf-size", 0, POPT_ARG_STRING, 0, OPT_SUBBUF_SIZE, 0, 0}, + {"num-subbuf", 0, POPT_ARG_STRING, 0, OPT_NUM_SUBBUF, 0, 0}, {"switch-timer", 0, POPT_ARG_INT, 0, OPT_SWITCH_TIMER, 0, 0}, {"read-timer", 0, POPT_ARG_INT, 0, OPT_READ_TIMER, 0, 0}, {"list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL}, @@ -106,12 +106,14 @@ static void usage(FILE *ofp) DEFAULT_CHANNEL_SUBBUF_SIZE, DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE); fprintf(ofp, " Needs to be a power of 2 for\n"); - fprintf(ofp, " kernel and ust tracers\n"); + fprintf(ofp, " kernel and ust tracers.\n"); + fprintf(ofp, " Hex values allowed using 0x prefix\n"); fprintf(ofp, " --num-subbuf NUM Number of subbufers\n"); fprintf(ofp, " (default: %u)\n", DEFAULT_CHANNEL_SUBBUF_NUM); fprintf(ofp, " Needs to be a power of 2 for\n"); - fprintf(ofp, " kernel and ust tracers\n"); + fprintf(ofp, " kernel and ust tracers.\n"); + fprintf(ofp, " Hex values allowed using 0x prefix\n"); fprintf(ofp, " --switch-timer USEC Switch timer interval in usec (default: %u)\n", DEFAULT_CHANNEL_SWITCH_TIMER); fprintf(ofp, " --read-timer USEC Read timer interval in usec (default: %u)\n", @@ -245,6 +247,8 @@ int cmd_enable_channels(int argc, const char **argv) int opt, ret = CMD_SUCCESS; static poptContext pc; char *session_name = NULL; + uint64_t lvalue; + char *argstr, *endptr; init_channel_config(); @@ -265,13 +269,111 @@ int cmd_enable_channels(int argc, const char **argv) DBG("Channel set to overwrite"); break; case OPT_SUBBUF_SIZE: - /* TODO Replace atol with strtol and check for errors */ - chan.attr.subbuf_size = atol(poptGetOptArg(pc)); - DBG("Channel subbuf size set to %" PRIu64, chan.attr.subbuf_size); + argstr = poptGetOptArg(pc); + errno = 0; + lvalue = (uint64_t) strtoll(argstr, &endptr, 0); /* Allow hex or octal values */ + if (errno != 0) + { + ERR("Invalid channel subbuf size: %s", strerror(errno)); + usage(stderr); + ret = CMD_ERROR; + goto end; + } + else if (lvalue == 0 && argstr == endptr) + { + ERR("Invalid channel subbuf size: not a number"); + usage(stderr); + ret = CMD_ERROR; + goto end; + } + /* Human friendly imput */ + if (endptr != NULL && *endptr != '\0') + { + switch (*endptr) { + case 'k': + case 'K': + lvalue *= 1024; + break; + case 'm': + case 'M': + lvalue *= 1024*1024; + break; + case 'g': + case 'G': + lvalue *= 1024*1024*1024; + break; + case 't': + case 'T': + lvalue *= 1024*1024*1024*1024; + break; + } + } + /* + * Not power of 2 + * http://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2 + */ + if (!(lvalue && !(lvalue & (lvalue-1)))) + { + /* Round up to power of 2 */ + lvalue--; + lvalue |= lvalue >> 1; lvalue |= lvalue >> 2; lvalue |= lvalue >> 4; + lvalue |= lvalue >> 8; lvalue |= lvalue >> 16; lvalue |= lvalue >> 32; + lvalue++; + /* and tell the user about it */ + MSG("Setting channel subbuf size to %"PRIu64" bytes", lvalue); + } + chan.attr.subbuf_size = lvalue; + DBG("Setting channel subbuf size to %" PRIu64, chan.attr.subbuf_size); break; case OPT_NUM_SUBBUF: - /* TODO Replace atoi with strtol and check for errors */ - chan.attr.num_subbuf = atoi(poptGetOptArg(pc)); + argstr = poptGetOptArg(pc); + errno = 0; + lvalue = (uint64_t) strtoll(argstr, &endptr, 0); /* Allow hex or octal values */ + if (errno != 0) + { + ERR("Invalid channel subbuf number: %s", strerror(errno)); + usage(stderr); + ret = CMD_ERROR; + goto end; + } + else if (lvalue == 0 && argstr == endptr) + { + ERR("Invalid channel subbuf number: not a number"); + usage(stderr); + ret = CMD_ERROR; + goto end; + } + if (endptr != NULL && *endptr != '\0') + { + switch (*endptr) { + case 'k': + case 'K': + lvalue *= 1024; + break; + case 'm': + case 'M': + lvalue *= 1024*1024; + break; + case 'g': + case 'G': + lvalue *= 1024*1024*1024; + break; + case 't': + case 'T': + lvalue *= 1024*1024*1024*1024; + break; + } + } + if (!(lvalue && !(lvalue & (lvalue-1)))) + { + lvalue--; + lvalue |= lvalue >> 1; lvalue |= lvalue >> 2; lvalue |= lvalue >> 4; + lvalue |= lvalue >> 8; lvalue |= lvalue >> 16; lvalue |= lvalue >> 32; + lvalue++; + /* and tell the user about it */ + MSG("Setting channel subbuf number to %" PRIu64, lvalue); + } + chan.attr.num_subbuf = lvalue; DBG("Channel subbuf num set to %" PRIu64, chan.attr.num_subbuf); break; case OPT_SWITCH_TIMER: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 945 bytes Desc: OpenPGP digital signature URL: From mathieu.desnoyers at efficios.com Sat May 12 12:04:02 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sat, 12 May 2012 12:04:02 -0400 Subject: [lttng-dev] Early Registration for Linux Plumbers Conference ends May 15th Message-ID: <20120512160402.GA6227@Krystal> Hi! A few words to let you know that for those who would like to attend Linux Plumbers Conference 2012 (www.linuxplumbersconf.org/2012/attend), co-located in San Diego with LinuxCon North America 2012, the 300$ discounded registration fee ends on May 15th (students don't have to worry so much, as their entrance fee is 100$). I will be co-leading the Scaling microconference with Paul E. McKenney at this conference, so it will be worth it !! ;-) Best regards, Mathieu -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From toojays at toojays.net Sun May 13 22:10:14 2012 From: toojays at toojays.net (John Steele Scott) Date: Mon, 14 May 2012 11:40:14 +0930 Subject: [lttng-dev] LTTng on RHEL 6 or Centos 6? Message-ID: <4FB06986.3080402@toojays.net> I'd like to do some analysis on a Centos 6.2 system.* At I found an old article where Yannick says support for a patched 2.6.32 kernel would go into lttng-modules. Did this happen at any stage? A quick search in git didn't find answers. Is there any more recent status on this front? Otherwise, does anyone know if any of the "old" patches at will apply on the RHEL/Centos 6 kernel? *: (Actually the system under examination is running some hacked up Centos 5.4 / 2.6.18 kernel, but I may be able to run experiments on a newer system and extrapolate my results.) Thanks, John From michael at tonian.com Mon May 14 11:32:35 2012 From: michael at tonian.com (Michael Livshin) Date: Mon, 14 May 2012 18:32:35 +0300 Subject: [lttng-dev] Out-of-tree build fixes Message-ID: Hi all, the (hopefully) attached 2 patches fix out-of-tree building of lttng-ust and lttng-tools for me. Thanks, --m -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: lttng-tools-oot-build.diff Type: application/octet-stream Size: 4994 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: lttng-ust-oot-build.diff Type: application/octet-stream Size: 4578 bytes Desc: not available URL: From mathieu.desnoyers at efficios.com Mon May 14 22:39:01 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 14 May 2012 22:39:01 -0400 Subject: [lttng-dev] [RFC PATCH urcu] Document uatomic operations Message-ID: <20120515023901.GA22786@Krystal> Document each atomic operation provided by urcu/uatomic.h, along with their memory barrier guarantees. Signed-off-by: Mathieu Desnoyers --- diff --git a/doc/Makefile.am b/doc/Makefile.am index bec1d7c..db9811c 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1 +1 @@ -dist_doc_DATA = rcu-api.txt +dist_doc_DATA = rcu-api.txt uatomic-api.txt diff --git a/doc/uatomic-api.txt b/doc/uatomic-api.txt new file mode 100644 index 0000000..3605acf --- /dev/null +++ b/doc/uatomic-api.txt @@ -0,0 +1,80 @@ +Userspace RCU Atomic Operations API +by Mathieu Desnoyers and Paul E. McKenney + + +This document describes the API. Those are the atomic +operations provided by the Userspace RCU library. The general rule +regarding memory barriers is that only uatomic_xchg(), +uatomic_cmpxchg(), uatomic_add_return(), and uatomic_sub_return() imply +full memory barriers before and after the atomic operation. Other +primitives don't guarantee any memory barrier. + +Only atomic operations performed on integers ("int" and "long", signed +and unsigned) are supported on all architectures. Some architectures +also support 1-byte and 2-byte atomic operations. Those respectively +have UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT defined when +uatomic.h is included. An architecture trying to perform an atomic write +to a type size not supported by the architecture will trigger an illegal +instruction. + +In the description below, "type" is a type that can be atomically +written to by the architecture. It needs to be at most word-sized, and +its alignment needs to greater or equal to its size. + +type uatomic_set(type *addr, type v) + + Atomically write @v into @addr. + +type uatomic_read(type *addr) + + Atomically read @v from @addr. + +type uatomic_cmpxchg(type *addr, type old, type new) + + Atomically check if @addr contains @old. If true, then replace + the content of @addr by @new. Return the value previously + contained by @addr. This function imply a full memory barrier + before and after the atomic operation. + +type uatomic_xchg(type *addr, type new) + + Atomically replace the content of @addr by @new, and return the + value previously contained by @addr. This function imply a full + memory barrier before and after the atomic operation. + +type uatomic_add_return(type *addr, type v) +type uatomic_sub_return(type *addr, type v) + + Atomically increment/decrement the content of @addr by @v, and + return the resulting value. This function imply a full memory + barrier before and after the atomic operation. + +void uatomic_and(type *addr, type mask) +void uatomic_or(type *addr, type mask) + + Atomically write the result of bitwise "and"/"or" between the + content of @addr and @mask into @addr. Memory barriers are + provided by explicitly using cmm_smp_mb__before_uatomic_and(), + cmm_smp_mb__after_uatomic_and(), + cmm_smp_mb__before_uatomic_or(), and + cmm_smp_mb__after_uatomic_or(). + +void uatomic_add(type *addr, type v) +void uatomic_sub(type *addr, type v) + + Atomically increment/decrement the content of @addr by @v. + Memory barriers are provided by explicitly using + cmm_smp_mb__before_uatomic_add(), + cmm_smp_mb__after_uatomic_add(), + cmm_smp_mb__before_uatomic_sub(), and + cmm_smp_mb__after_uatomic_sub(). + +void uatomic_inc(type *addr) +void uatomic_dec(type *addr) + + Atomically increment/decrement the content of @addr by 1. Memory + barriers are provided by explicitly using + cmm_smp_mb__before_uatomic_inc(), + cmm_smp_mb__after_uatomic_inc(), + cmm_smp_mb__before_uatomic_dec(), and + cmm_smp_mb__after_uatomic_dec(). -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon May 14 23:36:04 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 14 May 2012 23:36:04 -0400 Subject: [lttng-dev] [RFC PATCH urcu] document concurrent data structures Message-ID: <20120515033604.GA23692@Krystal> Document the concurrent data structures provided by the userspace RCU library. Signed-off-by: Mathieu Desnoyers --- diff --git a/doc/cds-api.txt b/doc/cds-api.txt new file mode 100644 index 0000000..7a3c6e0 --- /dev/null +++ b/doc/cds-api.txt @@ -0,0 +1,59 @@ +Userspace RCU Concurrent Data Structures (CDS) API +by Mathieu Desnoyers and Paul E. McKenney + + +This document describes briefly the data structures contained with the +userspace RCU library. + +urcu/list.h: + + Doubly-linked list, which requires mutual exclusion on updates + and reads. + +urcu/rculist.h: + + Doubly-linked list, which requires mutual exclusion on updates, + allows RCU read traversals. + +urcu/hlist.h: + + Doubly-linked list, with single pointer list head. Requires + mutual exclusion on updates and reads. Useful for implementing + hash tables. Downside over list.h: lookup of tail in O(n). + +urcu/rcuhlist.h: + + Doubly-linked list, with single pointer list head. Requires + mutual exclusion on updates, allows RCU read traversals. Useful + for implementing hash tables. Downside over rculist.h: lookup of + tail in O(n). + +urcu/rculfqueue.h: + + RCU queue with lock-free enqueue, lock-free dequeue. RCU used to + provide existance guarantees. + +urcu/wfqueue.h: + + Queue with wait-free enqueue, blocking dequeue. This queue does + _not_ use RCU. + +urcu/rculfstack.h: + + RCU stack with lock-free push, lock-free dequeue. RCU used to + provide existance guarantees. + +urcu/wfstack.h: + + Stack with wait-free enqueue, blocking dequeue. This stack does + _not_ use RCU. + +urcu/rculfhash.h: + + Lock-Free Resizable RCU Hash Table. RCU used to provide + existance guarantees. Provides scalable updates, and scalable + RCU read-side lookups and traversals. Unique and duplicate keys + are supported. Provides "uniquify add" and "replace add" + operations, along with associated read-side traversal uniqueness + guarantees. Automatic hash table resize based on number of + elements is supported. See the API for more details. -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From paulmck at linux.vnet.ibm.com Tue May 15 00:09:36 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Mon, 14 May 2012 21:09:36 -0700 Subject: [lttng-dev] [RFC PATCH urcu] Document uatomic operations In-Reply-To: <20120515023901.GA22786@Krystal> References: <20120515023901.GA22786@Krystal> Message-ID: <20120515040936.GB2412@linux.vnet.ibm.com> On Mon, May 14, 2012 at 10:39:01PM -0400, Mathieu Desnoyers wrote: > Document each atomic operation provided by urcu/uatomic.h, along with > their memory barrier guarantees. Great to see the documentation!!! Some comments below. Thanx, Paul > Signed-off-by: Mathieu Desnoyers > --- > diff --git a/doc/Makefile.am b/doc/Makefile.am > index bec1d7c..db9811c 100644 > --- a/doc/Makefile.am > +++ b/doc/Makefile.am > @@ -1 +1 @@ > -dist_doc_DATA = rcu-api.txt > +dist_doc_DATA = rcu-api.txt uatomic-api.txt > diff --git a/doc/uatomic-api.txt b/doc/uatomic-api.txt > new file mode 100644 > index 0000000..3605acf > --- /dev/null > +++ b/doc/uatomic-api.txt > @@ -0,0 +1,80 @@ > +Userspace RCU Atomic Operations API > +by Mathieu Desnoyers and Paul E. McKenney > + > + > +This document describes the API. Those are the atomic > +operations provided by the Userspace RCU library. The general rule > +regarding memory barriers is that only uatomic_xchg(), > +uatomic_cmpxchg(), uatomic_add_return(), and uatomic_sub_return() imply > +full memory barriers before and after the atomic operation. Other > +primitives don't guarantee any memory barrier. > + > +Only atomic operations performed on integers ("int" and "long", signed > +and unsigned) are supported on all architectures. Some architectures > +also support 1-byte and 2-byte atomic operations. Those respectively > +have UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT defined when > +uatomic.h is included. An architecture trying to perform an atomic write > +to a type size not supported by the architecture will trigger an illegal > +instruction. > + > +In the description below, "type" is a type that can be atomically > +written to by the architecture. It needs to be at most word-sized, and > +its alignment needs to greater or equal to its size. > + > +type uatomic_set(type *addr, type v) > + > + Atomically write @v into @addr. Wouldn't this instead be "void uatomic_set(type *addr, type v)"? By "Atomically write @v into @addr", what is meant is that no concurrent operation that reads from addr will see partial effects of uatomic_set(), correct? In other words, the concurrent read will either see v or the old value, not a mush of the two. > + > +type uatomic_read(type *addr) > + > + Atomically read @v from @addr. Similar comments on the meaning of "atomically". This may sound picky, but people coming from an x86 environment might otherwise assume that there is lock prefix involved... > + > +type uatomic_cmpxchg(type *addr, type old, type new) > + > + Atomically check if @addr contains @old. If true, then replace > + the content of @addr by @new. Return the value previously > + contained by @addr. This function imply a full memory barrier > + before and after the atomic operation. Suggest "then atomically replace" or some such. It might not hurt to add that this is an atomic read-modify-write operation. Similar comments on the other value-returning atomics. > + > +type uatomic_xchg(type *addr, type new) > + > + Atomically replace the content of @addr by @new, and return the > + value previously contained by @addr. This function imply a full > + memory barrier before and after the atomic operation. > + > +type uatomic_add_return(type *addr, type v) > +type uatomic_sub_return(type *addr, type v) > + > + Atomically increment/decrement the content of @addr by @v, and > + return the resulting value. This function imply a full memory > + barrier before and after the atomic operation. > + > +void uatomic_and(type *addr, type mask) > +void uatomic_or(type *addr, type mask) > + > + Atomically write the result of bitwise "and"/"or" between the > + content of @addr and @mask into @addr. Memory barriers are > + provided by explicitly using cmm_smp_mb__before_uatomic_and(), > + cmm_smp_mb__after_uatomic_and(), > + cmm_smp_mb__before_uatomic_or(), and > + cmm_smp_mb__after_uatomic_or(). I suggest replacing "Memory barriers are provided ..." with something like "These operations do not necessarily imply memory barriers. If memory barriers are needed, they may be provided ...". Then perhaps add a sentence stating that the advantage of using the four __before_/__after_ primitives is that they are no-ops on architectures in which the underlying atomic instructions implicitly supply the needed memory barriers. Simlar comments on the other non-value-returning atomic operations below. > + > +void uatomic_add(type *addr, type v) > +void uatomic_sub(type *addr, type v) > + > + Atomically increment/decrement the content of @addr by @v. > + Memory barriers are provided by explicitly using > + cmm_smp_mb__before_uatomic_add(), > + cmm_smp_mb__after_uatomic_add(), > + cmm_smp_mb__before_uatomic_sub(), and > + cmm_smp_mb__after_uatomic_sub(). > + > +void uatomic_inc(type *addr) > +void uatomic_dec(type *addr) > + > + Atomically increment/decrement the content of @addr by 1. Memory > + barriers are provided by explicitly using > + cmm_smp_mb__before_uatomic_inc(), > + cmm_smp_mb__after_uatomic_inc(), > + cmm_smp_mb__before_uatomic_dec(), and > + cmm_smp_mb__after_uatomic_dec(). > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > From paulmck at linux.vnet.ibm.com Tue May 15 00:12:38 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Mon, 14 May 2012 21:12:38 -0700 Subject: [lttng-dev] [rp] [RFC PATCH urcu] document concurrent data structures In-Reply-To: <20120515033604.GA23692@Krystal> References: <20120515033604.GA23692@Krystal> Message-ID: <20120515041238.GD2412@linux.vnet.ibm.com> On Mon, May 14, 2012 at 11:36:04PM -0400, Mathieu Desnoyers wrote: > Document the concurrent data structures provided by the userspace RCU > library. Looks good to me! Reviewed-by: Paul E. McKenney > Signed-off-by: Mathieu Desnoyers > --- > diff --git a/doc/cds-api.txt b/doc/cds-api.txt > new file mode 100644 > index 0000000..7a3c6e0 > --- /dev/null > +++ b/doc/cds-api.txt > @@ -0,0 +1,59 @@ > +Userspace RCU Concurrent Data Structures (CDS) API > +by Mathieu Desnoyers and Paul E. McKenney > + > + > +This document describes briefly the data structures contained with the > +userspace RCU library. > + > +urcu/list.h: > + > + Doubly-linked list, which requires mutual exclusion on updates > + and reads. > + > +urcu/rculist.h: > + > + Doubly-linked list, which requires mutual exclusion on updates, > + allows RCU read traversals. > + > +urcu/hlist.h: > + > + Doubly-linked list, with single pointer list head. Requires > + mutual exclusion on updates and reads. Useful for implementing > + hash tables. Downside over list.h: lookup of tail in O(n). > + > +urcu/rcuhlist.h: > + > + Doubly-linked list, with single pointer list head. Requires > + mutual exclusion on updates, allows RCU read traversals. Useful > + for implementing hash tables. Downside over rculist.h: lookup of > + tail in O(n). > + > +urcu/rculfqueue.h: > + > + RCU queue with lock-free enqueue, lock-free dequeue. RCU used to > + provide existance guarantees. > + > +urcu/wfqueue.h: > + > + Queue with wait-free enqueue, blocking dequeue. This queue does > + _not_ use RCU. > + > +urcu/rculfstack.h: > + > + RCU stack with lock-free push, lock-free dequeue. RCU used to > + provide existance guarantees. > + > +urcu/wfstack.h: > + > + Stack with wait-free enqueue, blocking dequeue. This stack does > + _not_ use RCU. > + > +urcu/rculfhash.h: > + > + Lock-Free Resizable RCU Hash Table. RCU used to provide > + existance guarantees. Provides scalable updates, and scalable > + RCU read-side lookups and traversals. Unique and duplicate keys > + are supported. Provides "uniquify add" and "replace add" > + operations, along with associated read-side traversal uniqueness > + guarantees. Automatic hash table resize based on number of > + elements is supported. See the API for more details. > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > rp mailing list > rp at svcs.cs.pdx.edu > http://svcs.cs.pdx.edu/mailman/listinfo/rp > From Constantine.Antonovich at emc.com Tue May 15 03:21:31 2012 From: Constantine.Antonovich at emc.com (Constantine.Antonovich at emc.com) Date: Tue, 15 May 2012 03:21:31 -0400 Subject: [lttng-dev] [ltt-dev] ust-0.12: relocation R_X86_64_PC32 against `__start Message-ID: Hello, Jan, I am wondering, have you found a solution to this problem? For a number of reasons, I need to compile ust-0.16 on RHEL 5.7 (I cannot move to newer versions), and I face the same problem. I would truly appreciate your assistance in this matter. Regards, Constantine Antonovich. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mathieu.desnoyers at efficios.com Tue May 15 08:10:03 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 15 May 2012 08:10:03 -0400 Subject: [lttng-dev] [RFC PATCH urcu] Document uatomic operations In-Reply-To: <20120515040936.GB2412@linux.vnet.ibm.com> References: <20120515023901.GA22786@Krystal> <20120515040936.GB2412@linux.vnet.ibm.com> Message-ID: <20120515121003.GA31468@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > On Mon, May 14, 2012 at 10:39:01PM -0400, Mathieu Desnoyers wrote: > > Document each atomic operation provided by urcu/uatomic.h, along with > > their memory barrier guarantees. > > Great to see the documentation!!! Some comments below. > > Thanx, Paul > > > Signed-off-by: Mathieu Desnoyers > > --- > > diff --git a/doc/Makefile.am b/doc/Makefile.am > > index bec1d7c..db9811c 100644 > > --- a/doc/Makefile.am > > +++ b/doc/Makefile.am > > @@ -1 +1 @@ > > -dist_doc_DATA = rcu-api.txt > > +dist_doc_DATA = rcu-api.txt uatomic-api.txt > > diff --git a/doc/uatomic-api.txt b/doc/uatomic-api.txt > > new file mode 100644 > > index 0000000..3605acf > > --- /dev/null > > +++ b/doc/uatomic-api.txt > > @@ -0,0 +1,80 @@ > > +Userspace RCU Atomic Operations API > > +by Mathieu Desnoyers and Paul E. McKenney > > + > > + > > +This document describes the API. Those are the atomic > > +operations provided by the Userspace RCU library. The general rule > > +regarding memory barriers is that only uatomic_xchg(), > > +uatomic_cmpxchg(), uatomic_add_return(), and uatomic_sub_return() imply > > +full memory barriers before and after the atomic operation. Other > > +primitives don't guarantee any memory barrier. > > + > > +Only atomic operations performed on integers ("int" and "long", signed > > +and unsigned) are supported on all architectures. Some architectures > > +also support 1-byte and 2-byte atomic operations. Those respectively > > +have UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT defined when > > +uatomic.h is included. An architecture trying to perform an atomic write > > +to a type size not supported by the architecture will trigger an illegal > > +instruction. > > + > > +In the description below, "type" is a type that can be atomically > > +written to by the architecture. It needs to be at most word-sized, and > > +its alignment needs to greater or equal to its size. > > + > > +type uatomic_set(type *addr, type v) > > + > > + Atomically write @v into @addr. > > Wouldn't this instead be "void uatomic_set(type *addr, type v)"? Well, in that case, we'd need to change the macro. Currently, _uatomic_set maps directly to: #define _uatomic_set(addr, v) CMM_STORE_SHARED(*(addr), (v)) and CMM_STORE_SHARED returns v. The question becomes: should we change _uatomic_set or CMM_STORE_SHARED so they don't return anything, or document that they return something ? One thing I noticed is that linters often complain that the return value of CMM_STORE_SHARED is never used. One thing we could look into is to try some gcc attributes and/or linter annotations to flag this return value as possibly unused. Thoughts ? > > By "Atomically write @v into @addr", what is meant is that no concurrent > operation that reads from addr will see partial effects of uatomic_set(), > correct? In other words, the concurrent read will either see v or > the old value, not a mush of the two. yep. I added that clarification. > > > + > > +type uatomic_read(type *addr) > > + > > + Atomically read @v from @addr. > > Similar comments on the meaning of "atomically". This may sound picky, > but people coming from an x86 environment might otherwise assume that > there is lock prefix involved... same. > > > + > > +type uatomic_cmpxchg(type *addr, type old, type new) > > + > > + Atomically check if @addr contains @old. If true, then replace > > + the content of @addr by @new. Return the value previously > > + contained by @addr. This function imply a full memory barrier > > + before and after the atomic operation. > > Suggest "then atomically replace" or some such. It might not hurt > to add that this is an atomic read-modify-write operation. Updated to: type uatomic_cmpxchg(type *addr, type old, type new) An atomic read-modify-write operation that performs this sequence of operations atomically: check if @addr contains @old. If true, then replace the content of @addr by @new. Return the value previously contained by @addr. This function imply a full memory barrier before and after the atomic operation. > > Similar comments on the other value-returning atomics. Will do something similar. > > > + > > +type uatomic_xchg(type *addr, type new) > > + > > + Atomically replace the content of @addr by @new, and return the > > + value previously contained by @addr. This function imply a full > > + memory barrier before and after the atomic operation. > > + > > +type uatomic_add_return(type *addr, type v) > > +type uatomic_sub_return(type *addr, type v) > > + > > + Atomically increment/decrement the content of @addr by @v, and > > + return the resulting value. This function imply a full memory > > + barrier before and after the atomic operation. > > + > > +void uatomic_and(type *addr, type mask) > > +void uatomic_or(type *addr, type mask) > > + > > + Atomically write the result of bitwise "and"/"or" between the > > + content of @addr and @mask into @addr. Memory barriers are > > + provided by explicitly using cmm_smp_mb__before_uatomic_and(), > > + cmm_smp_mb__after_uatomic_and(), > > + cmm_smp_mb__before_uatomic_or(), and > > + cmm_smp_mb__after_uatomic_or(). > > I suggest replacing "Memory barriers are provided ..." with something like > "These operations do not necessarily imply memory barriers. If memory > barriers are needed, they may be provided ...". Then perhaps add a > sentence stating that the advantage of using the four __before_/__after_ > primitives is that they are no-ops on architectures in which the underlying > atomic instructions implicitly supply the needed memory barriers. > > Simlar comments on the other non-value-returning atomic operations below. OK, done. Here is the update: diff --git a/doc/Makefile.am b/doc/Makefile.am index 27d3793..3422653 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1 +1 @@ -dist_doc_DATA = rcu-api.txt cds-api.txt +dist_doc_DATA = rcu-api.txt cds-api.txt uatomic-api.txt diff --git a/doc/uatomic-api.txt b/doc/uatomic-api.txt new file mode 100644 index 0000000..3ad8fbb --- /dev/null +++ b/doc/uatomic-api.txt @@ -0,0 +1,102 @@ +Userspace RCU Atomic Operations API +by Mathieu Desnoyers and Paul E. McKenney + + +This document describes the API. Those are the atomic +operations provided by the Userspace RCU library. The general rule +regarding memory barriers is that only uatomic_xchg(), +uatomic_cmpxchg(), uatomic_add_return(), and uatomic_sub_return() imply +full memory barriers before and after the atomic operation. Other +primitives don't guarantee any memory barrier. + +Only atomic operations performed on integers ("int" and "long", signed +and unsigned) are supported on all architectures. Some architectures +also support 1-byte and 2-byte atomic operations. Those respectively +have UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT defined when +uatomic.h is included. An architecture trying to perform an atomic write +to a type size not supported by the architecture will trigger an illegal +instruction. + +In the description below, "type" is a type that can be atomically +written to by the architecture. It needs to be at most word-sized, and +its alignment needs to greater or equal to its size. + +type uatomic_set(type *addr, type v) + + Atomically write @v into @addr. By "atomically", we mean that no + concurrent operation that reads from addr will see partial + effects of uatomic_set(). + +type uatomic_read(type *addr) + + Atomically read @v from @addr. By "atomically", we mean that + uatomic_read() cannot see a partial effect of any concurrent + uatomic update. + +type uatomic_cmpxchg(type *addr, type old, type new) + + An atomic read-modify-write operation that performs this + sequence of operations atomically: check if @addr contains @old. + If true, then replace the content of @addr by @new. Return the + value previously contained by @addr. This function imply a full + memory barrier before and after the atomic operation. + +type uatomic_xchg(type *addr, type new) + + An atomic read-modify-write operation that performs this sequence + of operations atomically: replace the content of @addr by @new, + and return the value previously contained by @addr. This + function imply a full memory barrier before and after the atomic + operation. + +type uatomic_add_return(type *addr, type v) +type uatomic_sub_return(type *addr, type v) + + An atomic read-modify-write operation that performs this + sequence of operations atomically: increment/decrement the + content of @addr by @v, and return the resulting value. This + function imply a full memory barrier before and after the atomic + operation. + +void uatomic_and(type *addr, type mask) +void uatomic_or(type *addr, type mask) + + Atomically write the result of bitwise "and"/"or" between the + content of @addr and @mask into @addr. + These operations do not necessarily imply memory barriers. + If memory barriers are needed, they may be provided by + explicitly using + cmm_smp_mb__before_uatomic_and(), + cmm_smp_mb__after_uatomic_and(), + cmm_smp_mb__before_uatomic_or(), and + cmm_smp_mb__after_uatomic_or(). These explicit barriers are + np-ops on architectures in which the underlying atomic + instructions implicitly supply the needed memory barriers. + +void uatomic_add(type *addr, type v) +void uatomic_sub(type *addr, type v) + + Atomically increment/decrement the content of @addr by @v. + These operations do not necessarily imply memory barriers. + If memory barriers are needed, they may be provided by + explicitly using + cmm_smp_mb__before_uatomic_add(), + cmm_smp_mb__after_uatomic_add(), + cmm_smp_mb__before_uatomic_sub(), and + cmm_smp_mb__after_uatomic_sub(). These explicit barriers are + np-ops on architectures in which the underlying atomic + instructions implicitly supply the needed memory barriers. + +void uatomic_inc(type *addr) +void uatomic_dec(type *addr) + + Atomically increment/decrement the content of @addr by 1. + These operations do not necessarily imply memory barriers. + If memory barriers are needed, they may be provided by + explicitly using + cmm_smp_mb__before_uatomic_inc(), + cmm_smp_mb__after_uatomic_inc(), + cmm_smp_mb__before_uatomic_dec(), and + cmm_smp_mb__after_uatomic_dec(). These explicit barriers are + np-ops on architectures in which the underlying atomic + instructions implicitly supply the needed memory barriers. -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Tue May 15 19:48:26 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 15 May 2012 19:48:26 -0400 Subject: [lttng-dev] [CFP] Tracing Micro-conference at LPC2012 (August 28-30, San Diego) Message-ID: <20120515234826.GA10967@Krystal> Hi, We are organizing a tracing micro-conference taking place in San Diego, within Linux Plumbers Conference 2012. The micro-conference is planned to be held somewhere between August 28 and 30, in San Diego, CA. If you are interested to present, please don't hesitate to get in touch with us quickly (ideally within this week, or next week), since deadlines are approaching. Our intent is to gather people involved in development and users of tracing tools and trace analysis tools to allow discussing the latest developments, allow users to express their needs, and generally ensure that developers and end users understand each other. We are welcoming presentations from both end users and developers, on topics covering, but not limited to: - Trace collection and extraction, - Trace filtering, - Trace aggregation, - Trace formats, - Tracing multi-core systems, - Trace abstraction, - Trace modeling, - Automated trace analysis (e.g. dependency analysis), - Tracing large clusters and distributed systems, - Hardware-level tracing (e.g. DSP, GPU, bare-metal), - Trace visualisation, - Interaction between debugging and tracing, - Tracing remote control, - Analysis of large trace datasets. It can cover both recently available technologies and ongoing work. If you are interested to present, please get in touch with Dominique Toupin or myself. The micro-conference wiki can be accessed at: http://wiki.linuxplumbersconf.org/2012:tracing Feedback is welcome! Thank you, Dominique Toupin & Mathieu Desnoyers -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed May 16 09:56:01 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 16 May 2012 09:56:01 -0400 Subject: [lttng-dev] [RFC PATCH urcu] Add TLS detection m4 macro Message-ID: <20120516135601.GA29920@Krystal> Will allow urcu to support OSes that require to use pthread TLS (and do not provide __thread TLS support). Suggested-by: Marek Vavru?a Signed-off-by: Mathieu Desnoyers --- diff --git a/.gitignore b/.gitignore index 1112e43..15e9fc3 100644 --- a/.gitignore +++ b/.gitignore @@ -78,7 +78,6 @@ tests/*.log .libs/ Makefile.in Makefile -*.m4 *.la *.bz2 *.o @@ -86,7 +85,18 @@ Makefile *.loT /config.log /configure -/config/ +/config/compile +/config/config.guess +/config/config.sub +/config/depcomp +/config/install-sh +/config/libtool.m4 +/config/ltmain.sh +/config/lt~obsolete.m4 +/config/ltoptions.m4 +/config/ltsugar.m4 +/config/ltversion.m4 +/config/missing /libtool /stamp-h1 /config.h.in diff --git a/LICENSE b/LICENSE index ad13f78..eb696b2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ Userspace RCU library licensing Mathieu Desnoyers -May 10, 2009 +May 15, 2012 * LGPLv2.1 @@ -57,3 +57,9 @@ test_urcu.c test_urcu_yield.c test_rwlock_timing.c urcu-asm.c + +* GPLv3 (or later) + +The following build-related macro is under GPLv3 (or later): + +m4/ax_tls.m4 diff --git a/config/ax_tls.m4 b/config/ax_tls.m4 new file mode 100644 index 0000000..033e3b1 --- /dev/null +++ b/config/ax_tls.m4 @@ -0,0 +1,76 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_tls.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_TLS([action-if-found], [action-if-not-found]) +# +# DESCRIPTION +# +# Provides a test for the compiler support of thread local storage (TLS) +# extensions. Defines TLS if it is found. Currently knows about GCC/ICC +# and MSVC. I think SunPro uses the same as GCC, and Borland apparently +# supports either. +# +# LICENSE +# +# Copyright (c) 2008 Alan Woodland +# Copyright (c) 2010 Diego Elio Petteno` +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 10 + +AC_DEFUN([AX_TLS], [ + AC_MSG_CHECKING(for thread local storage (TLS) class) + AC_CACHE_VAL(ac_cv_tls, [ + ax_tls_keywords="__thread __declspec(thread) none" + for ax_tls_keyword in $ax_tls_keywords; do + AS_CASE([$ax_tls_keyword], + [none], [ac_cv_tls=none ; break], + [AC_TRY_COMPILE( + [#include + static void + foo(void) { + static ] $ax_tls_keyword [ int bar; + exit(1); + }], + [], + [ac_cv_tls=$ax_tls_keyword ; break], + ac_cv_tls=none + )]) + done + ]) + AC_MSG_RESULT($ac_cv_tls) + + AS_IF([test "$ac_cv_tls" != "none"], + AC_DEFINE_UNQUOTED([TLS], $ac_cv_tls, [If the compiler supports a TLS storage class define it to that here]) + m4_ifnblank([$1], [$1]), + m4_ifnblank([$2], [$2]) + ) +]) diff --git a/configure.ac b/configure.ac index 6bf1cb9..1790bb8 100644 --- a/configure.ac +++ b/configure.ac @@ -15,6 +15,8 @@ AC_CANONICAL_HOST AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +m4_include([config/ax_tls.m4]) + AC_CONFIG_SRCDIR([urcu.h]) AC_CONFIG_HEADERS([config.h urcu/config.h]) @@ -24,6 +26,9 @@ AH_TEMPLATE([CONFIG_RCU_HAVE_FENCE], [Defined when on a system that has memory f AH_TEMPLATE([CONFIG_RCU_HAVE_FUTEX], [Defined when on a system with futex support.]) AH_TEMPLATE([CONFIG_RCU_COMPAT_ARCH], [Compatibility mode for i386 which lacks cmpxchg instruction.]) AH_TEMPLATE([CONFIG_RCU_ARM_HAVE_DMB], [Use the dmb instruction if available for use on ARM.]) +AH_TEMPLATE([CONFIG_RCU_TLS], [TLS provided by the compiler.]) + +AX_TLS([AC_DEFINE_UNQUOTED([CONFIG_RCU_TLS], $ac_cv_tls)], []) # Checks for programs. AC_PROG_CC diff --git a/urcu/config.h.in b/urcu/config.h.in index 02c7b2e..de1d1d0 100644 --- a/urcu/config.h.in +++ b/urcu/config.h.in @@ -16,3 +16,6 @@ /* Use the dmb instruction is available for use on ARM. */ #undef CONFIG_RCU_ARM_HAVE_DMB + +/* TLS provided by the compiler. */ +#define CONFIG_RCU_TLS TLS -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed May 16 09:56:58 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 16 May 2012 09:56:58 -0400 Subject: [lttng-dev] [RFC PATCH urcu] Implement urcu/tls-compat.h Message-ID: <20120516135658.GB29920@Krystal> Suggested-by: Marek Vavru?a Signed-off-by: Mathieu Desnoyers --- diff --git a/Makefile.am b/Makefile.am index 0a369fd..6263057 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,7 +18,8 @@ nobase_dist_include_HEADERS = urcu/compiler.h urcu/hlist.h urcu/list.h \ urcu/ref.h urcu/cds.h urcu/urcu_ref.h urcu/urcu-futex.h \ urcu/uatomic_arch.h urcu/rculfhash.h \ $(top_srcdir)/urcu/map/*.h \ - $(top_srcdir)/urcu/static/*.h + $(top_srcdir)/urcu/static/*.h \ + urcu/tls-compat.h nobase_nodist_include_HEADERS = urcu/arch.h urcu/uatomic.h urcu/config.h EXTRA_DIST = $(top_srcdir)/urcu/arch/*.h $(top_srcdir)/urcu/uatomic/*.h \ diff --git a/urcu/tls-compat.h b/urcu/tls-compat.h new file mode 100644 index 0000000..d7c7537 --- /dev/null +++ b/urcu/tls-compat.h @@ -0,0 +1,99 @@ +#ifndef _URCU_TLS_COMPAT_H +#define _URCU_TLS_COMPAT_H + +/* + * urcu/tls-compat.h + * + * Userspace RCU library - Thread-Local Storage Compatibility Header + * + * Copyright 2012 - Mathieu Desnoyers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef CONFIG_RCU_TLS /* Based on ax_tls.m4 */ + +# define DECLARE_URCU_TLS(type, name) \ + CONFIG_RCU_TLS type __tls_ ## name + +# define DEFINE_URCU_TLS(type, name) \ + CONFIG_RCU_TLS type __tls_ ## name + +# define URCU_TLS(name) (__tls_ ## name) + +#else /* #ifndef CONFIG_RCU_TLS */ + +# include + +struct urcu_tls { + pthread_key_t key; + pthread_mutex_t init_mutex; + int init_done; +}; + +# define DECLARE_URCU_TLS(type, name) \ + type *__tls_access_ ## name(void) + +/* + * Note: we don't free memory at process exit, since it will be dealt + * with by the OS. + */ +# define DEFINE_URCU_TLS(type, name) \ + type *__tls_access_ ## name(void) \ + { \ + static struct urcu_tls __tls_ ## name = { \ + .init_mutex = PTHREAD_MUTEX_INITIALIZER,\ + .init_done = 0, \ + }; \ + void *__tls_p; \ + if (!__tls_ ## name.init_done) { \ + /* Mutex to protect concurrent init */ \ + pthread_mutex_lock(&__tls_ ## name.init_mutex); \ + if (!__tls_ ## name.init_done) { \ + (void) pthread_key_create(&__tls_ ## name.key, \ + free); \ + cmm_smp_wmb(); /* create key before write init_done */ \ + __tls_ ## name.init_done = 1; \ + } \ + pthread_mutex_unlock(&__tls_ ## name.init_mutex); \ + } \ + cmm_smp_rmb(); /* read init_done before getting key */ \ + __tls_p = pthread_getspecific(__tls_ ## name.key); \ + if (caa_unlikely(__tls_p == NULL)) { \ + __tls_p = calloc(1, sizeof(type)); \ + (void) pthread_setspecific(__tls_ ## name.key, \ + __tls_p); \ + } \ + return __tls_p; \ + } + +# define URCU_TLS(name) (*__tls_access_ ## name()) + +#endif /* #else #ifndef CONFIG_RCU_TLS */ + +#ifdef __cplusplus +} +#endif + +#endif /* _URCU_TLS_COMPAT_H */ -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed May 16 09:58:02 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 16 May 2012 09:58:02 -0400 Subject: [lttng-dev] [RFC PATCH urcu] Use urcu/tls-compat.h Message-ID: <20120516135802.GC29920@Krystal> Provides compatibility for OpenBSD, NetBSD and Darwin. Suggested-by: Marek Vavru?a Signed-off-by: Mathieu Desnoyers --- diff --git a/tests/test_mutex.c b/tests/test_mutex.c index 3f84bbf..ba184a4 100644 --- a/tests/test_mutex.c +++ b/tests/test_mutex.c @@ -35,6 +35,7 @@ #include #include +#include #ifdef __linux__ #include @@ -155,8 +156,8 @@ static int test_duration_read(void) return !test_stop; } -static unsigned long long __thread nr_writes; -static unsigned long long __thread nr_reads; +static DEFINE_URCU_TLS(unsigned long long, nr_writes); +static DEFINE_URCU_TLS(unsigned long long, nr_reads); static unsigned long long __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *tot_nr_writes; @@ -208,12 +209,12 @@ void *thr_reader(void *data) if (caa_unlikely(rduration)) loop_sleep(rduration); pthread_mutex_unlock(&lock); - nr_reads++; + URCU_TLS(nr_reads)++; if (caa_unlikely(!test_duration_read())) break; } - tot_nr_reads[tidx] = nr_reads; + tot_nr_reads[tidx] = URCU_TLS(nr_reads); printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "reader", pthread_self(), (unsigned long)gettid()); return ((void*)1); @@ -241,7 +242,7 @@ void *thr_writer(void *data) if (caa_unlikely(wduration)) loop_sleep(wduration); pthread_mutex_unlock(&lock); - nr_writes++; + URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; if (caa_unlikely(wdelay)) @@ -250,7 +251,7 @@ void *thr_writer(void *data) printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "writer", pthread_self(), (unsigned long)gettid()); - tot_nr_writes[wtidx] = nr_writes; + tot_nr_writes[wtidx] = URCU_TLS(nr_writes); return ((void*)2); } diff --git a/tests/test_perthreadlock.c b/tests/test_perthreadlock.c index fa9c89a..6ff0412 100644 --- a/tests/test_perthreadlock.c +++ b/tests/test_perthreadlock.c @@ -35,6 +35,7 @@ #include #include +#include #ifdef __linux__ #include @@ -159,8 +160,8 @@ static int test_duration_read(void) return !test_stop; } -static unsigned long long __thread nr_writes; -static unsigned long long __thread nr_reads; +static DEFINE_URCU_TLS(unsigned long long, nr_writes); +static DEFINE_URCU_TLS(unsigned long long, nr_reads); static unsigned long long __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *tot_nr_writes; @@ -212,12 +213,12 @@ void *thr_reader(void *data) if (caa_unlikely(rduration)) loop_sleep(rduration); pthread_mutex_unlock(&per_thread_lock[tidx].lock); - nr_reads++; + URCU_TLS(nr_reads)++; if (caa_unlikely(!test_duration_read())) break; } - tot_nr_reads[tidx] = nr_reads; + tot_nr_reads[tidx] = URCU_TLS(nr_reads); printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "reader", pthread_self(), (unsigned long)gettid()); return ((void*)1); @@ -250,7 +251,7 @@ void *thr_writer(void *data) for (tidx = (long)nr_readers - 1; tidx >= 0; tidx--) { pthread_mutex_unlock(&per_thread_lock[tidx].lock); } - nr_writes++; + URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; if (caa_unlikely(wdelay)) @@ -259,7 +260,7 @@ void *thr_writer(void *data) printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "writer", pthread_self(), (unsigned long)gettid()); - tot_nr_writes[wtidx] = nr_writes; + tot_nr_writes[wtidx] = URCU_TLS(nr_writes); return ((void*)2); } diff --git a/tests/test_rwlock.c b/tests/test_rwlock.c index 34d8c07..ccbc9d1 100644 --- a/tests/test_rwlock.c +++ b/tests/test_rwlock.c @@ -35,6 +35,7 @@ #include #include +#include #ifdef __linux__ #include @@ -156,8 +157,8 @@ static int test_duration_read(void) return !test_stop; } -static unsigned long long __thread nr_writes; -static unsigned long long __thread nr_reads; +static DEFINE_URCU_TLS(unsigned long long, nr_writes); +static DEFINE_URCU_TLS(unsigned long long, nr_reads); static unsigned int nr_readers; static unsigned int nr_writers; @@ -204,12 +205,12 @@ void *thr_reader(void *_count) if (caa_unlikely(rduration)) loop_sleep(rduration); pthread_rwlock_unlock(&lock); - nr_reads++; + URCU_TLS(nr_reads)++; if (caa_unlikely(!test_duration_read())) break; } - *count = nr_reads; + *count = URCU_TLS(nr_reads); printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "reader", pthread_self(), (unsigned long)gettid()); return ((void*)1); @@ -237,7 +238,7 @@ void *thr_writer(void *_count) if (caa_unlikely(wduration)) loop_sleep(wduration); pthread_rwlock_unlock(&lock); - nr_writes++; + URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; if (caa_unlikely(wdelay)) @@ -246,7 +247,7 @@ void *thr_writer(void *_count) printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "writer", pthread_self(), (unsigned long)gettid()); - *count = nr_writes; + *count = URCU_TLS(nr_writes); return ((void*)2); } diff --git a/tests/test_urcu.c b/tests/test_urcu.c index 870f133..1b1b94b 100644 --- a/tests/test_urcu.c +++ b/tests/test_urcu.c @@ -35,6 +35,7 @@ #include #include +#include #ifdef __linux__ #include @@ -154,8 +155,8 @@ static int test_duration_read(void) return !test_stop; } -static unsigned long long __thread nr_writes; -static unsigned long long __thread nr_reads; +static DEFINE_URCU_TLS(unsigned long long, nr_writes); +static DEFINE_URCU_TLS(unsigned long long, nr_reads); static unsigned int nr_readers; static unsigned int nr_writers; @@ -242,7 +243,7 @@ void *thr_reader(void *_count) if (caa_unlikely(rduration)) loop_sleep(rduration); rcu_read_unlock(); - nr_reads++; + URCU_TLS(nr_reads)++; if (caa_unlikely(!test_duration_read())) break; } @@ -253,7 +254,7 @@ void *thr_reader(void *_count) rcu_register_thread(); rcu_unregister_thread(); - *count = nr_reads; + *count = URCU_TLS(nr_reads); printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "reader", pthread_self(), (unsigned long)gettid()); return ((void*)1); @@ -287,7 +288,7 @@ void *thr_writer(void *_count) old->a = 0; test_array_free(old); rcu_copy_mutex_unlock(); - nr_writes++; + URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; if (caa_unlikely(wdelay)) @@ -296,7 +297,7 @@ void *thr_writer(void *_count) printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "writer", pthread_self(), (unsigned long)gettid()); - *count = nr_writes; + *count = URCU_TLS(nr_writes); return ((void*)2); } diff --git a/tests/test_urcu_assign.c b/tests/test_urcu_assign.c index 42d70c2..31e22e5 100644 --- a/tests/test_urcu_assign.c +++ b/tests/test_urcu_assign.c @@ -35,6 +35,7 @@ #include #include +#include #ifdef __linux__ #include @@ -154,8 +155,8 @@ static int test_duration_read(void) return !test_stop; } -static unsigned long long __thread nr_writes; -static unsigned long long __thread nr_reads; +static DEFINE_URCU_TLS(unsigned long long, nr_writes); +static DEFINE_URCU_TLS(unsigned long long, nr_reads); static unsigned int nr_readers; static unsigned int nr_writers; @@ -242,14 +243,14 @@ void *thr_reader(void *_count) if (caa_unlikely(rduration)) loop_sleep(rduration); rcu_read_unlock(); - nr_reads++; + URCU_TLS(nr_reads)++; if (caa_unlikely(!test_duration_read())) break; } rcu_unregister_thread(); - *count = nr_reads; + *count = URCU_TLS(nr_reads); printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "reader", pthread_self(), (unsigned long)gettid()); return ((void*)1); @@ -284,7 +285,7 @@ void *thr_writer(void *_count) old->a = 0; test_array_free(old); rcu_copy_mutex_unlock(); - nr_writes++; + URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; if (caa_unlikely(wdelay)) @@ -293,7 +294,7 @@ void *thr_writer(void *_count) printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "writer", pthread_self(), (unsigned long)gettid()); - *count = nr_writes; + *count = URCU_TLS(nr_writes); return ((void*)2); } diff --git a/tests/test_urcu_bp.c b/tests/test_urcu_bp.c index 857913f..41caeb0 100644 --- a/tests/test_urcu_bp.c +++ b/tests/test_urcu_bp.c @@ -35,6 +35,7 @@ #include #include +#include #ifdef __linux__ #include @@ -154,8 +155,8 @@ static int test_duration_read(void) return !test_stop; } -static unsigned long long __thread nr_writes; -static unsigned long long __thread nr_reads; +static DEFINE_URCU_TLS(unsigned long long, nr_writes); +static DEFINE_URCU_TLS(unsigned long long, nr_reads); static unsigned int nr_readers; static unsigned int nr_writers; @@ -242,14 +243,14 @@ void *thr_reader(void *_count) if (caa_unlikely(rduration)) loop_sleep(rduration); rcu_read_unlock(); - nr_reads++; + URCU_TLS(nr_reads)++; if (caa_unlikely(!test_duration_read())) break; } rcu_unregister_thread(); - *count = nr_reads; + *count = URCU_TLS(nr_reads); printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "reader", pthread_self(), (unsigned long)gettid()); return ((void*)1); @@ -283,7 +284,7 @@ void *thr_writer(void *_count) old->a = 0; test_array_free(old); rcu_copy_mutex_unlock(); - nr_writes++; + URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; if (caa_unlikely(wdelay)) @@ -292,7 +293,7 @@ void *thr_writer(void *_count) printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "writer", pthread_self(), (unsigned long)gettid()); - *count = nr_writes; + *count = URCU_TLS(nr_writes); return ((void*)2); } diff --git a/tests/test_urcu_defer.c b/tests/test_urcu_defer.c index 1575e9c..cd9780b 100644 --- a/tests/test_urcu_defer.c +++ b/tests/test_urcu_defer.c @@ -35,6 +35,7 @@ #include #include +#include #ifdef __linux__ #include @@ -155,8 +156,8 @@ static int test_duration_read(void) return !test_stop; } -static unsigned long long __thread nr_writes; -static unsigned long long __thread nr_reads; +static DEFINE_URCU_TLS(unsigned long long, nr_writes); +static DEFINE_URCU_TLS(unsigned long long, nr_reads); static unsigned long long __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *tot_nr_writes; @@ -213,14 +214,14 @@ void *thr_reader(void *_count) if (caa_unlikely(rduration)) loop_sleep(rduration); rcu_read_unlock(); - nr_reads++; + URCU_TLS(nr_reads)++; if (caa_unlikely(!test_duration_read())) break; } rcu_unregister_thread(); - *count = nr_reads; + *count = URCU_TLS(nr_reads); printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "reader", pthread_self(), (unsigned long)gettid()); return ((void*)1); @@ -271,7 +272,7 @@ void *thr_writer(void *data) defer_rcu(test_cb2, (void *)-2L); defer_rcu(test_cb2, (void *)-4L); defer_rcu(test_cb2, (void *)-2L); - nr_writes++; + URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; if (caa_unlikely(wdelay)) @@ -282,7 +283,7 @@ void *thr_writer(void *data) printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "writer", pthread_self(), (unsigned long)gettid()); - tot_nr_writes[wtidx] = nr_writes; + tot_nr_writes[wtidx] = URCU_TLS(nr_writes); return ((void*)2); } diff --git a/tests/test_urcu_gc.c b/tests/test_urcu_gc.c index 21c5d56..3a42506 100644 --- a/tests/test_urcu_gc.c +++ b/tests/test_urcu_gc.c @@ -35,6 +35,7 @@ #include #include +#include #ifdef __linux__ #include @@ -163,8 +164,8 @@ static int test_duration_read(void) return !test_stop; } -static unsigned long long __thread nr_writes; -static unsigned long long __thread nr_reads; +static DEFINE_URCU_TLS(unsigned long long, nr_writes); +static DEFINE_URCU_TLS(unsigned long long, nr_reads); static unsigned long long __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *tot_nr_writes; @@ -221,14 +222,14 @@ void *thr_reader(void *_count) if (caa_unlikely(rduration)) loop_sleep(rduration); rcu_read_unlock(); - nr_reads++; + URCU_TLS(nr_reads)++; if (caa_unlikely(!test_duration_read())) break; } rcu_unregister_thread(); - *count = nr_reads; + *count = URCU_TLS(nr_reads); printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "reader", pthread_self(), (unsigned long)gettid()); return ((void*)1); @@ -294,7 +295,7 @@ void *thr_writer(void *data) if (caa_unlikely(wduration)) loop_sleep(wduration); rcu_gc_reclaim(wtidx, old); - nr_writes++; + URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; if (caa_unlikely(wdelay)) @@ -303,7 +304,7 @@ void *thr_writer(void *data) printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "writer", pthread_self(), (unsigned long)gettid()); - tot_nr_writes[wtidx] = nr_writes; + tot_nr_writes[wtidx] = URCU_TLS(nr_writes); return ((void*)2); } diff --git a/tests/test_urcu_hash.c b/tests/test_urcu_hash.c index 2223413..5710de0 100644 --- a/tests/test_urcu_hash.c +++ b/tests/test_urcu_hash.c @@ -82,13 +82,13 @@ int (*get_populate_hash_cb(void))(void) return test_hash_cb[test_choice].populate_hash; } -unsigned int __thread rand_lookup; -unsigned long __thread nr_add; -unsigned long __thread nr_addexist; -unsigned long __thread nr_del; -unsigned long __thread nr_delnoent; -unsigned long __thread lookup_fail; -unsigned long __thread lookup_ok; +DEFINE_URCU_TLS(unsigned int, rand_lookup); +DEFINE_URCU_TLS(unsigned long, nr_add); +DEFINE_URCU_TLS(unsigned long, nr_addexist); +DEFINE_URCU_TLS(unsigned long, nr_del); +DEFINE_URCU_TLS(unsigned long, nr_delnoent); +DEFINE_URCU_TLS(unsigned long, lookup_fail); +DEFINE_URCU_TLS(unsigned long, lookup_ok); struct cds_lfht *test_ht; @@ -126,8 +126,8 @@ int use_affinity = 0; pthread_mutex_t affinity_mutex = PTHREAD_MUTEX_INITIALIZER; -unsigned long long __thread nr_writes; -unsigned long long __thread nr_reads; +DEFINE_URCU_TLS(unsigned long long, nr_writes); +DEFINE_URCU_TLS(unsigned long long, nr_reads); unsigned int nr_readers; unsigned int nr_writers; diff --git a/tests/test_urcu_hash.h b/tests/test_urcu_hash.h index 083e71c..fe13c36 100644 --- a/tests/test_urcu_hash.h +++ b/tests/test_urcu_hash.h @@ -37,6 +37,8 @@ #include #include +#include + #ifdef __linux__ #include #endif @@ -102,13 +104,13 @@ struct wr_count { unsigned long remove; }; -extern unsigned int __thread rand_lookup; -extern unsigned long __thread nr_add; -extern unsigned long __thread nr_addexist; -extern unsigned long __thread nr_del; -extern unsigned long __thread nr_delnoent; -extern unsigned long __thread lookup_fail; -extern unsigned long __thread lookup_ok; +extern DECLARE_URCU_TLS(unsigned int, rand_lookup); +extern DECLARE_URCU_TLS(unsigned long, nr_add); +extern DECLARE_URCU_TLS(unsigned long, nr_addexist); +extern DECLARE_URCU_TLS(unsigned long, nr_del); +extern DECLARE_URCU_TLS(unsigned long, nr_delnoent); +extern DECLARE_URCU_TLS(unsigned long, lookup_fail); +extern DECLARE_URCU_TLS(unsigned long, lookup_ok); extern struct cds_lfht *test_ht; @@ -214,8 +216,8 @@ static inline int test_duration_read(void) return !test_stop; } -extern unsigned long long __thread nr_writes; -extern unsigned long long __thread nr_reads; +extern DECLARE_URCU_TLS(unsigned long long, nr_writes); +extern DECLARE_URCU_TLS(unsigned long long, nr_reads); extern unsigned int nr_readers; extern unsigned int nr_writers; diff --git a/tests/test_urcu_hash_rw.c b/tests/test_urcu_hash_rw.c index 7310344..a789236 100644 --- a/tests/test_urcu_hash_rw.c +++ b/tests/test_urcu_hash_rw.c @@ -80,7 +80,7 @@ void *test_hash_rw_thr_reader(void *_count) for (;;) { rcu_read_lock(); cds_lfht_test_lookup(test_ht, - (void *)(((unsigned long) rand_r(&rand_lookup) % lookup_pool_size) + lookup_pool_offset), + (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % lookup_pool_size) + lookup_pool_offset), sizeof(void *), &iter); node = cds_lfht_iter_get_test_node(&iter); if (node == NULL) { @@ -88,28 +88,29 @@ void *test_hash_rw_thr_reader(void *_count) printf("[ERROR] Lookup cannot find initial node.\n"); exit(-1); } - lookup_fail++; + URCU_TLS(lookup_fail)++; } else { - lookup_ok++; + URCU_TLS(lookup_ok)++; } debug_yield_read(); if (caa_unlikely(rduration)) loop_sleep(rduration); rcu_read_unlock(); - nr_reads++; + URCU_TLS(nr_reads)++; if (caa_unlikely(!test_duration_read())) break; - if (caa_unlikely((nr_reads & ((1 << 10) - 1)) == 0)) + if (caa_unlikely((URCU_TLS(nr_reads) & ((1 << 10) - 1)) == 0)) rcu_quiescent_state(); } rcu_unregister_thread(); - *count = nr_reads; + *count = URCU_TLS(nr_reads); printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "reader", pthread_self(), (unsigned long)gettid()); printf_verbose("readid : %lx, lookupfail %lu, lookupok %lu\n", - pthread_self(), lookup_fail, lookup_ok); + pthread_self(), URCU_TLS(lookup_fail), + URCU_TLS(lookup_ok)); return ((void*)1); } @@ -136,10 +137,10 @@ void *test_hash_rw_thr_writer(void *_count) for (;;) { if ((addremove == AR_ADD || add_only) - || (addremove == AR_RANDOM && rand_r(&rand_lookup) & 1)) { + || (addremove == AR_RANDOM && rand_r(&URCU_TLS(rand_lookup)) & 1)) { node = malloc(sizeof(struct lfht_test_node)); lfht_test_node_init(node, - (void *)(((unsigned long) rand_r(&rand_lookup) % write_pool_size) + write_pool_offset), + (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset), sizeof(void *)); rcu_read_lock(); if (add_unique) { @@ -159,36 +160,36 @@ void *test_hash_rw_thr_writer(void *_count) rcu_read_unlock(); if (add_unique && ret_node != &node->node) { free(node); - nr_addexist++; + URCU_TLS(nr_addexist)++; } else { if (add_replace && ret_node) { call_rcu(&to_test_node(ret_node)->head, free_node_cb); - nr_addexist++; + URCU_TLS(nr_addexist)++; } else { - nr_add++; + URCU_TLS(nr_add)++; } } } else { /* May delete */ rcu_read_lock(); cds_lfht_test_lookup(test_ht, - (void *)(((unsigned long) rand_r(&rand_lookup) % write_pool_size) + write_pool_offset), + (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset), sizeof(void *), &iter); ret = cds_lfht_del(test_ht, cds_lfht_iter_get_node(&iter)); rcu_read_unlock(); if (ret == 0) { node = cds_lfht_iter_get_test_node(&iter); call_rcu(&node->head, free_node_cb); - nr_del++; + URCU_TLS(nr_del)++; } else - nr_delnoent++; + URCU_TLS(nr_delnoent)++; } #if 0 - //if (nr_writes % 100000 == 0) { - if (nr_writes % 1000 == 0) { + //if (URCU_TLS(nr_writes) % 100000 == 0) { + if (URCU_TLS(nr_writes) % 1000 == 0) { rcu_read_lock(); - if (rand_r(&rand_lookup) & 1) { + if (rand_r(&URCU_TLS(rand_lookup)) & 1) { ht_resize(test_ht, 1); } else { ht_resize(test_ht, -1); @@ -196,12 +197,12 @@ void *test_hash_rw_thr_writer(void *_count) rcu_read_unlock(); } #endif //0 - nr_writes++; + URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; if (caa_unlikely(wdelay)) loop_sleep(wdelay); - if (caa_unlikely((nr_writes & ((1 << 10) - 1)) == 0)) + if (caa_unlikely((URCU_TLS(nr_writes) & ((1 << 10) - 1)) == 0)) rcu_quiescent_state(); } @@ -210,12 +211,13 @@ void *test_hash_rw_thr_writer(void *_count) printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "writer", pthread_self(), (unsigned long)gettid()); printf_verbose("info id %lx: nr_add %lu, nr_addexist %lu, nr_del %lu, " - "nr_delnoent %lu\n", pthread_self(), nr_add, - nr_addexist, nr_del, nr_delnoent); - count->update_ops = nr_writes; - count->add = nr_add; - count->add_exist = nr_addexist; - count->remove = nr_del; + "nr_delnoent %lu\n", pthread_self(), URCU_TLS(nr_add), + URCU_TLS(nr_addexist), URCU_TLS(nr_del), + URCU_TLS(nr_delnoent)); + count->update_ops = URCU_TLS(nr_writes); + count->add = URCU_TLS(nr_add); + count->add_exist = URCU_TLS(nr_addexist); + count->remove = URCU_TLS(nr_del); return ((void*)2); } @@ -235,10 +237,10 @@ int test_hash_rw_populate_hash(void) "larger random pool (-p option). This may take a while...\n", init_populate, init_pool_size); } - while (nr_add < init_populate) { + while (URCU_TLS(nr_add) < init_populate) { node = malloc(sizeof(struct lfht_test_node)); lfht_test_node_init(node, - (void *)(((unsigned long) rand_r(&rand_lookup) % init_pool_size) + init_pool_offset), + (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % init_pool_size) + init_pool_offset), sizeof(void *)); rcu_read_lock(); if (add_unique) { @@ -258,16 +260,16 @@ int test_hash_rw_populate_hash(void) rcu_read_unlock(); if (add_unique && ret_node != &node->node) { free(node); - nr_addexist++; + URCU_TLS(nr_addexist)++; } else { if (add_replace && ret_node) { call_rcu(&to_test_node(ret_node)->head, free_node_cb); - nr_addexist++; + URCU_TLS(nr_addexist)++; } else { - nr_add++; + URCU_TLS(nr_add)++; } } - nr_writes++; + URCU_TLS(nr_writes)++; } return 0; } diff --git a/tests/test_urcu_hash_unique.c b/tests/test_urcu_hash_unique.c index c934feb..610f479 100644 --- a/tests/test_urcu_hash_unique.c +++ b/tests/test_urcu_hash_unique.c @@ -98,20 +98,21 @@ void *test_hash_unique_thr_reader(void *_count) debug_yield_read(); if (caa_unlikely(rduration)) loop_sleep(rduration); - nr_reads++; + URCU_TLS(nr_reads)++; if (caa_unlikely(!test_duration_read())) break; - if (caa_unlikely((nr_reads & ((1 << 10) - 1)) == 0)) + if (caa_unlikely((URCU_TLS(nr_reads) & ((1 << 10) - 1)) == 0)) rcu_quiescent_state(); } rcu_unregister_thread(); - *count = nr_reads; + *count = URCU_TLS(nr_reads); printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "reader", pthread_self(), (unsigned long)gettid()); printf_verbose("readid : %lx, lookupfail %lu, lookupok %lu\n", - pthread_self(), lookup_fail, lookup_ok); + pthread_self(), URCU_TLS(lookup_fail), + URCU_TLS(lookup_ok)); return ((void*)1); } @@ -142,13 +143,13 @@ void *test_hash_unique_thr_writer(void *_count) * add unique/add replace with new node key from range. */ if (1 || (addremove == AR_ADD || add_only) - || (addremove == AR_RANDOM && rand_r(&rand_lookup) & 1)) { + || (addremove == AR_RANDOM && rand_r(&URCU_TLS(rand_lookup)) & 1)) { node = malloc(sizeof(struct lfht_test_node)); lfht_test_node_init(node, - (void *)(((unsigned long) rand_r(&rand_lookup) % write_pool_size) + write_pool_offset), + (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset), sizeof(void *)); rcu_read_lock(); - loc_add_unique = rand_r(&rand_lookup) & 1; + loc_add_unique = rand_r(&URCU_TLS(rand_lookup)) & 1; if (loc_add_unique) { ret_node = cds_lfht_add_unique(test_ht, test_hash(node->key, node->key_len, TEST_HASH_SEED), @@ -168,39 +169,39 @@ void *test_hash_unique_thr_writer(void *_count) if (loc_add_unique) { if (ret_node != &node->node) { free(node); - nr_addexist++; + URCU_TLS(nr_addexist)++; } else { - nr_add++; + URCU_TLS(nr_add)++; } } else { if (ret_node) { call_rcu(&to_test_node(ret_node)->head, free_node_cb); - nr_addexist++; + URCU_TLS(nr_addexist)++; } else { - nr_add++; + URCU_TLS(nr_add)++; } } } else { /* May delete */ rcu_read_lock(); cds_lfht_test_lookup(test_ht, - (void *)(((unsigned long) rand_r(&rand_lookup) % write_pool_size) + write_pool_offset), + (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset), sizeof(void *), &iter); ret = cds_lfht_del(test_ht, cds_lfht_iter_get_node(&iter)); rcu_read_unlock(); if (ret == 0) { node = cds_lfht_iter_get_test_node(&iter); call_rcu(&node->head, free_node_cb); - nr_del++; + URCU_TLS(nr_del)++; } else - nr_delnoent++; + URCU_TLS(nr_delnoent)++; } #if 0 - //if (nr_writes % 100000 == 0) { - if (nr_writes % 1000 == 0) { + //if (URCU_TLS(nr_writes) % 100000 == 0) { + if (URCU_TLS(nr_writes) % 1000 == 0) { rcu_read_lock(); - if (rand_r(&rand_lookup) & 1) { + if (rand_r(&URCU_TLS(rand_lookup)) & 1) { ht_resize(test_ht, 1); } else { ht_resize(test_ht, -1); @@ -208,12 +209,12 @@ void *test_hash_unique_thr_writer(void *_count) rcu_read_unlock(); } #endif //0 - nr_writes++; + URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; if (caa_unlikely(wdelay)) loop_sleep(wdelay); - if (caa_unlikely((nr_writes & ((1 << 10) - 1)) == 0)) + if (caa_unlikely((URCU_TLS(nr_writes) & ((1 << 10) - 1)) == 0)) rcu_quiescent_state(); } @@ -222,12 +223,13 @@ void *test_hash_unique_thr_writer(void *_count) printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "writer", pthread_self(), (unsigned long)gettid()); printf_verbose("info id %lx: nr_add %lu, nr_addexist %lu, nr_del %lu, " - "nr_delnoent %lu\n", pthread_self(), nr_add, - nr_addexist, nr_del, nr_delnoent); - count->update_ops = nr_writes; - count->add = nr_add; - count->add_exist = nr_addexist; - count->remove = nr_del; + "nr_delnoent %lu\n", pthread_self(), URCU_TLS(nr_add), + URCU_TLS(nr_addexist), URCU_TLS(nr_del), + URCU_TLS(nr_delnoent)); + count->update_ops = URCU_TLS(nr_writes); + count->add = URCU_TLS(nr_add); + count->add_exist = URCU_TLS(nr_addexist); + count->remove = URCU_TLS(nr_del); return ((void*)2); } @@ -247,10 +249,10 @@ int test_hash_unique_populate_hash(void) "larger random pool (-p option). This may take a while...\n", init_populate, init_pool_size); } - while (nr_add < init_populate) { + while (URCU_TLS(nr_add) < init_populate) { node = malloc(sizeof(struct lfht_test_node)); lfht_test_node_init(node, - (void *)(((unsigned long) rand_r(&rand_lookup) % init_pool_size) + init_pool_offset), + (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % init_pool_size) + init_pool_offset), sizeof(void *)); rcu_read_lock(); ret_node = cds_lfht_add_replace(test_ht, @@ -259,11 +261,11 @@ int test_hash_unique_populate_hash(void) rcu_read_unlock(); if (ret_node) { call_rcu(&to_test_node(ret_node)->head, free_node_cb); - nr_addexist++; + URCU_TLS(nr_addexist)++; } else { - nr_add++; + URCU_TLS(nr_add)++; } - nr_writes++; + URCU_TLS(nr_writes)++; } return 0; } diff --git a/tests/test_urcu_lfq.c b/tests/test_urcu_lfq.c index 01a2781..66ddd41 100644 --- a/tests/test_urcu_lfq.c +++ b/tests/test_urcu_lfq.c @@ -38,6 +38,7 @@ #include #include +#include #ifdef __linux__ #include @@ -148,11 +149,11 @@ static int test_duration_enqueue(void) return !test_stop; } -static unsigned long long __thread nr_dequeues; -static unsigned long long __thread nr_enqueues; +static DEFINE_URCU_TLS(unsigned long long, nr_dequeues); +static DEFINE_URCU_TLS(unsigned long long, nr_enqueues); -static unsigned long long __thread nr_successful_dequeues; -static unsigned long long __thread nr_successful_enqueues; +static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); +static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); static unsigned int nr_enqueuers; static unsigned int nr_dequeuers; @@ -188,24 +189,24 @@ void *thr_enqueuer(void *_count) rcu_read_lock(); cds_lfq_enqueue_rcu(&q, &node->list); rcu_read_unlock(); - nr_successful_enqueues++; + URCU_TLS(nr_successful_enqueues)++; if (caa_unlikely(wdelay)) loop_sleep(wdelay); fail: - nr_enqueues++; + URCU_TLS(nr_enqueues)++; if (caa_unlikely(!test_duration_enqueue())) break; } rcu_unregister_thread(); - count[0] = nr_enqueues; - count[1] = nr_successful_enqueues; + count[0] = URCU_TLS(nr_enqueues); + count[1] = URCU_TLS(nr_successful_enqueues); printf_verbose("enqueuer thread_end, thread id : %lx, tid %lu, " "enqueues %llu successful_enqueues %llu\n", - pthread_self(), (unsigned long)gettid(), nr_enqueues, - nr_successful_enqueues); + pthread_self(), (unsigned long)gettid(), + URCU_TLS(nr_enqueues), URCU_TLS(nr_successful_enqueues)); return ((void*)1); } @@ -251,10 +252,10 @@ void *thr_dequeuer(void *_count) if (node) { call_rcu(&node->rcu, free_node_cb); - nr_successful_dequeues++; + URCU_TLS(nr_successful_dequeues)++; } - nr_dequeues++; + URCU_TLS(nr_dequeues)++; if (caa_unlikely(!test_duration_dequeue())) break; if (caa_unlikely(rduration)) @@ -265,10 +266,10 @@ void *thr_dequeuer(void *_count) rcu_defer_unregister_thread(); printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " "dequeues %llu, successful_dequeues %llu\n", - pthread_self(), (unsigned long)gettid(), nr_dequeues, - nr_successful_dequeues); - count[0] = nr_dequeues; - count[1] = nr_successful_dequeues; + pthread_self(), (unsigned long)gettid(), + URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues)); + count[0] = URCU_TLS(nr_dequeues); + count[1] = URCU_TLS(nr_successful_dequeues); return ((void*)2); } diff --git a/tests/test_urcu_lfs.c b/tests/test_urcu_lfs.c index b48a35f..88bf65d 100644 --- a/tests/test_urcu_lfs.c +++ b/tests/test_urcu_lfs.c @@ -38,6 +38,7 @@ #include #include +#include #ifdef __linux__ #include @@ -148,11 +149,11 @@ static int test_duration_enqueue(void) return !test_stop; } -static unsigned long long __thread nr_dequeues; -static unsigned long long __thread nr_enqueues; +static DEFINE_URCU_TLS(unsigned long long, nr_dequeues); +static DEFINE_URCU_TLS(unsigned long long, nr_enqueues); -static unsigned long long __thread nr_successful_dequeues; -static unsigned long long __thread nr_successful_enqueues; +static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); +static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); static unsigned int nr_enqueuers; static unsigned int nr_dequeuers; @@ -187,24 +188,24 @@ void *thr_enqueuer(void *_count) cds_lfs_node_init_rcu(&node->list); /* No rcu read-side is needed for push */ cds_lfs_push_rcu(&s, &node->list); - nr_successful_enqueues++; + URCU_TLS(nr_successful_enqueues)++; if (caa_unlikely(wdelay)) loop_sleep(wdelay); fail: - nr_enqueues++; + URCU_TLS(nr_enqueues)++; if (caa_unlikely(!test_duration_enqueue())) break; } rcu_unregister_thread(); - count[0] = nr_enqueues; - count[1] = nr_successful_enqueues; + count[0] = URCU_TLS(nr_enqueues); + count[1] = URCU_TLS(nr_successful_enqueues); printf_verbose("enqueuer thread_end, thread id : %lx, tid %lu, " "enqueues %llu successful_enqueues %llu\n", - pthread_self(), (unsigned long)gettid(), nr_enqueues, - nr_successful_enqueues); + pthread_self(), (unsigned long)gettid(), + URCU_TLS(nr_enqueues), URCU_TLS(nr_successful_enqueues)); return ((void*)1); } @@ -249,9 +250,9 @@ void *thr_dequeuer(void *_count) rcu_read_unlock(); if (node) { call_rcu(&node->rcu, free_node_cb); - nr_successful_dequeues++; + URCU_TLS(nr_successful_dequeues)++; } - nr_dequeues++; + URCU_TLS(nr_dequeues)++; if (caa_unlikely(!test_duration_dequeue())) break; if (caa_unlikely(rduration)) @@ -263,10 +264,10 @@ void *thr_dequeuer(void *_count) printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " "dequeues %llu, successful_dequeues %llu\n", - pthread_self(), (unsigned long)gettid(), nr_dequeues, - nr_successful_dequeues); - count[0] = nr_dequeues; - count[1] = nr_successful_dequeues; + pthread_self(), (unsigned long)gettid(), + URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues)); + count[0] = URCU_TLS(nr_dequeues); + count[1] = URCU_TLS(nr_successful_dequeues); return ((void*)2); } diff --git a/tests/test_urcu_qsbr.c b/tests/test_urcu_qsbr.c index b986fd8..421fb07 100644 --- a/tests/test_urcu_qsbr.c +++ b/tests/test_urcu_qsbr.c @@ -35,6 +35,7 @@ #include #include +#include #ifdef __linux__ #include @@ -153,8 +154,8 @@ static int test_duration_read(void) return !test_stop; } -static unsigned long long __thread nr_writes; -static unsigned long long __thread nr_reads; +static DEFINE_URCU_TLS(unsigned long long, nr_writes); +static DEFINE_URCU_TLS(unsigned long long, nr_reads); static unsigned int nr_readers; static unsigned int nr_writers; @@ -241,9 +242,9 @@ void *thr_reader(void *_count) if (caa_unlikely(rduration)) loop_sleep(rduration); rcu_read_unlock(); - nr_reads++; + URCU_TLS(nr_reads)++; /* QS each 1024 reads */ - if (caa_unlikely((nr_reads & ((1 << 10) - 1)) == 0)) + if (caa_unlikely((URCU_TLS(nr_reads) & ((1 << 10) - 1)) == 0)) rcu_quiescent_state(); if (caa_unlikely(!test_duration_read())) break; @@ -255,7 +256,7 @@ void *thr_reader(void *_count) rcu_register_thread(); rcu_unregister_thread(); - *count = nr_reads; + *count = URCU_TLS(nr_reads); printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "reader", pthread_self(), (unsigned long)gettid()); return ((void*)1); @@ -290,7 +291,7 @@ void *thr_writer(void *_count) old->a = 0; test_array_free(old); rcu_copy_mutex_unlock(); - nr_writes++; + URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; if (caa_unlikely(wdelay)) @@ -299,7 +300,7 @@ void *thr_writer(void *_count) printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "writer", pthread_self(), (unsigned long)gettid()); - *count = nr_writes; + *count = URCU_TLS(nr_writes); return ((void*)2); } diff --git a/tests/test_urcu_qsbr_gc.c b/tests/test_urcu_qsbr_gc.c index 9deb0aa..561a475 100644 --- a/tests/test_urcu_qsbr_gc.c +++ b/tests/test_urcu_qsbr_gc.c @@ -35,6 +35,7 @@ #include #include +#include #ifdef __linux__ #include @@ -159,8 +160,8 @@ static int test_duration_read(void) return !test_stop; } -static unsigned long long __thread nr_writes; -static unsigned long long __thread nr_reads; +static DEFINE_URCU_TLS(unsigned long long, nr_writes); +static DEFINE_URCU_TLS(unsigned long long, nr_reads); static unsigned int nr_readers; static unsigned int nr_writers; @@ -217,9 +218,9 @@ void *thr_reader(void *_count) if (caa_unlikely(rduration)) loop_sleep(rduration); _rcu_read_unlock(); - nr_reads++; + URCU_TLS(nr_reads)++; /* QS each 1024 reads */ - if (caa_unlikely((nr_reads & ((1 << 10) - 1)) == 0)) + if (caa_unlikely((URCU_TLS(nr_reads) & ((1 << 10) - 1)) == 0)) _rcu_quiescent_state(); if (caa_unlikely(!test_duration_read())) break; @@ -227,7 +228,7 @@ void *thr_reader(void *_count) rcu_unregister_thread(); - *count = nr_reads; + *count = URCU_TLS(nr_reads); printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "reader", pthread_self(), (unsigned long)gettid()); return ((void*)1); @@ -293,7 +294,7 @@ void *thr_writer(void *data) if (caa_unlikely(wduration)) loop_sleep(wduration); rcu_gc_reclaim(wtidx, old); - nr_writes++; + URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; if (caa_unlikely(wdelay)) @@ -302,7 +303,7 @@ void *thr_writer(void *data) printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "writer", pthread_self(), (unsigned long)gettid()); - tot_nr_writes[wtidx] = nr_writes; + tot_nr_writes[wtidx] = URCU_TLS(nr_writes); return ((void*)2); } diff --git a/tests/test_urcu_wfq.c b/tests/test_urcu_wfq.c index 83ec635..75a9275 100644 --- a/tests/test_urcu_wfq.c +++ b/tests/test_urcu_wfq.c @@ -38,6 +38,7 @@ #include #include +#include #ifdef __linux__ #include @@ -147,11 +148,11 @@ static int test_duration_enqueue(void) return !test_stop; } -static unsigned long long __thread nr_dequeues; -static unsigned long long __thread nr_enqueues; +static DEFINE_URCU_TLS(unsigned long long, nr_dequeues); +static DEFINE_URCU_TLS(unsigned long long, nr_enqueues); -static unsigned long long __thread nr_successful_dequeues; -static unsigned long long __thread nr_successful_enqueues; +static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); +static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); static unsigned int nr_enqueuers; static unsigned int nr_dequeuers; @@ -178,22 +179,22 @@ void *thr_enqueuer(void *_count) goto fail; cds_wfq_node_init(node); cds_wfq_enqueue(&q, node); - nr_successful_enqueues++; + URCU_TLS(nr_successful_enqueues)++; if (caa_unlikely(wdelay)) loop_sleep(wdelay); fail: - nr_enqueues++; + URCU_TLS(nr_enqueues)++; if (caa_unlikely(!test_duration_enqueue())) break; } - count[0] = nr_enqueues; - count[1] = nr_successful_enqueues; + count[0] = URCU_TLS(nr_enqueues); + count[1] = URCU_TLS(nr_successful_enqueues); printf_verbose("enqueuer thread_end, thread id : %lx, tid %lu, " "enqueues %llu successful_enqueues %llu\n", - pthread_self(), (unsigned long)gettid(), nr_enqueues, - nr_successful_enqueues); + pthread_self(), (unsigned long)gettid(), + URCU_TLS(nr_enqueues), URCU_TLS(nr_successful_enqueues)); return ((void*)1); } @@ -217,10 +218,10 @@ void *thr_dequeuer(void *_count) if (node) { free(node); - nr_successful_dequeues++; + URCU_TLS(nr_successful_dequeues)++; } - nr_dequeues++; + URCU_TLS(nr_dequeues)++; if (caa_unlikely(!test_duration_dequeue())) break; if (caa_unlikely(rduration)) @@ -229,10 +230,10 @@ void *thr_dequeuer(void *_count) printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " "dequeues %llu, successful_dequeues %llu\n", - pthread_self(), (unsigned long)gettid(), nr_dequeues, - nr_successful_dequeues); - count[0] = nr_dequeues; - count[1] = nr_successful_dequeues; + pthread_self(), (unsigned long)gettid(), + URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues)); + count[0] = URCU_TLS(nr_dequeues); + count[1] = URCU_TLS(nr_successful_dequeues); return ((void*)2); } diff --git a/tests/test_urcu_wfs.c b/tests/test_urcu_wfs.c index 7746a1d..be09944 100644 --- a/tests/test_urcu_wfs.c +++ b/tests/test_urcu_wfs.c @@ -38,6 +38,7 @@ #include #include +#include #ifdef __linux__ #include @@ -147,11 +148,11 @@ static int test_duration_enqueue(void) return !test_stop; } -static unsigned long long __thread nr_dequeues; -static unsigned long long __thread nr_enqueues; +static DEFINE_URCU_TLS(unsigned long long, nr_dequeues); +static DEFINE_URCU_TLS(unsigned long long, nr_enqueues); -static unsigned long long __thread nr_successful_dequeues; -static unsigned long long __thread nr_successful_enqueues; +static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); +static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); static unsigned int nr_enqueuers; static unsigned int nr_dequeuers; @@ -178,22 +179,22 @@ void *thr_enqueuer(void *_count) goto fail; cds_wfs_node_init(node); cds_wfs_push(&s, node); - nr_successful_enqueues++; + URCU_TLS(nr_successful_enqueues)++; if (caa_unlikely(wdelay)) loop_sleep(wdelay); fail: - nr_enqueues++; + URCU_TLS(nr_enqueues)++; if (caa_unlikely(!test_duration_enqueue())) break; } - count[0] = nr_enqueues; - count[1] = nr_successful_enqueues; + count[0] = URCU_TLS(nr_enqueues); + count[1] = URCU_TLS(nr_successful_enqueues); printf_verbose("enqueuer thread_end, thread id : %lx, tid %lu, " "enqueues %llu successful_enqueues %llu\n", - pthread_self(), (unsigned long)gettid(), nr_enqueues, - nr_successful_enqueues); + pthread_self(), (unsigned long)gettid(), + URCU_TLS(nr_enqueues), URCU_TLS(nr_successful_enqueues)); return ((void*)1); } @@ -217,10 +218,10 @@ void *thr_dequeuer(void *_count) if (node) { free(node); - nr_successful_dequeues++; + URCU_TLS(nr_successful_dequeues)++; } - nr_dequeues++; + URCU_TLS(nr_dequeues)++; if (caa_unlikely(!test_duration_dequeue())) break; if (caa_unlikely(rduration)) @@ -229,10 +230,10 @@ void *thr_dequeuer(void *_count) printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " "dequeues %llu, successful_dequeues %llu\n", - pthread_self(), (unsigned long)gettid(), nr_dequeues, - nr_successful_dequeues); - count[0] = nr_dequeues; - count[1] = nr_successful_dequeues; + pthread_self(), (unsigned long)gettid(), + URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues)); + count[0] = URCU_TLS(nr_dequeues); + count[1] = URCU_TLS(nr_successful_dequeues); return ((void*)2); } diff --git a/urcu-bp.c b/urcu-bp.c index 08b4b55..bb657d7 100644 --- a/urcu-bp.c +++ b/urcu-bp.c @@ -40,6 +40,7 @@ #include "urcu/map/urcu-bp.h" #include "urcu/static/urcu-bp.h" #include "urcu-pointer.h" +#include "urcu/tls-compat.h" /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ #undef _LGPL_SOURCE @@ -94,7 +95,7 @@ static pthread_mutex_t rcu_gp_lock = PTHREAD_MUTEX_INITIALIZER; #ifdef DEBUG_YIELD unsigned int yield_active; -unsigned int __thread rand_yield; +DEFINE_URCU_TLS(unsigned int, rand_yield); #endif /* @@ -109,7 +110,7 @@ long rcu_gp_ctr = RCU_GP_COUNT; * Pointer to registry elements. Written to only by each individual reader. Read * by both the reader and the writers. */ -struct rcu_reader __thread *rcu_reader; +DEFINE_URCU_TLS(struct rcu_reader *, rcu_reader); static CDS_LIST_HEAD(registry); @@ -322,7 +323,7 @@ static void add_thread(void) rcu_reader_reg->tid = pthread_self(); assert(rcu_reader_reg->ctr == 0); cds_list_add(&rcu_reader_reg->node, ®istry); - rcu_reader = rcu_reader_reg; + URCU_TLS(rcu_reader) = rcu_reader_reg; } /* Called with signals off and mutex locked */ @@ -363,7 +364,7 @@ void rcu_bp_register(void) /* * Check if a signal concurrently registered our thread since * the check in rcu_read_lock(). */ - if (rcu_reader) + if (URCU_TLS(rcu_reader)) goto end; mutex_lock(&rcu_gp_lock); diff --git a/urcu-call-rcu-impl.h b/urcu-call-rcu-impl.h index 36e3cf4..8ed2ab3 100644 --- a/urcu-call-rcu-impl.h +++ b/urcu-call-rcu-impl.h @@ -40,6 +40,7 @@ #include "urcu-pointer.h" #include "urcu/list.h" #include "urcu/futex.h" +#include "urcu/tls-compat.h" /* Data structure that identifies a call_rcu thread. */ @@ -62,7 +63,7 @@ CDS_LIST_HEAD(call_rcu_data_list); /* Link a thread using call_rcu() to its call_rcu thread. */ -static __thread struct call_rcu_data *thread_call_rcu_data; +static DEFINE_URCU_TLS(struct call_rcu_data *, thread_call_rcu_data); /* Guard call_rcu thread creation. */ @@ -232,7 +233,7 @@ static void *call_rcu_thread(void *arg) */ rcu_register_thread(); - thread_call_rcu_data = crdp; + URCU_TLS(thread_call_rcu_data) = crdp; if (!rt) { uatomic_dec(&crdp->futex); /* Decrement futex before reading call_rcu list */ @@ -470,8 +471,8 @@ struct call_rcu_data *get_call_rcu_data(void) { struct call_rcu_data *crd; - if (thread_call_rcu_data != NULL) - return thread_call_rcu_data; + if (URCU_TLS(thread_call_rcu_data) != NULL) + return URCU_TLS(thread_call_rcu_data); if (maxcpus > 0) { crd = get_cpu_call_rcu_data(sched_getcpu()); @@ -488,7 +489,7 @@ struct call_rcu_data *get_call_rcu_data(void) struct call_rcu_data *get_thread_call_rcu_data(void) { - return thread_call_rcu_data; + return URCU_TLS(thread_call_rcu_data); } /* @@ -504,7 +505,7 @@ struct call_rcu_data *get_thread_call_rcu_data(void) void set_thread_call_rcu_data(struct call_rcu_data *crdp) { - thread_call_rcu_data = crdp; + URCU_TLS(thread_call_rcu_data) = crdp; } /* @@ -746,7 +747,7 @@ void call_rcu_after_fork_child(void) maxcpus_reset(); free(per_cpu_call_rcu_data); rcu_set_pointer(&per_cpu_call_rcu_data, NULL); - thread_call_rcu_data = NULL; + URCU_TLS(thread_call_rcu_data) = NULL; /* Dispose of all of the rest of the call_rcu_data structures. */ cds_list_for_each_entry_safe(crdp, next, &call_rcu_data_list, list) { diff --git a/urcu-defer-impl.h b/urcu-defer-impl.h index 4d1ca5e..f65e410 100644 --- a/urcu-defer-impl.h +++ b/urcu-defer-impl.h @@ -48,6 +48,7 @@ #include #include #include +#include /* * Number of entries in the per-thread defer queue. Must be power of 2. @@ -130,7 +131,7 @@ static int32_t defer_thread_stop; * Written to only by each individual deferer. Read by both the deferer and * the reclamation tread. */ -static struct defer_queue __thread defer_queue; +static DEFINE_URCU_TLS(struct defer_queue, defer_queue); static CDS_LIST_HEAD(registry_defer); static pthread_t tid_defer; @@ -245,12 +246,12 @@ static void _rcu_defer_barrier_thread(void) { unsigned long head, num_items; - head = defer_queue.head; - num_items = head - defer_queue.tail; + head = URCU_TLS(defer_queue).head; + num_items = head - URCU_TLS(defer_queue).tail; if (caa_unlikely(!num_items)) return; synchronize_rcu(); - rcu_defer_barrier_queue(&defer_queue, head); + rcu_defer_barrier_queue(&URCU_TLS(defer_queue), head); } void rcu_defer_barrier_thread(void) @@ -311,8 +312,8 @@ void _defer_rcu(void (*fct)(void *p), void *p) * Head is only modified by ourself. Tail can be modified by reclamation * thread. */ - head = defer_queue.head; - tail = CMM_LOAD_SHARED(defer_queue.tail); + head = URCU_TLS(defer_queue).head; + tail = CMM_LOAD_SHARED(URCU_TLS(defer_queue).tail); /* * If queue is full, or reached threshold. Empty queue ourself. @@ -321,7 +322,7 @@ void _defer_rcu(void (*fct)(void *p), void *p) if (caa_unlikely(head - tail >= DEFER_QUEUE_SIZE - 2)) { assert(head - tail <= DEFER_QUEUE_SIZE); rcu_defer_barrier_thread(); - assert(head - CMM_LOAD_SHARED(defer_queue.tail) == 0); + assert(head - CMM_LOAD_SHARED(URCU_TLS(defer_queue).tail) == 0); } /* @@ -340,25 +341,25 @@ void _defer_rcu(void (*fct)(void *p), void *p) * Decode: see the comments before 'struct defer_queue' * or the code in rcu_defer_barrier_queue(). */ - if (caa_unlikely(defer_queue.last_fct_in != fct + if (caa_unlikely(URCU_TLS(defer_queue).last_fct_in != fct || DQ_IS_FCT_BIT(p) || p == DQ_FCT_MARK)) { - defer_queue.last_fct_in = fct; + URCU_TLS(defer_queue).last_fct_in = fct; if (caa_unlikely(DQ_IS_FCT_BIT(fct) || fct == DQ_FCT_MARK)) { - _CMM_STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK], + _CMM_STORE_SHARED(URCU_TLS(defer_queue).q[head++ & DEFER_QUEUE_MASK], DQ_FCT_MARK); - _CMM_STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK], + _CMM_STORE_SHARED(URCU_TLS(defer_queue).q[head++ & DEFER_QUEUE_MASK], fct); } else { DQ_SET_FCT_BIT(fct); - _CMM_STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK], + _CMM_STORE_SHARED(URCU_TLS(defer_queue).q[head++ & DEFER_QUEUE_MASK], fct); } } - _CMM_STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK], p); + _CMM_STORE_SHARED(URCU_TLS(defer_queue).q[head++ & DEFER_QUEUE_MASK], p); cmm_smp_wmb(); /* Publish new pointer before head */ /* Write q[] before head. */ - CMM_STORE_SHARED(defer_queue.head, head); + CMM_STORE_SHARED(URCU_TLS(defer_queue).head, head); cmm_smp_mb(); /* Write queue head before read futex */ /* * Wake-up any waiting defer thread. @@ -422,16 +423,16 @@ int rcu_defer_register_thread(void) { int was_empty; - assert(defer_queue.last_head == 0); - assert(defer_queue.q == NULL); - defer_queue.q = malloc(sizeof(void *) * DEFER_QUEUE_SIZE); - if (!defer_queue.q) + assert(URCU_TLS(defer_queue).last_head == 0); + assert(URCU_TLS(defer_queue).q == NULL); + URCU_TLS(defer_queue).q = malloc(sizeof(void *) * DEFER_QUEUE_SIZE); + if (!URCU_TLS(defer_queue).q) return -ENOMEM; mutex_lock_defer(&defer_thread_mutex); mutex_lock_defer(&rcu_defer_mutex); was_empty = cds_list_empty(®istry_defer); - cds_list_add(&defer_queue.list, ®istry_defer); + cds_list_add(&URCU_TLS(defer_queue).list, ®istry_defer); mutex_unlock(&rcu_defer_mutex); if (was_empty) @@ -446,10 +447,10 @@ void rcu_defer_unregister_thread(void) mutex_lock_defer(&defer_thread_mutex); mutex_lock_defer(&rcu_defer_mutex); - cds_list_del(&defer_queue.list); + cds_list_del(&URCU_TLS(defer_queue).list); _rcu_defer_barrier_thread(); - free(defer_queue.q); - defer_queue.q = NULL; + free(URCU_TLS(defer_queue).q); + URCU_TLS(defer_queue).q = NULL; is_empty = cds_list_empty(®istry_defer); mutex_unlock(&rcu_defer_mutex); diff --git a/urcu-qsbr.c b/urcu-qsbr.c index 745676e..b20d564 100644 --- a/urcu-qsbr.c +++ b/urcu-qsbr.c @@ -40,6 +40,7 @@ #define BUILD_QSBR_LIB #include "urcu/static/urcu-qsbr.h" #include "urcu-pointer.h" +#include "urcu/tls-compat.h" /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ #undef _LGPL_SOURCE @@ -66,11 +67,11 @@ unsigned long rcu_gp_ctr = RCU_GP_ONLINE; * Written to only by each individual reader. Read by both the reader and the * writers. */ -struct rcu_reader __thread rcu_reader; +DEFINE_URCU_TLS(struct rcu_reader, rcu_reader); #ifdef DEBUG_YIELD unsigned int yield_active; -unsigned int __thread rand_yield; +DEFINE_URCU_TLS(unsigned int, rand_yield); #endif static CDS_LIST_HEAD(registry); @@ -139,7 +140,7 @@ static void update_counter_and_wait(void) * quiescent state. Failure to do so could result in the writer * waiting forever while new readers are always accessing data * (no progress). Enforce compiler-order of store to rcu_gp_ctr - * before load rcu_reader ctr. + * before load URCU_TLS(rcu_reader).ctr. */ cmm_barrier(); @@ -206,7 +207,7 @@ void synchronize_rcu(void) { unsigned long was_online; - was_online = rcu_reader.ctr; + was_online = URCU_TLS(rcu_reader).ctr; /* All threads should read qparity before accessing data structure * where new ptr points to. In the "then" case, rcu_thread_offline @@ -236,7 +237,7 @@ void synchronize_rcu(void) * committing next rcu_gp_ctr update to memory. Failure to * do so could result in the writer waiting forever while new * readers are always accessing data (no progress). Enforce - * compiler-order of load rcu_reader ctr before store to + * compiler-order of load URCU_TLS(rcu_reader).ctr before store to * rcu_gp_ctr. */ cmm_barrier(); @@ -269,7 +270,7 @@ void synchronize_rcu(void) { unsigned long was_online; - was_online = rcu_reader.ctr; + was_online = URCU_TLS(rcu_reader).ctr; /* * Mark the writer thread offline to make sure we don't wait for @@ -326,11 +327,11 @@ void rcu_thread_online(void) void rcu_register_thread(void) { - rcu_reader.tid = pthread_self(); - assert(rcu_reader.ctr == 0); + URCU_TLS(rcu_reader).tid = pthread_self(); + assert(URCU_TLS(rcu_reader).ctr == 0); mutex_lock(&rcu_gp_lock); - cds_list_add(&rcu_reader.node, ®istry); + cds_list_add(&URCU_TLS(rcu_reader).node, ®istry); mutex_unlock(&rcu_gp_lock); _rcu_thread_online(); } @@ -343,7 +344,7 @@ void rcu_unregister_thread(void) */ _rcu_thread_offline(); mutex_lock(&rcu_gp_lock); - cds_list_del(&rcu_reader.node); + cds_list_del(&URCU_TLS(rcu_reader).node); mutex_unlock(&rcu_gp_lock); } diff --git a/urcu.c b/urcu.c index 3948629..5fb4db8 100644 --- a/urcu.c +++ b/urcu.c @@ -40,6 +40,7 @@ #include "urcu/map/urcu.h" #include "urcu/static/urcu.h" #include "urcu-pointer.h" +#include "urcu/tls-compat.h" /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ #undef _LGPL_SOURCE @@ -94,11 +95,11 @@ unsigned long rcu_gp_ctr = RCU_GP_COUNT; * Written to only by each individual reader. Read by both the reader and the * writers. */ -struct rcu_reader __thread rcu_reader; +DEFINE_URCU_TLS(struct rcu_reader, rcu_reader); #ifdef DEBUG_YIELD unsigned int yield_active; -unsigned int __thread rand_yield; +DEFINE_URCU_TLS(unsigned int, rand_yield); #endif static CDS_LIST_HEAD(registry); @@ -120,9 +121,9 @@ static void mutex_lock(pthread_mutex_t *mutex) perror("Error in pthread mutex lock"); exit(-1); } - if (CMM_LOAD_SHARED(rcu_reader.need_mb)) { + if (CMM_LOAD_SHARED(URCU_TLS(rcu_reader).need_mb)) { cmm_smp_mb(); - _CMM_STORE_SHARED(rcu_reader.need_mb, 0); + _CMM_STORE_SHARED(URCU_TLS(rcu_reader).need_mb, 0); cmm_smp_mb(); } poll(NULL,0,10); @@ -245,7 +246,7 @@ void update_counter_and_wait(void) cmm_smp_mb(); /* - * Wait for each thread rcu_reader.ctr count to become 0. + * Wait for each thread URCU_TLS(rcu_reader).ctr count to become 0. */ for (;;) { wait_loops++; @@ -277,7 +278,8 @@ void update_counter_and_wait(void) #else /* #ifndef HAS_INCOHERENT_CACHES */ /* * BUSY-LOOP. Force the reader thread to commit its - * rcu_reader.ctr update to memory if we wait for too long. + * URCU_TLS(rcu_reader).ctr update to memory if we wait + * for too long. */ if (cds_list_empty(®istry)) { if (wait_loops == RCU_QS_ACTIVE_ATTEMPTS) { @@ -328,7 +330,7 @@ void synchronize_rcu(void) * committing next rcu_gp_ctr update to memory. Failure to do so could * result in the writer waiting forever while new readers are always * accessing data (no progress). Enforce compiler-order of load - * rcu_reader ctr before store to rcu_gp_ctr. + * URCU_TLS(rcu_reader).ctr before store to rcu_gp_ctr. */ cmm_barrier(); @@ -368,20 +370,20 @@ void rcu_read_unlock(void) void rcu_register_thread(void) { - rcu_reader.tid = pthread_self(); - assert(rcu_reader.need_mb == 0); - assert(!(rcu_reader.ctr & RCU_GP_CTR_NEST_MASK)); + URCU_TLS(rcu_reader).tid = pthread_self(); + assert(URCU_TLS(rcu_reader).need_mb == 0); + assert(!(URCU_TLS(rcu_reader).ctr & RCU_GP_CTR_NEST_MASK)); mutex_lock(&rcu_gp_lock); rcu_init(); /* In case gcc does not support constructor attribute */ - cds_list_add(&rcu_reader.node, ®istry); + cds_list_add(&URCU_TLS(rcu_reader).node, ®istry); mutex_unlock(&rcu_gp_lock); } void rcu_unregister_thread(void) { mutex_lock(&rcu_gp_lock); - cds_list_del(&rcu_reader.node); + cds_list_del(&URCU_TLS(rcu_reader).node); mutex_unlock(&rcu_gp_lock); } @@ -405,7 +407,7 @@ static void sigrcu_handler(int signo, siginfo_t *siginfo, void *context) * executed on. */ cmm_smp_mb(); - _CMM_STORE_SHARED(rcu_reader.need_mb, 0); + _CMM_STORE_SHARED(URCU_TLS(rcu_reader).need_mb, 0); cmm_smp_mb(); } diff --git a/urcu/static/urcu-bp.h b/urcu/static/urcu-bp.h index 8d22163..e7b2eda 100644 --- a/urcu/static/urcu-bp.h +++ b/urcu/static/urcu-bp.h @@ -38,6 +38,7 @@ #include #include #include +#include /* * This code section can only be included in LGPL 2.1 compatible source code. @@ -74,25 +75,25 @@ extern "C" { #define MAX_SLEEP 50 extern unsigned int yield_active; -extern unsigned int __thread rand_yield; +extern DECLARE_URCU_TLS(unsigned int, rand_yield); static inline void debug_yield_read(void) { if (yield_active & YIELD_READ) - if (rand_r(&rand_yield) & 0x1) - usleep(rand_r(&rand_yield) % MAX_SLEEP); + if (rand_r(&URCU_TLS(rand_yield)) & 0x1) + usleep(rand_r(&URCU_TLS(rand_yield)) % MAX_SLEEP); } static inline void debug_yield_write(void) { if (yield_active & YIELD_WRITE) - if (rand_r(&rand_yield) & 0x1) - usleep(rand_r(&rand_yield) % MAX_SLEEP); + if (rand_r(&URCU_TLS(rand_yield)) & 0x1) + usleep(rand_r(&URCU_TLS(rand_yield)) % MAX_SLEEP); } static inline void debug_yield_init(void) { - rand_yield = time(NULL) ^ pthread_self(); + URCU_TLS(rand_yield) = time(NULL) ^ pthread_self(); } #else static inline void debug_yield_read(void) @@ -144,7 +145,7 @@ struct rcu_reader { * Adds a pointer dereference on the read-side, but won't require to unregister * the reader thread. */ -extern struct rcu_reader __thread *rcu_reader; +extern DECLARE_URCU_TLS(struct rcu_reader *, rcu_reader); static inline int rcu_old_gp_ongoing(long *value) { @@ -166,24 +167,24 @@ static inline void _rcu_read_lock(void) long tmp; /* Check if registered */ - if (caa_unlikely(!rcu_reader)) + if (caa_unlikely(!URCU_TLS(rcu_reader))) rcu_bp_register(); cmm_barrier(); /* Ensure the compiler does not reorder us with mutex */ - tmp = rcu_reader->ctr; + tmp = URCU_TLS(rcu_reader)->ctr; /* * rcu_gp_ctr is * RCU_GP_COUNT | (~RCU_GP_CTR_PHASE or RCU_GP_CTR_PHASE) */ if (caa_likely(!(tmp & RCU_GP_CTR_NEST_MASK))) { - _CMM_STORE_SHARED(rcu_reader->ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); + _CMM_STORE_SHARED(URCU_TLS(rcu_reader)->ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); /* * Set active readers count for outermost nesting level before * accessing the pointer. */ cmm_smp_mb(); } else { - _CMM_STORE_SHARED(rcu_reader->ctr, tmp + RCU_GP_COUNT); + _CMM_STORE_SHARED(URCU_TLS(rcu_reader)->ctr, tmp + RCU_GP_COUNT); } } @@ -193,7 +194,7 @@ static inline void _rcu_read_unlock(void) * Finish using rcu before decrementing the pointer. */ cmm_smp_mb(); - _CMM_STORE_SHARED(rcu_reader->ctr, rcu_reader->ctr - RCU_GP_COUNT); + _CMM_STORE_SHARED(URCU_TLS(rcu_reader)->ctr, URCU_TLS(rcu_reader)->ctr - RCU_GP_COUNT); cmm_barrier(); /* Ensure the compiler does not reorder us with mutex */ } diff --git a/urcu/static/urcu-qsbr.h b/urcu/static/urcu-qsbr.h index 68bfc31..22908a4 100644 --- a/urcu/static/urcu-qsbr.h +++ b/urcu/static/urcu-qsbr.h @@ -42,6 +42,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -74,25 +75,25 @@ extern "C" { #define MAX_SLEEP 50 extern unsigned int yield_active; -extern unsigned int __thread rand_yield; +extern DECLARE_URCU_TLS(unsigned int, rand_yield); static inline void debug_yield_read(void) { if (yield_active & YIELD_READ) - if (rand_r(&rand_yield) & 0x1) - usleep(rand_r(&rand_yield) % MAX_SLEEP); + if (rand_r(&URCU_TLS(rand_yield)) & 0x1) + usleep(rand_r(&URCU_TLS(rand_yield)) % MAX_SLEEP); } static inline void debug_yield_write(void) { if (yield_active & YIELD_WRITE) - if (rand_r(&rand_yield) & 0x1) - usleep(rand_r(&rand_yield) % MAX_SLEEP); + if (rand_r(&URCU_TLS(rand_yield)) & 0x1) + usleep(rand_r(&URCU_TLS(rand_yield)) % MAX_SLEEP); } static inline void debug_yield_init(void) { - rand_yield = time(NULL) ^ pthread_self(); + URCU_TLS(rand_yield) = time(NULL) ^ pthread_self(); } #else static inline void debug_yield_read(void) @@ -128,7 +129,7 @@ struct rcu_reader { pthread_t tid; }; -extern struct rcu_reader __thread rcu_reader; +extern DECLARE_URCU_TLS(struct rcu_reader, rcu_reader); extern int32_t gp_futex; @@ -137,8 +138,8 @@ extern int32_t gp_futex; */ static inline void wake_up_gp(void) { - if (caa_unlikely(_CMM_LOAD_SHARED(rcu_reader.waiting))) { - _CMM_STORE_SHARED(rcu_reader.waiting, 0); + if (caa_unlikely(_CMM_LOAD_SHARED(URCU_TLS(rcu_reader).waiting))) { + _CMM_STORE_SHARED(URCU_TLS(rcu_reader).waiting, 0); cmm_smp_mb(); if (uatomic_read(&gp_futex) != -1) return; @@ -158,7 +159,7 @@ static inline int rcu_gp_ongoing(unsigned long *ctr) static inline void _rcu_read_lock(void) { - rcu_assert(rcu_reader.ctr); + rcu_assert(URCU_TLS(rcu_reader).ctr); } static inline void _rcu_read_unlock(void) @@ -168,8 +169,8 @@ static inline void _rcu_read_unlock(void) static inline void _rcu_quiescent_state(void) { cmm_smp_mb(); - _CMM_STORE_SHARED(rcu_reader.ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); - cmm_smp_mb(); /* write rcu_reader.ctr before read futex */ + _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); + cmm_smp_mb(); /* write URCU_TLS(rcu_reader).ctr before read futex */ wake_up_gp(); cmm_smp_mb(); } @@ -177,8 +178,8 @@ static inline void _rcu_quiescent_state(void) static inline void _rcu_thread_offline(void) { cmm_smp_mb(); - CMM_STORE_SHARED(rcu_reader.ctr, 0); - cmm_smp_mb(); /* write rcu_reader.ctr before read futex */ + CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, 0); + cmm_smp_mb(); /* write URCU_TLS(rcu_reader).ctr before read futex */ wake_up_gp(); cmm_barrier(); /* Ensure the compiler does not reorder us with mutex */ } @@ -186,7 +187,7 @@ static inline void _rcu_thread_offline(void) static inline void _rcu_thread_online(void) { cmm_barrier(); /* Ensure the compiler does not reorder us with mutex */ - _CMM_STORE_SHARED(rcu_reader.ctr, CMM_LOAD_SHARED(rcu_gp_ctr)); + _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, CMM_LOAD_SHARED(rcu_gp_ctr)); cmm_smp_mb(); } diff --git a/urcu/static/urcu.h b/urcu/static/urcu.h index 7ae0185..f27f8b6 100644 --- a/urcu/static/urcu.h +++ b/urcu/static/urcu.h @@ -40,6 +40,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -121,25 +122,25 @@ extern "C" { #endif extern unsigned int yield_active; -extern unsigned int __thread rand_yield; +extern DECLARE_URCU_TLS(unsigned int, rand_yield); static inline void debug_yield_read(void) { if (yield_active & YIELD_READ) - if (rand_r(&rand_yield) & 0x1) - usleep(rand_r(&rand_yield) % MAX_SLEEP); + if (rand_r(&URCU_TLS(rand_yield)) & 0x1) + usleep(rand_r(&URCU_TLS(rand_yield)) % MAX_SLEEP); } static inline void debug_yield_write(void) { if (yield_active & YIELD_WRITE) - if (rand_r(&rand_yield) & 0x1) - usleep(rand_r(&rand_yield) % MAX_SLEEP); + if (rand_r(&URCU_TLS(rand_yield)) & 0x1) + usleep(rand_r(&URCU_TLS(rand_yield)) % MAX_SLEEP); } static inline void debug_yield_init(void) { - rand_yield = time(NULL) ^ (unsigned long) pthread_self(); + URCU_TLS(rand_yield) = time(NULL) ^ (unsigned long) pthread_self(); } #else static inline void debug_yield_read(void) @@ -222,7 +223,7 @@ struct rcu_reader { pthread_t tid; }; -extern struct rcu_reader __thread rcu_reader; +extern DECLARE_URCU_TLS(struct rcu_reader, rcu_reader); extern int32_t gp_futex; @@ -256,20 +257,20 @@ static inline void _rcu_read_lock(void) unsigned long tmp; cmm_barrier(); /* Ensure the compiler does not reorder us with mutex */ - tmp = rcu_reader.ctr; + tmp = URCU_TLS(rcu_reader).ctr; /* * rcu_gp_ctr is * RCU_GP_COUNT | (~RCU_GP_CTR_PHASE or RCU_GP_CTR_PHASE) */ if (caa_likely(!(tmp & RCU_GP_CTR_NEST_MASK))) { - _CMM_STORE_SHARED(rcu_reader.ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); + _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); /* * Set active readers count for outermost nesting level before * accessing the pointer. See smp_mb_master(). */ smp_mb_slave(RCU_MB_GROUP); } else { - _CMM_STORE_SHARED(rcu_reader.ctr, tmp + RCU_GP_COUNT); + _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, tmp + RCU_GP_COUNT); } } @@ -277,19 +278,19 @@ static inline void _rcu_read_unlock(void) { unsigned long tmp; - tmp = rcu_reader.ctr; + tmp = URCU_TLS(rcu_reader).ctr; /* * Finish using rcu before decrementing the pointer. * See smp_mb_master(). */ if (caa_likely((tmp & RCU_GP_CTR_NEST_MASK) == RCU_GP_COUNT)) { smp_mb_slave(RCU_MB_GROUP); - _CMM_STORE_SHARED(rcu_reader.ctr, rcu_reader.ctr - RCU_GP_COUNT); - /* write rcu_reader.ctr before read futex */ + _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, URCU_TLS(rcu_reader).ctr - RCU_GP_COUNT); + /* write URCU_TLS(rcu_reader).ctr before read futex */ smp_mb_slave(RCU_MB_GROUP); wake_up_gp(); } else { - _CMM_STORE_SHARED(rcu_reader.ctr, rcu_reader.ctr - RCU_GP_COUNT); + _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, URCU_TLS(rcu_reader).ctr - RCU_GP_COUNT); } cmm_barrier(); /* Ensure the compiler does not reorder us with mutex */ } -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From marek.vavrusa at nic.cz Wed May 16 10:22:17 2012 From: marek.vavrusa at nic.cz (=?UTF-8?Q?Marek_Vavru=C5=A1a?=) Date: Wed, 16 May 2012 16:22:17 +0200 Subject: [lttng-dev] [RFC PATCH urcu] Use urcu/tls-compat.h In-Reply-To: <20120516135802.GC29920@Krystal> References: <20120516135802.GC29920@Krystal> Message-ID: Matthieu, thanks a lot for sorting the issues with the patch. Things have been very busy for last couple weeks. Anyway there's another problem with NetBSD 5, as it has implemented mremap() call. Unfortunately the syntax is different from Linux one. I have made a patch that just prevents name clash, but that's not 100% correct. liburcu should probably detect mremap version on configure and then use the correct implementation via wrapper. Kind regards, Marek On 16 May 2012 15:58, Mathieu Desnoyers wrote: > Provides compatibility for OpenBSD, NetBSD and Darwin. > > Suggested-by: Marek Vavru?a > Signed-off-by: Mathieu Desnoyers > --- > diff --git a/tests/test_mutex.c b/tests/test_mutex.c > index 3f84bbf..ba184a4 100644 > --- a/tests/test_mutex.c > +++ b/tests/test_mutex.c > @@ -35,6 +35,7 @@ > ?#include > > ?#include > +#include > > ?#ifdef __linux__ > ?#include > @@ -155,8 +156,8 @@ static int test_duration_read(void) > ? ? ? ?return !test_stop; > ?} > > -static unsigned long long __thread nr_writes; > -static unsigned long long __thread nr_reads; > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > ?static > ?unsigned long long __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *tot_nr_writes; > @@ -208,12 +209,12 @@ void *thr_reader(void *data) > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > ? ? ? ? ? ? ? ?pthread_mutex_unlock(&lock); > - ? ? ? ? ? ? ? nr_reads++; > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ?} > > - ? ? ? tot_nr_reads[tidx] = nr_reads; > + ? ? ? tot_nr_reads[tidx] = URCU_TLS(nr_reads); > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > ? ? ? ?return ((void*)1); > @@ -241,7 +242,7 @@ void *thr_writer(void *data) > ? ? ? ? ? ? ? ?if (caa_unlikely(wduration)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wduration); > ? ? ? ? ? ? ? ?pthread_mutex_unlock(&lock); > - ? ? ? ? ? ? ? nr_writes++; > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > @@ -250,7 +251,7 @@ void *thr_writer(void *data) > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > - ? ? ? tot_nr_writes[wtidx] = nr_writes; > + ? ? ? tot_nr_writes[wtidx] = URCU_TLS(nr_writes); > ? ? ? ?return ((void*)2); > ?} > > diff --git a/tests/test_perthreadlock.c b/tests/test_perthreadlock.c > index fa9c89a..6ff0412 100644 > --- a/tests/test_perthreadlock.c > +++ b/tests/test_perthreadlock.c > @@ -35,6 +35,7 @@ > ?#include > > ?#include > +#include > > ?#ifdef __linux__ > ?#include > @@ -159,8 +160,8 @@ static int test_duration_read(void) > ? ? ? ?return !test_stop; > ?} > > -static unsigned long long __thread nr_writes; > -static unsigned long long __thread nr_reads; > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > ?static > ?unsigned long long __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *tot_nr_writes; > @@ -212,12 +213,12 @@ void *thr_reader(void *data) > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > ? ? ? ? ? ? ? ?pthread_mutex_unlock(&per_thread_lock[tidx].lock); > - ? ? ? ? ? ? ? nr_reads++; > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ?} > > - ? ? ? tot_nr_reads[tidx] = nr_reads; > + ? ? ? tot_nr_reads[tidx] = URCU_TLS(nr_reads); > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > ? ? ? ?return ((void*)1); > @@ -250,7 +251,7 @@ void *thr_writer(void *data) > ? ? ? ? ? ? ? ?for (tidx = (long)nr_readers - 1; tidx >= 0; tidx--) { > ? ? ? ? ? ? ? ? ? ? ? ?pthread_mutex_unlock(&per_thread_lock[tidx].lock); > ? ? ? ? ? ? ? ?} > - ? ? ? ? ? ? ? nr_writes++; > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > @@ -259,7 +260,7 @@ void *thr_writer(void *data) > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > - ? ? ? tot_nr_writes[wtidx] = nr_writes; > + ? ? ? tot_nr_writes[wtidx] = URCU_TLS(nr_writes); > ? ? ? ?return ((void*)2); > ?} > > diff --git a/tests/test_rwlock.c b/tests/test_rwlock.c > index 34d8c07..ccbc9d1 100644 > --- a/tests/test_rwlock.c > +++ b/tests/test_rwlock.c > @@ -35,6 +35,7 @@ > ?#include > > ?#include > +#include > > ?#ifdef __linux__ > ?#include > @@ -156,8 +157,8 @@ static int test_duration_read(void) > ? ? ? ?return !test_stop; > ?} > > -static unsigned long long __thread nr_writes; > -static unsigned long long __thread nr_reads; > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > ?static unsigned int nr_readers; > ?static unsigned int nr_writers; > @@ -204,12 +205,12 @@ void *thr_reader(void *_count) > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > ? ? ? ? ? ? ? ?pthread_rwlock_unlock(&lock); > - ? ? ? ? ? ? ? nr_reads++; > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ?} > > - ? ? ? *count = nr_reads; > + ? ? ? *count = URCU_TLS(nr_reads); > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > ? ? ? ?return ((void*)1); > @@ -237,7 +238,7 @@ void *thr_writer(void *_count) > ? ? ? ? ? ? ? ?if (caa_unlikely(wduration)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wduration); > ? ? ? ? ? ? ? ?pthread_rwlock_unlock(&lock); > - ? ? ? ? ? ? ? nr_writes++; > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > @@ -246,7 +247,7 @@ void *thr_writer(void *_count) > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > - ? ? ? *count = nr_writes; > + ? ? ? *count = URCU_TLS(nr_writes); > ? ? ? ?return ((void*)2); > ?} > > diff --git a/tests/test_urcu.c b/tests/test_urcu.c > index 870f133..1b1b94b 100644 > --- a/tests/test_urcu.c > +++ b/tests/test_urcu.c > @@ -35,6 +35,7 @@ > ?#include > > ?#include > +#include > > ?#ifdef __linux__ > ?#include > @@ -154,8 +155,8 @@ static int test_duration_read(void) > ? ? ? ?return !test_stop; > ?} > > -static unsigned long long __thread nr_writes; > -static unsigned long long __thread nr_reads; > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > ?static unsigned int nr_readers; > ?static unsigned int nr_writers; > @@ -242,7 +243,7 @@ void *thr_reader(void *_count) > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > ? ? ? ? ? ? ? ?rcu_read_unlock(); > - ? ? ? ? ? ? ? nr_reads++; > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ?} > @@ -253,7 +254,7 @@ void *thr_reader(void *_count) > ? ? ? ?rcu_register_thread(); > ? ? ? ?rcu_unregister_thread(); > > - ? ? ? *count = nr_reads; > + ? ? ? *count = URCU_TLS(nr_reads); > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > ? ? ? ?return ((void*)1); > @@ -287,7 +288,7 @@ void *thr_writer(void *_count) > ? ? ? ? ? ? ? ? ? ? ? ?old->a = 0; > ? ? ? ? ? ? ? ?test_array_free(old); > ? ? ? ? ? ? ? ?rcu_copy_mutex_unlock(); > - ? ? ? ? ? ? ? nr_writes++; > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > @@ -296,7 +297,7 @@ void *thr_writer(void *_count) > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > - ? ? ? *count = nr_writes; > + ? ? ? *count = URCU_TLS(nr_writes); > ? ? ? ?return ((void*)2); > ?} > > diff --git a/tests/test_urcu_assign.c b/tests/test_urcu_assign.c > index 42d70c2..31e22e5 100644 > --- a/tests/test_urcu_assign.c > +++ b/tests/test_urcu_assign.c > @@ -35,6 +35,7 @@ > ?#include > > ?#include > +#include > > ?#ifdef __linux__ > ?#include > @@ -154,8 +155,8 @@ static int test_duration_read(void) > ? ? ? ?return !test_stop; > ?} > > -static unsigned long long __thread nr_writes; > -static unsigned long long __thread nr_reads; > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > ?static unsigned int nr_readers; > ?static unsigned int nr_writers; > @@ -242,14 +243,14 @@ void *thr_reader(void *_count) > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > ? ? ? ? ? ? ? ?rcu_read_unlock(); > - ? ? ? ? ? ? ? nr_reads++; > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ?} > > ? ? ? ?rcu_unregister_thread(); > > - ? ? ? *count = nr_reads; > + ? ? ? *count = URCU_TLS(nr_reads); > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > ? ? ? ?return ((void*)1); > @@ -284,7 +285,7 @@ void *thr_writer(void *_count) > ? ? ? ? ? ? ? ? ? ? ? ?old->a = 0; > ? ? ? ? ? ? ? ?test_array_free(old); > ? ? ? ? ? ? ? ?rcu_copy_mutex_unlock(); > - ? ? ? ? ? ? ? nr_writes++; > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > @@ -293,7 +294,7 @@ void *thr_writer(void *_count) > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > - ? ? ? *count = nr_writes; > + ? ? ? *count = URCU_TLS(nr_writes); > ? ? ? ?return ((void*)2); > ?} > > diff --git a/tests/test_urcu_bp.c b/tests/test_urcu_bp.c > index 857913f..41caeb0 100644 > --- a/tests/test_urcu_bp.c > +++ b/tests/test_urcu_bp.c > @@ -35,6 +35,7 @@ > ?#include > > ?#include > +#include > > ?#ifdef __linux__ > ?#include > @@ -154,8 +155,8 @@ static int test_duration_read(void) > ? ? ? ?return !test_stop; > ?} > > -static unsigned long long __thread nr_writes; > -static unsigned long long __thread nr_reads; > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > ?static unsigned int nr_readers; > ?static unsigned int nr_writers; > @@ -242,14 +243,14 @@ void *thr_reader(void *_count) > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > ? ? ? ? ? ? ? ?rcu_read_unlock(); > - ? ? ? ? ? ? ? nr_reads++; > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ?} > > ? ? ? ?rcu_unregister_thread(); > > - ? ? ? *count = nr_reads; > + ? ? ? *count = URCU_TLS(nr_reads); > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > ? ? ? ?return ((void*)1); > @@ -283,7 +284,7 @@ void *thr_writer(void *_count) > ? ? ? ? ? ? ? ? ? ? ? ?old->a = 0; > ? ? ? ? ? ? ? ?test_array_free(old); > ? ? ? ? ? ? ? ?rcu_copy_mutex_unlock(); > - ? ? ? ? ? ? ? nr_writes++; > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > @@ -292,7 +293,7 @@ void *thr_writer(void *_count) > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > - ? ? ? *count = nr_writes; > + ? ? ? *count = URCU_TLS(nr_writes); > ? ? ? ?return ((void*)2); > ?} > > diff --git a/tests/test_urcu_defer.c b/tests/test_urcu_defer.c > index 1575e9c..cd9780b 100644 > --- a/tests/test_urcu_defer.c > +++ b/tests/test_urcu_defer.c > @@ -35,6 +35,7 @@ > ?#include > > ?#include > +#include > > ?#ifdef __linux__ > ?#include > @@ -155,8 +156,8 @@ static int test_duration_read(void) > ? ? ? ?return !test_stop; > ?} > > -static unsigned long long __thread nr_writes; > -static unsigned long long __thread nr_reads; > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > ?static > ?unsigned long long __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *tot_nr_writes; > @@ -213,14 +214,14 @@ void *thr_reader(void *_count) > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > ? ? ? ? ? ? ? ?rcu_read_unlock(); > - ? ? ? ? ? ? ? nr_reads++; > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ?} > > ? ? ? ?rcu_unregister_thread(); > > - ? ? ? *count = nr_reads; > + ? ? ? *count = URCU_TLS(nr_reads); > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > ? ? ? ?return ((void*)1); > @@ -271,7 +272,7 @@ void *thr_writer(void *data) > ? ? ? ? ? ? ? ?defer_rcu(test_cb2, (void *)-2L); > ? ? ? ? ? ? ? ?defer_rcu(test_cb2, (void *)-4L); > ? ? ? ? ? ? ? ?defer_rcu(test_cb2, (void *)-2L); > - ? ? ? ? ? ? ? nr_writes++; > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > @@ -282,7 +283,7 @@ void *thr_writer(void *data) > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > - ? ? ? tot_nr_writes[wtidx] = nr_writes; > + ? ? ? tot_nr_writes[wtidx] = URCU_TLS(nr_writes); > ? ? ? ?return ((void*)2); > ?} > > diff --git a/tests/test_urcu_gc.c b/tests/test_urcu_gc.c > index 21c5d56..3a42506 100644 > --- a/tests/test_urcu_gc.c > +++ b/tests/test_urcu_gc.c > @@ -35,6 +35,7 @@ > ?#include > > ?#include > +#include > > ?#ifdef __linux__ > ?#include > @@ -163,8 +164,8 @@ static int test_duration_read(void) > ? ? ? ?return !test_stop; > ?} > > -static unsigned long long __thread nr_writes; > -static unsigned long long __thread nr_reads; > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > ?static > ?unsigned long long __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *tot_nr_writes; > @@ -221,14 +222,14 @@ void *thr_reader(void *_count) > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > ? ? ? ? ? ? ? ?rcu_read_unlock(); > - ? ? ? ? ? ? ? nr_reads++; > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ?} > > ? ? ? ?rcu_unregister_thread(); > > - ? ? ? *count = nr_reads; > + ? ? ? *count = URCU_TLS(nr_reads); > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > ? ? ? ?return ((void*)1); > @@ -294,7 +295,7 @@ void *thr_writer(void *data) > ? ? ? ? ? ? ? ?if (caa_unlikely(wduration)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wduration); > ? ? ? ? ? ? ? ?rcu_gc_reclaim(wtidx, old); > - ? ? ? ? ? ? ? nr_writes++; > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > @@ -303,7 +304,7 @@ void *thr_writer(void *data) > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > - ? ? ? tot_nr_writes[wtidx] = nr_writes; > + ? ? ? tot_nr_writes[wtidx] = URCU_TLS(nr_writes); > ? ? ? ?return ((void*)2); > ?} > > diff --git a/tests/test_urcu_hash.c b/tests/test_urcu_hash.c > index 2223413..5710de0 100644 > --- a/tests/test_urcu_hash.c > +++ b/tests/test_urcu_hash.c > @@ -82,13 +82,13 @@ int (*get_populate_hash_cb(void))(void) > ? ? ? ?return test_hash_cb[test_choice].populate_hash; > ?} > > -unsigned int __thread rand_lookup; > -unsigned long __thread nr_add; > -unsigned long __thread nr_addexist; > -unsigned long __thread nr_del; > -unsigned long __thread nr_delnoent; > -unsigned long __thread lookup_fail; > -unsigned long __thread lookup_ok; > +DEFINE_URCU_TLS(unsigned int, rand_lookup); > +DEFINE_URCU_TLS(unsigned long, nr_add); > +DEFINE_URCU_TLS(unsigned long, nr_addexist); > +DEFINE_URCU_TLS(unsigned long, nr_del); > +DEFINE_URCU_TLS(unsigned long, nr_delnoent); > +DEFINE_URCU_TLS(unsigned long, lookup_fail); > +DEFINE_URCU_TLS(unsigned long, lookup_ok); > > ?struct cds_lfht *test_ht; > > @@ -126,8 +126,8 @@ int use_affinity = 0; > > ?pthread_mutex_t affinity_mutex = PTHREAD_MUTEX_INITIALIZER; > > -unsigned long long __thread nr_writes; > -unsigned long long __thread nr_reads; > +DEFINE_URCU_TLS(unsigned long long, nr_writes); > +DEFINE_URCU_TLS(unsigned long long, nr_reads); > > ?unsigned int nr_readers; > ?unsigned int nr_writers; > diff --git a/tests/test_urcu_hash.h b/tests/test_urcu_hash.h > index 083e71c..fe13c36 100644 > --- a/tests/test_urcu_hash.h > +++ b/tests/test_urcu_hash.h > @@ -37,6 +37,8 @@ > ?#include > ?#include > > +#include > + > ?#ifdef __linux__ > ?#include > ?#endif > @@ -102,13 +104,13 @@ struct wr_count { > ? ? ? ?unsigned long remove; > ?}; > > -extern unsigned int __thread rand_lookup; > -extern unsigned long __thread nr_add; > -extern unsigned long __thread nr_addexist; > -extern unsigned long __thread nr_del; > -extern unsigned long __thread nr_delnoent; > -extern unsigned long __thread lookup_fail; > -extern unsigned long __thread lookup_ok; > +extern DECLARE_URCU_TLS(unsigned int, rand_lookup); > +extern DECLARE_URCU_TLS(unsigned long, nr_add); > +extern DECLARE_URCU_TLS(unsigned long, nr_addexist); > +extern DECLARE_URCU_TLS(unsigned long, nr_del); > +extern DECLARE_URCU_TLS(unsigned long, nr_delnoent); > +extern DECLARE_URCU_TLS(unsigned long, lookup_fail); > +extern DECLARE_URCU_TLS(unsigned long, lookup_ok); > > ?extern struct cds_lfht *test_ht; > > @@ -214,8 +216,8 @@ static inline int test_duration_read(void) > ? ? ? ?return !test_stop; > ?} > > -extern unsigned long long __thread nr_writes; > -extern unsigned long long __thread nr_reads; > +extern DECLARE_URCU_TLS(unsigned long long, nr_writes); > +extern DECLARE_URCU_TLS(unsigned long long, nr_reads); > > ?extern unsigned int nr_readers; > ?extern unsigned int nr_writers; > diff --git a/tests/test_urcu_hash_rw.c b/tests/test_urcu_hash_rw.c > index 7310344..a789236 100644 > --- a/tests/test_urcu_hash_rw.c > +++ b/tests/test_urcu_hash_rw.c > @@ -80,7 +80,7 @@ void *test_hash_rw_thr_reader(void *_count) > ? ? ? ?for (;;) { > ? ? ? ? ? ? ? ?rcu_read_lock(); > ? ? ? ? ? ? ? ?cds_lfht_test_lookup(test_ht, > - ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&rand_lookup) % lookup_pool_size) + lookup_pool_offset), > + ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % lookup_pool_size) + lookup_pool_offset), > ? ? ? ? ? ? ? ? ? ? ? ?sizeof(void *), &iter); > ? ? ? ? ? ? ? ?node = cds_lfht_iter_get_test_node(&iter); > ? ? ? ? ? ? ? ?if (node == NULL) { > @@ -88,28 +88,29 @@ void *test_hash_rw_thr_reader(void *_count) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?printf("[ERROR] Lookup cannot find initial node.\n"); > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?exit(-1); > ? ? ? ? ? ? ? ? ? ? ? ?} > - ? ? ? ? ? ? ? ? ? ? ? lookup_fail++; > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(lookup_fail)++; > ? ? ? ? ? ? ? ?} else { > - ? ? ? ? ? ? ? ? ? ? ? lookup_ok++; > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(lookup_ok)++; > ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ?debug_yield_read(); > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > ? ? ? ? ? ? ? ?rcu_read_unlock(); > - ? ? ? ? ? ? ? nr_reads++; > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > - ? ? ? ? ? ? ? if (caa_unlikely((nr_reads & ((1 << 10) - 1)) == 0)) > + ? ? ? ? ? ? ? if (caa_unlikely((URCU_TLS(nr_reads) & ((1 << 10) - 1)) == 0)) > ? ? ? ? ? ? ? ? ? ? ? ?rcu_quiescent_state(); > ? ? ? ?} > > ? ? ? ?rcu_unregister_thread(); > > - ? ? ? *count = nr_reads; > + ? ? ? *count = URCU_TLS(nr_reads); > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > ? ? ? ?printf_verbose("readid : %lx, lookupfail %lu, lookupok %lu\n", > - ? ? ? ? ? ? ? ? ? ? ? pthread_self(), lookup_fail, lookup_ok); > + ? ? ? ? ? ? ? ? ? ? ? pthread_self(), URCU_TLS(lookup_fail), > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(lookup_ok)); > ? ? ? ?return ((void*)1); > > ?} > @@ -136,10 +137,10 @@ void *test_hash_rw_thr_writer(void *_count) > > ? ? ? ?for (;;) { > ? ? ? ? ? ? ? ?if ((addremove == AR_ADD || add_only) > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? || (addremove == AR_RANDOM && rand_r(&rand_lookup) & 1)) { > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? || (addremove == AR_RANDOM && rand_r(&URCU_TLS(rand_lookup)) & 1)) { > ? ? ? ? ? ? ? ? ? ? ? ?node = malloc(sizeof(struct lfht_test_node)); > ? ? ? ? ? ? ? ? ? ? ? ?lfht_test_node_init(node, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&rand_lookup) % write_pool_size) + write_pool_offset), > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset), > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(void *)); > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_lock(); > ? ? ? ? ? ? ? ? ? ? ? ?if (add_unique) { > @@ -159,36 +160,36 @@ void *test_hash_rw_thr_writer(void *_count) > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_unlock(); > ? ? ? ? ? ? ? ? ? ? ? ?if (add_unique && ret_node != &node->node) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?free(node); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_addexist++; > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_addexist)++; > ? ? ? ? ? ? ? ? ? ? ? ?} else { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (add_replace && ret_node) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?call_rcu(&to_test_node(ret_node)->head, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?free_node_cb); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_addexist++; > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_addexist)++; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} else { > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_add++; > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_add)++; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ?} else { > ? ? ? ? ? ? ? ? ? ? ? ?/* May delete */ > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_lock(); > ? ? ? ? ? ? ? ? ? ? ? ?cds_lfht_test_lookup(test_ht, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&rand_lookup) % write_pool_size) + write_pool_offset), > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset), > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(void *), &iter); > ? ? ? ? ? ? ? ? ? ? ? ?ret = cds_lfht_del(test_ht, cds_lfht_iter_get_node(&iter)); > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_unlock(); > ? ? ? ? ? ? ? ? ? ? ? ?if (ret == 0) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?node = cds_lfht_iter_get_test_node(&iter); > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?call_rcu(&node->head, free_node_cb); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_del++; > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_del)++; > ? ? ? ? ? ? ? ? ? ? ? ?} else > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_delnoent++; > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_delnoent)++; > ? ? ? ? ? ? ? ?} > ?#if 0 > - ? ? ? ? ? ? ? //if (nr_writes % 100000 == 0) { > - ? ? ? ? ? ? ? if (nr_writes % 1000 == 0) { > + ? ? ? ? ? ? ? //if (URCU_TLS(nr_writes) % 100000 == 0) { > + ? ? ? ? ? ? ? if (URCU_TLS(nr_writes) % 1000 == 0) { > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_lock(); > - ? ? ? ? ? ? ? ? ? ? ? if (rand_r(&rand_lookup) & 1) { > + ? ? ? ? ? ? ? ? ? ? ? if (rand_r(&URCU_TLS(rand_lookup)) & 1) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ht_resize(test_ht, 1); > ? ? ? ? ? ? ? ? ? ? ? ?} else { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ht_resize(test_ht, -1); > @@ -196,12 +197,12 @@ void *test_hash_rw_thr_writer(void *_count) > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_unlock(); > ? ? ? ? ? ? ? ?} > ?#endif //0 > - ? ? ? ? ? ? ? nr_writes++; > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wdelay); > - ? ? ? ? ? ? ? if (caa_unlikely((nr_writes & ((1 << 10) - 1)) == 0)) > + ? ? ? ? ? ? ? if (caa_unlikely((URCU_TLS(nr_writes) & ((1 << 10) - 1)) == 0)) > ? ? ? ? ? ? ? ? ? ? ? ?rcu_quiescent_state(); > ? ? ? ?} > > @@ -210,12 +211,13 @@ void *test_hash_rw_thr_writer(void *_count) > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > ? ? ? ?printf_verbose("info id %lx: nr_add %lu, nr_addexist %lu, nr_del %lu, " > - ? ? ? ? ? ? ? ? ? ? ? "nr_delnoent %lu\n", pthread_self(), nr_add, > - ? ? ? ? ? ? ? ? ? ? ? nr_addexist, nr_del, nr_delnoent); > - ? ? ? count->update_ops = nr_writes; > - ? ? ? count->add = nr_add; > - ? ? ? count->add_exist = nr_addexist; > - ? ? ? count->remove = nr_del; > + ? ? ? ? ? ? ? ? ? ? ? "nr_delnoent %lu\n", pthread_self(), URCU_TLS(nr_add), > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_addexist), URCU_TLS(nr_del), > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_delnoent)); > + ? ? ? count->update_ops = URCU_TLS(nr_writes); > + ? ? ? count->add = URCU_TLS(nr_add); > + ? ? ? count->add_exist = URCU_TLS(nr_addexist); > + ? ? ? count->remove = URCU_TLS(nr_del); > ? ? ? ?return ((void*)2); > ?} > > @@ -235,10 +237,10 @@ int test_hash_rw_populate_hash(void) > ?"larger random pool (-p option). This may take a while...\n", init_populate, init_pool_size); > ? ? ? ?} > > - ? ? ? while (nr_add < init_populate) { > + ? ? ? while (URCU_TLS(nr_add) < init_populate) { > ? ? ? ? ? ? ? ?node = malloc(sizeof(struct lfht_test_node)); > ? ? ? ? ? ? ? ?lfht_test_node_init(node, > - ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&rand_lookup) % init_pool_size) + init_pool_offset), > + ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % init_pool_size) + init_pool_offset), > ? ? ? ? ? ? ? ? ? ? ? ?sizeof(void *)); > ? ? ? ? ? ? ? ?rcu_read_lock(); > ? ? ? ? ? ? ? ?if (add_unique) { > @@ -258,16 +260,16 @@ int test_hash_rw_populate_hash(void) > ? ? ? ? ? ? ? ?rcu_read_unlock(); > ? ? ? ? ? ? ? ?if (add_unique && ret_node != &node->node) { > ? ? ? ? ? ? ? ? ? ? ? ?free(node); > - ? ? ? ? ? ? ? ? ? ? ? nr_addexist++; > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_addexist)++; > ? ? ? ? ? ? ? ?} else { > ? ? ? ? ? ? ? ? ? ? ? ?if (add_replace && ret_node) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?call_rcu(&to_test_node(ret_node)->head, free_node_cb); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_addexist++; > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_addexist)++; > ? ? ? ? ? ? ? ? ? ? ? ?} else { > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_add++; > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_add)++; > ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ?} > - ? ? ? ? ? ? ? nr_writes++; > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > ? ? ? ?} > ? ? ? ?return 0; > ?} > diff --git a/tests/test_urcu_hash_unique.c b/tests/test_urcu_hash_unique.c > index c934feb..610f479 100644 > --- a/tests/test_urcu_hash_unique.c > +++ b/tests/test_urcu_hash_unique.c > @@ -98,20 +98,21 @@ void *test_hash_unique_thr_reader(void *_count) > ? ? ? ? ? ? ? ?debug_yield_read(); > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > - ? ? ? ? ? ? ? nr_reads++; > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > - ? ? ? ? ? ? ? if (caa_unlikely((nr_reads & ((1 << 10) - 1)) == 0)) > + ? ? ? ? ? ? ? if (caa_unlikely((URCU_TLS(nr_reads) & ((1 << 10) - 1)) == 0)) > ? ? ? ? ? ? ? ? ? ? ? ?rcu_quiescent_state(); > ? ? ? ?} > > ? ? ? ?rcu_unregister_thread(); > > - ? ? ? *count = nr_reads; > + ? ? ? *count = URCU_TLS(nr_reads); > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > ? ? ? ?printf_verbose("readid : %lx, lookupfail %lu, lookupok %lu\n", > - ? ? ? ? ? ? ? ? ? ? ? pthread_self(), lookup_fail, lookup_ok); > + ? ? ? ? ? ? ? ? ? ? ? pthread_self(), URCU_TLS(lookup_fail), > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(lookup_ok)); > ? ? ? ?return ((void*)1); > > ?} > @@ -142,13 +143,13 @@ void *test_hash_unique_thr_writer(void *_count) > ? ? ? ? ? ? ? ? * add unique/add replace with new node key from range. > ? ? ? ? ? ? ? ? */ > ? ? ? ? ? ? ? ?if (1 || (addremove == AR_ADD || add_only) > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? || (addremove == AR_RANDOM && rand_r(&rand_lookup) & 1)) { > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? || (addremove == AR_RANDOM && rand_r(&URCU_TLS(rand_lookup)) & 1)) { > ? ? ? ? ? ? ? ? ? ? ? ?node = malloc(sizeof(struct lfht_test_node)); > ? ? ? ? ? ? ? ? ? ? ? ?lfht_test_node_init(node, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&rand_lookup) % write_pool_size) + write_pool_offset), > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset), > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(void *)); > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_lock(); > - ? ? ? ? ? ? ? ? ? ? ? loc_add_unique = rand_r(&rand_lookup) & 1; > + ? ? ? ? ? ? ? ? ? ? ? loc_add_unique = rand_r(&URCU_TLS(rand_lookup)) & 1; > ? ? ? ? ? ? ? ? ? ? ? ?if (loc_add_unique) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ret_node = cds_lfht_add_unique(test_ht, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?test_hash(node->key, node->key_len, TEST_HASH_SEED), > @@ -168,39 +169,39 @@ void *test_hash_unique_thr_writer(void *_count) > ? ? ? ? ? ? ? ? ? ? ? ?if (loc_add_unique) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (ret_node != &node->node) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?free(node); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_addexist++; > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_addexist)++; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} else { > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_add++; > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_add)++; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ? ? ? ? ?} else { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (ret_node) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?call_rcu(&to_test_node(ret_node)->head, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?free_node_cb); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_addexist++; > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_addexist)++; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} else { > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_add++; > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_add)++; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ?} else { > ? ? ? ? ? ? ? ? ? ? ? ?/* May delete */ > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_lock(); > ? ? ? ? ? ? ? ? ? ? ? ?cds_lfht_test_lookup(test_ht, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&rand_lookup) % write_pool_size) + write_pool_offset), > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset), > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(void *), &iter); > ? ? ? ? ? ? ? ? ? ? ? ?ret = cds_lfht_del(test_ht, cds_lfht_iter_get_node(&iter)); > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_unlock(); > ? ? ? ? ? ? ? ? ? ? ? ?if (ret == 0) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?node = cds_lfht_iter_get_test_node(&iter); > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?call_rcu(&node->head, free_node_cb); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_del++; > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_del)++; > ? ? ? ? ? ? ? ? ? ? ? ?} else > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_delnoent++; > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_delnoent)++; > ? ? ? ? ? ? ? ?} > ?#if 0 > - ? ? ? ? ? ? ? //if (nr_writes % 100000 == 0) { > - ? ? ? ? ? ? ? if (nr_writes % 1000 == 0) { > + ? ? ? ? ? ? ? //if (URCU_TLS(nr_writes) % 100000 == 0) { > + ? ? ? ? ? ? ? if (URCU_TLS(nr_writes) % 1000 == 0) { > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_lock(); > - ? ? ? ? ? ? ? ? ? ? ? if (rand_r(&rand_lookup) & 1) { > + ? ? ? ? ? ? ? ? ? ? ? if (rand_r(&URCU_TLS(rand_lookup)) & 1) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ht_resize(test_ht, 1); > ? ? ? ? ? ? ? ? ? ? ? ?} else { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ht_resize(test_ht, -1); > @@ -208,12 +209,12 @@ void *test_hash_unique_thr_writer(void *_count) > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_unlock(); > ? ? ? ? ? ? ? ?} > ?#endif //0 > - ? ? ? ? ? ? ? nr_writes++; > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wdelay); > - ? ? ? ? ? ? ? if (caa_unlikely((nr_writes & ((1 << 10) - 1)) == 0)) > + ? ? ? ? ? ? ? if (caa_unlikely((URCU_TLS(nr_writes) & ((1 << 10) - 1)) == 0)) > ? ? ? ? ? ? ? ? ? ? ? ?rcu_quiescent_state(); > ? ? ? ?} > > @@ -222,12 +223,13 @@ void *test_hash_unique_thr_writer(void *_count) > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > ? ? ? ?printf_verbose("info id %lx: nr_add %lu, nr_addexist %lu, nr_del %lu, " > - ? ? ? ? ? ? ? ? ? ? ? "nr_delnoent %lu\n", pthread_self(), nr_add, > - ? ? ? ? ? ? ? ? ? ? ? nr_addexist, nr_del, nr_delnoent); > - ? ? ? count->update_ops = nr_writes; > - ? ? ? count->add = nr_add; > - ? ? ? count->add_exist = nr_addexist; > - ? ? ? count->remove = nr_del; > + ? ? ? ? ? ? ? ? ? ? ? "nr_delnoent %lu\n", pthread_self(), URCU_TLS(nr_add), > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_addexist), URCU_TLS(nr_del), > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_delnoent)); > + ? ? ? count->update_ops = URCU_TLS(nr_writes); > + ? ? ? count->add = URCU_TLS(nr_add); > + ? ? ? count->add_exist = URCU_TLS(nr_addexist); > + ? ? ? count->remove = URCU_TLS(nr_del); > ? ? ? ?return ((void*)2); > ?} > > @@ -247,10 +249,10 @@ int test_hash_unique_populate_hash(void) > ?"larger random pool (-p option). This may take a while...\n", init_populate, init_pool_size); > ? ? ? ?} > > - ? ? ? while (nr_add < init_populate) { > + ? ? ? while (URCU_TLS(nr_add) < init_populate) { > ? ? ? ? ? ? ? ?node = malloc(sizeof(struct lfht_test_node)); > ? ? ? ? ? ? ? ?lfht_test_node_init(node, > - ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&rand_lookup) % init_pool_size) + init_pool_offset), > + ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % init_pool_size) + init_pool_offset), > ? ? ? ? ? ? ? ? ? ? ? ?sizeof(void *)); > ? ? ? ? ? ? ? ?rcu_read_lock(); > ? ? ? ? ? ? ? ?ret_node = cds_lfht_add_replace(test_ht, > @@ -259,11 +261,11 @@ int test_hash_unique_populate_hash(void) > ? ? ? ? ? ? ? ?rcu_read_unlock(); > ? ? ? ? ? ? ? ?if (ret_node) { > ? ? ? ? ? ? ? ? ? ? ? ?call_rcu(&to_test_node(ret_node)->head, free_node_cb); > - ? ? ? ? ? ? ? ? ? ? ? nr_addexist++; > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_addexist)++; > ? ? ? ? ? ? ? ?} else { > - ? ? ? ? ? ? ? ? ? ? ? nr_add++; > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_add)++; > ? ? ? ? ? ? ? ?} > - ? ? ? ? ? ? ? nr_writes++; > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > ? ? ? ?} > ? ? ? ?return 0; > ?} > diff --git a/tests/test_urcu_lfq.c b/tests/test_urcu_lfq.c > index 01a2781..66ddd41 100644 > --- a/tests/test_urcu_lfq.c > +++ b/tests/test_urcu_lfq.c > @@ -38,6 +38,7 @@ > ?#include > > ?#include > +#include > > ?#ifdef __linux__ > ?#include > @@ -148,11 +149,11 @@ static int test_duration_enqueue(void) > ? ? ? ?return !test_stop; > ?} > > -static unsigned long long __thread nr_dequeues; > -static unsigned long long __thread nr_enqueues; > +static DEFINE_URCU_TLS(unsigned long long, nr_dequeues); > +static DEFINE_URCU_TLS(unsigned long long, nr_enqueues); > > -static unsigned long long __thread nr_successful_dequeues; > -static unsigned long long __thread nr_successful_enqueues; > +static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); > +static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); > > ?static unsigned int nr_enqueuers; > ?static unsigned int nr_dequeuers; > @@ -188,24 +189,24 @@ void *thr_enqueuer(void *_count) > ? ? ? ? ? ? ? ?rcu_read_lock(); > ? ? ? ? ? ? ? ?cds_lfq_enqueue_rcu(&q, &node->list); > ? ? ? ? ? ? ? ?rcu_read_unlock(); > - ? ? ? ? ? ? ? nr_successful_enqueues++; > + ? ? ? ? ? ? ? URCU_TLS(nr_successful_enqueues)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wdelay); > ?fail: > - ? ? ? ? ? ? ? nr_enqueues++; > + ? ? ? ? ? ? ? URCU_TLS(nr_enqueues)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_enqueue())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ?} > > ? ? ? ?rcu_unregister_thread(); > > - ? ? ? count[0] = nr_enqueues; > - ? ? ? count[1] = nr_successful_enqueues; > + ? ? ? count[0] = URCU_TLS(nr_enqueues); > + ? ? ? count[1] = URCU_TLS(nr_successful_enqueues); > ? ? ? ?printf_verbose("enqueuer thread_end, thread id : %lx, tid %lu, " > ? ? ? ? ? ? ? ? ? ? ? "enqueues %llu successful_enqueues %llu\n", > - ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), nr_enqueues, > - ? ? ? ? ? ? ? ? ? ? ?nr_successful_enqueues); > + ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), > + ? ? ? ? ? ? ? ? ? ? ?URCU_TLS(nr_enqueues), URCU_TLS(nr_successful_enqueues)); > ? ? ? ?return ((void*)1); > > ?} > @@ -251,10 +252,10 @@ void *thr_dequeuer(void *_count) > > ? ? ? ? ? ? ? ?if (node) { > ? ? ? ? ? ? ? ? ? ? ? ?call_rcu(&node->rcu, free_node_cb); > - ? ? ? ? ? ? ? ? ? ? ? nr_successful_dequeues++; > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_successful_dequeues)++; > ? ? ? ? ? ? ? ?} > > - ? ? ? ? ? ? ? nr_dequeues++; > + ? ? ? ? ? ? ? URCU_TLS(nr_dequeues)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_dequeue())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > @@ -265,10 +266,10 @@ void *thr_dequeuer(void *_count) > ? ? ? ?rcu_defer_unregister_thread(); > ? ? ? ?printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " > ? ? ? ? ? ? ? ? ? ? ? "dequeues %llu, successful_dequeues %llu\n", > - ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), nr_dequeues, > - ? ? ? ? ? ? ? ? ? ? ?nr_successful_dequeues); > - ? ? ? count[0] = nr_dequeues; > - ? ? ? count[1] = nr_successful_dequeues; > + ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), > + ? ? ? ? ? ? ? ? ? ? ?URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues)); > + ? ? ? count[0] = URCU_TLS(nr_dequeues); > + ? ? ? count[1] = URCU_TLS(nr_successful_dequeues); > ? ? ? ?return ((void*)2); > ?} > > diff --git a/tests/test_urcu_lfs.c b/tests/test_urcu_lfs.c > index b48a35f..88bf65d 100644 > --- a/tests/test_urcu_lfs.c > +++ b/tests/test_urcu_lfs.c > @@ -38,6 +38,7 @@ > ?#include > > ?#include > +#include > > ?#ifdef __linux__ > ?#include > @@ -148,11 +149,11 @@ static int test_duration_enqueue(void) > ? ? ? ?return !test_stop; > ?} > > -static unsigned long long __thread nr_dequeues; > -static unsigned long long __thread nr_enqueues; > +static DEFINE_URCU_TLS(unsigned long long, nr_dequeues); > +static DEFINE_URCU_TLS(unsigned long long, nr_enqueues); > > -static unsigned long long __thread nr_successful_dequeues; > -static unsigned long long __thread nr_successful_enqueues; > +static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); > +static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); > > ?static unsigned int nr_enqueuers; > ?static unsigned int nr_dequeuers; > @@ -187,24 +188,24 @@ void *thr_enqueuer(void *_count) > ? ? ? ? ? ? ? ?cds_lfs_node_init_rcu(&node->list); > ? ? ? ? ? ? ? ?/* No rcu read-side is needed for push */ > ? ? ? ? ? ? ? ?cds_lfs_push_rcu(&s, &node->list); > - ? ? ? ? ? ? ? nr_successful_enqueues++; > + ? ? ? ? ? ? ? URCU_TLS(nr_successful_enqueues)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wdelay); > ?fail: > - ? ? ? ? ? ? ? nr_enqueues++; > + ? ? ? ? ? ? ? URCU_TLS(nr_enqueues)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_enqueue())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ?} > > ? ? ? ?rcu_unregister_thread(); > > - ? ? ? count[0] = nr_enqueues; > - ? ? ? count[1] = nr_successful_enqueues; > + ? ? ? count[0] = URCU_TLS(nr_enqueues); > + ? ? ? count[1] = URCU_TLS(nr_successful_enqueues); > ? ? ? ?printf_verbose("enqueuer thread_end, thread id : %lx, tid %lu, " > ? ? ? ? ? ? ? ? ? ? ? "enqueues %llu successful_enqueues %llu\n", > - ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), nr_enqueues, > - ? ? ? ? ? ? ? ? ? ? ?nr_successful_enqueues); > + ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), > + ? ? ? ? ? ? ? ? ? ? ?URCU_TLS(nr_enqueues), URCU_TLS(nr_successful_enqueues)); > ? ? ? ?return ((void*)1); > > ?} > @@ -249,9 +250,9 @@ void *thr_dequeuer(void *_count) > ? ? ? ? ? ? ? ?rcu_read_unlock(); > ? ? ? ? ? ? ? ?if (node) { > ? ? ? ? ? ? ? ? ? ? ? ?call_rcu(&node->rcu, free_node_cb); > - ? ? ? ? ? ? ? ? ? ? ? nr_successful_dequeues++; > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_successful_dequeues)++; > ? ? ? ? ? ? ? ?} > - ? ? ? ? ? ? ? nr_dequeues++; > + ? ? ? ? ? ? ? URCU_TLS(nr_dequeues)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_dequeue())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > @@ -263,10 +264,10 @@ void *thr_dequeuer(void *_count) > > ? ? ? ?printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " > ? ? ? ? ? ? ? ? ? ? ? "dequeues %llu, successful_dequeues %llu\n", > - ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), nr_dequeues, > - ? ? ? ? ? ? ? ? ? ? ?nr_successful_dequeues); > - ? ? ? count[0] = nr_dequeues; > - ? ? ? count[1] = nr_successful_dequeues; > + ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), > + ? ? ? ? ? ? ? ? ? ? ?URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues)); > + ? ? ? count[0] = URCU_TLS(nr_dequeues); > + ? ? ? count[1] = URCU_TLS(nr_successful_dequeues); > ? ? ? ?return ((void*)2); > ?} > > diff --git a/tests/test_urcu_qsbr.c b/tests/test_urcu_qsbr.c > index b986fd8..421fb07 100644 > --- a/tests/test_urcu_qsbr.c > +++ b/tests/test_urcu_qsbr.c > @@ -35,6 +35,7 @@ > ?#include > > ?#include > +#include > > ?#ifdef __linux__ > ?#include > @@ -153,8 +154,8 @@ static int test_duration_read(void) > ? ? ? ?return !test_stop; > ?} > > -static unsigned long long __thread nr_writes; > -static unsigned long long __thread nr_reads; > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > ?static unsigned int nr_readers; > ?static unsigned int nr_writers; > @@ -241,9 +242,9 @@ void *thr_reader(void *_count) > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > ? ? ? ? ? ? ? ?rcu_read_unlock(); > - ? ? ? ? ? ? ? nr_reads++; > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > ? ? ? ? ? ? ? ?/* QS each 1024 reads */ > - ? ? ? ? ? ? ? if (caa_unlikely((nr_reads & ((1 << 10) - 1)) == 0)) > + ? ? ? ? ? ? ? if (caa_unlikely((URCU_TLS(nr_reads) & ((1 << 10) - 1)) == 0)) > ? ? ? ? ? ? ? ? ? ? ? ?rcu_quiescent_state(); > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > @@ -255,7 +256,7 @@ void *thr_reader(void *_count) > ? ? ? ?rcu_register_thread(); > ? ? ? ?rcu_unregister_thread(); > > - ? ? ? *count = nr_reads; > + ? ? ? *count = URCU_TLS(nr_reads); > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > ? ? ? ?return ((void*)1); > @@ -290,7 +291,7 @@ void *thr_writer(void *_count) > ? ? ? ? ? ? ? ? ? ? ? ?old->a = 0; > ? ? ? ? ? ? ? ?test_array_free(old); > ? ? ? ? ? ? ? ?rcu_copy_mutex_unlock(); > - ? ? ? ? ? ? ? nr_writes++; > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > @@ -299,7 +300,7 @@ void *thr_writer(void *_count) > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > - ? ? ? *count = nr_writes; > + ? ? ? *count = URCU_TLS(nr_writes); > ? ? ? ?return ((void*)2); > ?} > > diff --git a/tests/test_urcu_qsbr_gc.c b/tests/test_urcu_qsbr_gc.c > index 9deb0aa..561a475 100644 > --- a/tests/test_urcu_qsbr_gc.c > +++ b/tests/test_urcu_qsbr_gc.c > @@ -35,6 +35,7 @@ > ?#include > > ?#include > +#include > > ?#ifdef __linux__ > ?#include > @@ -159,8 +160,8 @@ static int test_duration_read(void) > ? ? ? ?return !test_stop; > ?} > > -static unsigned long long __thread nr_writes; > -static unsigned long long __thread nr_reads; > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > ?static unsigned int nr_readers; > ?static unsigned int nr_writers; > @@ -217,9 +218,9 @@ void *thr_reader(void *_count) > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > ? ? ? ? ? ? ? ?_rcu_read_unlock(); > - ? ? ? ? ? ? ? nr_reads++; > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > ? ? ? ? ? ? ? ?/* QS each 1024 reads */ > - ? ? ? ? ? ? ? if (caa_unlikely((nr_reads & ((1 << 10) - 1)) == 0)) > + ? ? ? ? ? ? ? if (caa_unlikely((URCU_TLS(nr_reads) & ((1 << 10) - 1)) == 0)) > ? ? ? ? ? ? ? ? ? ? ? ?_rcu_quiescent_state(); > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > @@ -227,7 +228,7 @@ void *thr_reader(void *_count) > > ? ? ? ?rcu_unregister_thread(); > > - ? ? ? *count = nr_reads; > + ? ? ? *count = URCU_TLS(nr_reads); > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > ? ? ? ?return ((void*)1); > @@ -293,7 +294,7 @@ void *thr_writer(void *data) > ? ? ? ? ? ? ? ?if (caa_unlikely(wduration)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wduration); > ? ? ? ? ? ? ? ?rcu_gc_reclaim(wtidx, old); > - ? ? ? ? ? ? ? nr_writes++; > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > @@ -302,7 +303,7 @@ void *thr_writer(void *data) > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > - ? ? ? tot_nr_writes[wtidx] = nr_writes; > + ? ? ? tot_nr_writes[wtidx] = URCU_TLS(nr_writes); > ? ? ? ?return ((void*)2); > ?} > > diff --git a/tests/test_urcu_wfq.c b/tests/test_urcu_wfq.c > index 83ec635..75a9275 100644 > --- a/tests/test_urcu_wfq.c > +++ b/tests/test_urcu_wfq.c > @@ -38,6 +38,7 @@ > ?#include > > ?#include > +#include > > ?#ifdef __linux__ > ?#include > @@ -147,11 +148,11 @@ static int test_duration_enqueue(void) > ? ? ? ?return !test_stop; > ?} > > -static unsigned long long __thread nr_dequeues; > -static unsigned long long __thread nr_enqueues; > +static DEFINE_URCU_TLS(unsigned long long, nr_dequeues); > +static DEFINE_URCU_TLS(unsigned long long, nr_enqueues); > > -static unsigned long long __thread nr_successful_dequeues; > -static unsigned long long __thread nr_successful_enqueues; > +static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); > +static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); > > ?static unsigned int nr_enqueuers; > ?static unsigned int nr_dequeuers; > @@ -178,22 +179,22 @@ void *thr_enqueuer(void *_count) > ? ? ? ? ? ? ? ? ? ? ? ?goto fail; > ? ? ? ? ? ? ? ?cds_wfq_node_init(node); > ? ? ? ? ? ? ? ?cds_wfq_enqueue(&q, node); > - ? ? ? ? ? ? ? nr_successful_enqueues++; > + ? ? ? ? ? ? ? URCU_TLS(nr_successful_enqueues)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wdelay); > ?fail: > - ? ? ? ? ? ? ? nr_enqueues++; > + ? ? ? ? ? ? ? URCU_TLS(nr_enqueues)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_enqueue())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ?} > > - ? ? ? count[0] = nr_enqueues; > - ? ? ? count[1] = nr_successful_enqueues; > + ? ? ? count[0] = URCU_TLS(nr_enqueues); > + ? ? ? count[1] = URCU_TLS(nr_successful_enqueues); > ? ? ? ?printf_verbose("enqueuer thread_end, thread id : %lx, tid %lu, " > ? ? ? ? ? ? ? ? ? ? ? "enqueues %llu successful_enqueues %llu\n", > - ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), nr_enqueues, > - ? ? ? ? ? ? ? ? ? ? ?nr_successful_enqueues); > + ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), > + ? ? ? ? ? ? ? ? ? ? ?URCU_TLS(nr_enqueues), URCU_TLS(nr_successful_enqueues)); > ? ? ? ?return ((void*)1); > > ?} > @@ -217,10 +218,10 @@ void *thr_dequeuer(void *_count) > > ? ? ? ? ? ? ? ?if (node) { > ? ? ? ? ? ? ? ? ? ? ? ?free(node); > - ? ? ? ? ? ? ? ? ? ? ? nr_successful_dequeues++; > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_successful_dequeues)++; > ? ? ? ? ? ? ? ?} > > - ? ? ? ? ? ? ? nr_dequeues++; > + ? ? ? ? ? ? ? URCU_TLS(nr_dequeues)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_dequeue())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > @@ -229,10 +230,10 @@ void *thr_dequeuer(void *_count) > > ? ? ? ?printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " > ? ? ? ? ? ? ? ? ? ? ? "dequeues %llu, successful_dequeues %llu\n", > - ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), nr_dequeues, > - ? ? ? ? ? ? ? ? ? ? ?nr_successful_dequeues); > - ? ? ? count[0] = nr_dequeues; > - ? ? ? count[1] = nr_successful_dequeues; > + ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), > + ? ? ? ? ? ? ? ? ? ? ?URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues)); > + ? ? ? count[0] = URCU_TLS(nr_dequeues); > + ? ? ? count[1] = URCU_TLS(nr_successful_dequeues); > ? ? ? ?return ((void*)2); > ?} > > diff --git a/tests/test_urcu_wfs.c b/tests/test_urcu_wfs.c > index 7746a1d..be09944 100644 > --- a/tests/test_urcu_wfs.c > +++ b/tests/test_urcu_wfs.c > @@ -38,6 +38,7 @@ > ?#include > > ?#include > +#include > > ?#ifdef __linux__ > ?#include > @@ -147,11 +148,11 @@ static int test_duration_enqueue(void) > ? ? ? ?return !test_stop; > ?} > > -static unsigned long long __thread nr_dequeues; > -static unsigned long long __thread nr_enqueues; > +static DEFINE_URCU_TLS(unsigned long long, nr_dequeues); > +static DEFINE_URCU_TLS(unsigned long long, nr_enqueues); > > -static unsigned long long __thread nr_successful_dequeues; > -static unsigned long long __thread nr_successful_enqueues; > +static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); > +static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); > > ?static unsigned int nr_enqueuers; > ?static unsigned int nr_dequeuers; > @@ -178,22 +179,22 @@ void *thr_enqueuer(void *_count) > ? ? ? ? ? ? ? ? ? ? ? ?goto fail; > ? ? ? ? ? ? ? ?cds_wfs_node_init(node); > ? ? ? ? ? ? ? ?cds_wfs_push(&s, node); > - ? ? ? ? ? ? ? nr_successful_enqueues++; > + ? ? ? ? ? ? ? URCU_TLS(nr_successful_enqueues)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wdelay); > ?fail: > - ? ? ? ? ? ? ? nr_enqueues++; > + ? ? ? ? ? ? ? URCU_TLS(nr_enqueues)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_enqueue())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ?} > > - ? ? ? count[0] = nr_enqueues; > - ? ? ? count[1] = nr_successful_enqueues; > + ? ? ? count[0] = URCU_TLS(nr_enqueues); > + ? ? ? count[1] = URCU_TLS(nr_successful_enqueues); > ? ? ? ?printf_verbose("enqueuer thread_end, thread id : %lx, tid %lu, " > ? ? ? ? ? ? ? ? ? ? ? "enqueues %llu successful_enqueues %llu\n", > - ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), nr_enqueues, > - ? ? ? ? ? ? ? ? ? ? ?nr_successful_enqueues); > + ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), > + ? ? ? ? ? ? ? ? ? ? ?URCU_TLS(nr_enqueues), URCU_TLS(nr_successful_enqueues)); > ? ? ? ?return ((void*)1); > > ?} > @@ -217,10 +218,10 @@ void *thr_dequeuer(void *_count) > > ? ? ? ? ? ? ? ?if (node) { > ? ? ? ? ? ? ? ? ? ? ? ?free(node); > - ? ? ? ? ? ? ? ? ? ? ? nr_successful_dequeues++; > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_successful_dequeues)++; > ? ? ? ? ? ? ? ?} > > - ? ? ? ? ? ? ? nr_dequeues++; > + ? ? ? ? ? ? ? URCU_TLS(nr_dequeues)++; > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_dequeue())) > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > @@ -229,10 +230,10 @@ void *thr_dequeuer(void *_count) > > ? ? ? ?printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " > ? ? ? ? ? ? ? ? ? ? ? "dequeues %llu, successful_dequeues %llu\n", > - ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), nr_dequeues, > - ? ? ? ? ? ? ? ? ? ? ?nr_successful_dequeues); > - ? ? ? count[0] = nr_dequeues; > - ? ? ? count[1] = nr_successful_dequeues; > + ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), > + ? ? ? ? ? ? ? ? ? ? ?URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues)); > + ? ? ? count[0] = URCU_TLS(nr_dequeues); > + ? ? ? count[1] = URCU_TLS(nr_successful_dequeues); > ? ? ? ?return ((void*)2); > ?} > > diff --git a/urcu-bp.c b/urcu-bp.c > index 08b4b55..bb657d7 100644 > --- a/urcu-bp.c > +++ b/urcu-bp.c > @@ -40,6 +40,7 @@ > ?#include "urcu/map/urcu-bp.h" > ?#include "urcu/static/urcu-bp.h" > ?#include "urcu-pointer.h" > +#include "urcu/tls-compat.h" > > ?/* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ > ?#undef _LGPL_SOURCE > @@ -94,7 +95,7 @@ static pthread_mutex_t rcu_gp_lock = PTHREAD_MUTEX_INITIALIZER; > > ?#ifdef DEBUG_YIELD > ?unsigned int yield_active; > -unsigned int __thread rand_yield; > +DEFINE_URCU_TLS(unsigned int, rand_yield); > ?#endif > > ?/* > @@ -109,7 +110,7 @@ long rcu_gp_ctr = RCU_GP_COUNT; > ?* Pointer to registry elements. Written to only by each individual reader. Read > ?* by both the reader and the writers. > ?*/ > -struct rcu_reader __thread *rcu_reader; > +DEFINE_URCU_TLS(struct rcu_reader *, rcu_reader); > > ?static CDS_LIST_HEAD(registry); > > @@ -322,7 +323,7 @@ static void add_thread(void) > ? ? ? ?rcu_reader_reg->tid = pthread_self(); > ? ? ? ?assert(rcu_reader_reg->ctr == 0); > ? ? ? ?cds_list_add(&rcu_reader_reg->node, ®istry); > - ? ? ? rcu_reader = rcu_reader_reg; > + ? ? ? URCU_TLS(rcu_reader) = rcu_reader_reg; > ?} > > ?/* Called with signals off and mutex locked */ > @@ -363,7 +364,7 @@ void rcu_bp_register(void) > ? ? ? ?/* > ? ? ? ? * Check if a signal concurrently registered our thread since > ? ? ? ? * the check in rcu_read_lock(). */ > - ? ? ? if (rcu_reader) > + ? ? ? if (URCU_TLS(rcu_reader)) > ? ? ? ? ? ? ? ?goto end; > > ? ? ? ?mutex_lock(&rcu_gp_lock); > diff --git a/urcu-call-rcu-impl.h b/urcu-call-rcu-impl.h > index 36e3cf4..8ed2ab3 100644 > --- a/urcu-call-rcu-impl.h > +++ b/urcu-call-rcu-impl.h > @@ -40,6 +40,7 @@ > ?#include "urcu-pointer.h" > ?#include "urcu/list.h" > ?#include "urcu/futex.h" > +#include "urcu/tls-compat.h" > > ?/* Data structure that identifies a call_rcu thread. */ > > @@ -62,7 +63,7 @@ CDS_LIST_HEAD(call_rcu_data_list); > > ?/* Link a thread using call_rcu() to its call_rcu thread. */ > > -static __thread struct call_rcu_data *thread_call_rcu_data; > +static DEFINE_URCU_TLS(struct call_rcu_data *, thread_call_rcu_data); > > ?/* Guard call_rcu thread creation. */ > > @@ -232,7 +233,7 @@ static void *call_rcu_thread(void *arg) > ? ? ? ? */ > ? ? ? ?rcu_register_thread(); > > - ? ? ? thread_call_rcu_data = crdp; > + ? ? ? URCU_TLS(thread_call_rcu_data) = crdp; > ? ? ? ?if (!rt) { > ? ? ? ? ? ? ? ?uatomic_dec(&crdp->futex); > ? ? ? ? ? ? ? ?/* Decrement futex before reading call_rcu list */ > @@ -470,8 +471,8 @@ struct call_rcu_data *get_call_rcu_data(void) > ?{ > ? ? ? ?struct call_rcu_data *crd; > > - ? ? ? if (thread_call_rcu_data != NULL) > - ? ? ? ? ? ? ? return thread_call_rcu_data; > + ? ? ? if (URCU_TLS(thread_call_rcu_data) != NULL) > + ? ? ? ? ? ? ? return URCU_TLS(thread_call_rcu_data); > > ? ? ? ?if (maxcpus > 0) { > ? ? ? ? ? ? ? ?crd = get_cpu_call_rcu_data(sched_getcpu()); > @@ -488,7 +489,7 @@ struct call_rcu_data *get_call_rcu_data(void) > > ?struct call_rcu_data *get_thread_call_rcu_data(void) > ?{ > - ? ? ? return thread_call_rcu_data; > + ? ? ? return URCU_TLS(thread_call_rcu_data); > ?} > > ?/* > @@ -504,7 +505,7 @@ struct call_rcu_data *get_thread_call_rcu_data(void) > > ?void set_thread_call_rcu_data(struct call_rcu_data *crdp) > ?{ > - ? ? ? thread_call_rcu_data = crdp; > + ? ? ? URCU_TLS(thread_call_rcu_data) = crdp; > ?} > > ?/* > @@ -746,7 +747,7 @@ void call_rcu_after_fork_child(void) > ? ? ? ?maxcpus_reset(); > ? ? ? ?free(per_cpu_call_rcu_data); > ? ? ? ?rcu_set_pointer(&per_cpu_call_rcu_data, NULL); > - ? ? ? thread_call_rcu_data = NULL; > + ? ? ? URCU_TLS(thread_call_rcu_data) = NULL; > > ? ? ? ?/* Dispose of all of the rest of the call_rcu_data structures. */ > ? ? ? ?cds_list_for_each_entry_safe(crdp, next, &call_rcu_data_list, list) { > diff --git a/urcu-defer-impl.h b/urcu-defer-impl.h > index 4d1ca5e..f65e410 100644 > --- a/urcu-defer-impl.h > +++ b/urcu-defer-impl.h > @@ -48,6 +48,7 @@ > ?#include > ?#include > ?#include > +#include > > ?/* > ?* Number of entries in the per-thread defer queue. Must be power of 2. > @@ -130,7 +131,7 @@ static int32_t defer_thread_stop; > ?* Written to only by each individual deferer. Read by both the deferer and > ?* the reclamation tread. > ?*/ > -static struct defer_queue __thread defer_queue; > +static DEFINE_URCU_TLS(struct defer_queue, defer_queue); > ?static CDS_LIST_HEAD(registry_defer); > ?static pthread_t tid_defer; > > @@ -245,12 +246,12 @@ static void _rcu_defer_barrier_thread(void) > ?{ > ? ? ? ?unsigned long head, num_items; > > - ? ? ? head = defer_queue.head; > - ? ? ? num_items = head - defer_queue.tail; > + ? ? ? head = URCU_TLS(defer_queue).head; > + ? ? ? num_items = head - URCU_TLS(defer_queue).tail; > ? ? ? ?if (caa_unlikely(!num_items)) > ? ? ? ? ? ? ? ?return; > ? ? ? ?synchronize_rcu(); > - ? ? ? rcu_defer_barrier_queue(&defer_queue, head); > + ? ? ? rcu_defer_barrier_queue(&URCU_TLS(defer_queue), head); > ?} > > ?void rcu_defer_barrier_thread(void) > @@ -311,8 +312,8 @@ void _defer_rcu(void (*fct)(void *p), void *p) > ? ? ? ? * Head is only modified by ourself. Tail can be modified by reclamation > ? ? ? ? * thread. > ? ? ? ? */ > - ? ? ? head = defer_queue.head; > - ? ? ? tail = CMM_LOAD_SHARED(defer_queue.tail); > + ? ? ? head = URCU_TLS(defer_queue).head; > + ? ? ? tail = CMM_LOAD_SHARED(URCU_TLS(defer_queue).tail); > > ? ? ? ?/* > ? ? ? ? * If queue is full, or reached threshold. Empty queue ourself. > @@ -321,7 +322,7 @@ void _defer_rcu(void (*fct)(void *p), void *p) > ? ? ? ?if (caa_unlikely(head - tail >= DEFER_QUEUE_SIZE - 2)) { > ? ? ? ? ? ? ? ?assert(head - tail <= DEFER_QUEUE_SIZE); > ? ? ? ? ? ? ? ?rcu_defer_barrier_thread(); > - ? ? ? ? ? ? ? assert(head - CMM_LOAD_SHARED(defer_queue.tail) == 0); > + ? ? ? ? ? ? ? assert(head - CMM_LOAD_SHARED(URCU_TLS(defer_queue).tail) == 0); > ? ? ? ?} > > ? ? ? ?/* > @@ -340,25 +341,25 @@ void _defer_rcu(void (*fct)(void *p), void *p) > ? ? ? ? * Decode: see the comments before 'struct defer_queue' > ? ? ? ? * ? ? ? ? or the code in rcu_defer_barrier_queue(). > ? ? ? ? */ > - ? ? ? if (caa_unlikely(defer_queue.last_fct_in != fct > + ? ? ? if (caa_unlikely(URCU_TLS(defer_queue).last_fct_in != fct > ? ? ? ? ? ? ? ? ? ? ? ?|| DQ_IS_FCT_BIT(p) > ? ? ? ? ? ? ? ? ? ? ? ?|| p == DQ_FCT_MARK)) { > - ? ? ? ? ? ? ? defer_queue.last_fct_in = fct; > + ? ? ? ? ? ? ? URCU_TLS(defer_queue).last_fct_in = fct; > ? ? ? ? ? ? ? ?if (caa_unlikely(DQ_IS_FCT_BIT(fct) || fct == DQ_FCT_MARK)) { > - ? ? ? ? ? ? ? ? ? ? ? _CMM_STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK], > + ? ? ? ? ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(defer_queue).q[head++ & DEFER_QUEUE_MASK], > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?DQ_FCT_MARK); > - ? ? ? ? ? ? ? ? ? ? ? _CMM_STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK], > + ? ? ? ? ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(defer_queue).q[head++ & DEFER_QUEUE_MASK], > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?fct); > ? ? ? ? ? ? ? ?} else { > ? ? ? ? ? ? ? ? ? ? ? ?DQ_SET_FCT_BIT(fct); > - ? ? ? ? ? ? ? ? ? ? ? _CMM_STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK], > + ? ? ? ? ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(defer_queue).q[head++ & DEFER_QUEUE_MASK], > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?fct); > ? ? ? ? ? ? ? ?} > ? ? ? ?} > - ? ? ? _CMM_STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK], p); > + ? ? ? _CMM_STORE_SHARED(URCU_TLS(defer_queue).q[head++ & DEFER_QUEUE_MASK], p); > ? ? ? ?cmm_smp_wmb(); ?/* Publish new pointer before head */ > ? ? ? ? ? ? ? ? ? ? ? ?/* Write q[] before head. */ > - ? ? ? CMM_STORE_SHARED(defer_queue.head, head); > + ? ? ? CMM_STORE_SHARED(URCU_TLS(defer_queue).head, head); > ? ? ? ?cmm_smp_mb(); ? /* Write queue head before read futex */ > ? ? ? ?/* > ? ? ? ? * Wake-up any waiting defer thread. > @@ -422,16 +423,16 @@ int rcu_defer_register_thread(void) > ?{ > ? ? ? ?int was_empty; > > - ? ? ? assert(defer_queue.last_head == 0); > - ? ? ? assert(defer_queue.q == NULL); > - ? ? ? defer_queue.q = malloc(sizeof(void *) * DEFER_QUEUE_SIZE); > - ? ? ? if (!defer_queue.q) > + ? ? ? assert(URCU_TLS(defer_queue).last_head == 0); > + ? ? ? assert(URCU_TLS(defer_queue).q == NULL); > + ? ? ? URCU_TLS(defer_queue).q = malloc(sizeof(void *) * DEFER_QUEUE_SIZE); > + ? ? ? if (!URCU_TLS(defer_queue).q) > ? ? ? ? ? ? ? ?return -ENOMEM; > > ? ? ? ?mutex_lock_defer(&defer_thread_mutex); > ? ? ? ?mutex_lock_defer(&rcu_defer_mutex); > ? ? ? ?was_empty = cds_list_empty(®istry_defer); > - ? ? ? cds_list_add(&defer_queue.list, ®istry_defer); > + ? ? ? cds_list_add(&URCU_TLS(defer_queue).list, ®istry_defer); > ? ? ? ?mutex_unlock(&rcu_defer_mutex); > > ? ? ? ?if (was_empty) > @@ -446,10 +447,10 @@ void rcu_defer_unregister_thread(void) > > ? ? ? ?mutex_lock_defer(&defer_thread_mutex); > ? ? ? ?mutex_lock_defer(&rcu_defer_mutex); > - ? ? ? cds_list_del(&defer_queue.list); > + ? ? ? cds_list_del(&URCU_TLS(defer_queue).list); > ? ? ? ?_rcu_defer_barrier_thread(); > - ? ? ? free(defer_queue.q); > - ? ? ? defer_queue.q = NULL; > + ? ? ? free(URCU_TLS(defer_queue).q); > + ? ? ? URCU_TLS(defer_queue).q = NULL; > ? ? ? ?is_empty = cds_list_empty(®istry_defer); > ? ? ? ?mutex_unlock(&rcu_defer_mutex); > > diff --git a/urcu-qsbr.c b/urcu-qsbr.c > index 745676e..b20d564 100644 > --- a/urcu-qsbr.c > +++ b/urcu-qsbr.c > @@ -40,6 +40,7 @@ > ?#define BUILD_QSBR_LIB > ?#include "urcu/static/urcu-qsbr.h" > ?#include "urcu-pointer.h" > +#include "urcu/tls-compat.h" > > ?/* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ > ?#undef _LGPL_SOURCE > @@ -66,11 +67,11 @@ unsigned long rcu_gp_ctr = RCU_GP_ONLINE; > ?* Written to only by each individual reader. Read by both the reader and the > ?* writers. > ?*/ > -struct rcu_reader __thread rcu_reader; > +DEFINE_URCU_TLS(struct rcu_reader, rcu_reader); > > ?#ifdef DEBUG_YIELD > ?unsigned int yield_active; > -unsigned int __thread rand_yield; > +DEFINE_URCU_TLS(unsigned int, rand_yield); > ?#endif > > ?static CDS_LIST_HEAD(registry); > @@ -139,7 +140,7 @@ static void update_counter_and_wait(void) > ? ? ? ? * quiescent state. Failure to do so could result in the writer > ? ? ? ? * waiting forever while new readers are always accessing data > ? ? ? ? * (no progress). Enforce compiler-order of store to rcu_gp_ctr > - ? ? ? ?* before load rcu_reader ctr. > + ? ? ? ?* before load URCU_TLS(rcu_reader).ctr. > ? ? ? ? */ > ? ? ? ?cmm_barrier(); > > @@ -206,7 +207,7 @@ void synchronize_rcu(void) > ?{ > ? ? ? ?unsigned long was_online; > > - ? ? ? was_online = rcu_reader.ctr; > + ? ? ? was_online = URCU_TLS(rcu_reader).ctr; > > ? ? ? ?/* All threads should read qparity before accessing data structure > ? ? ? ? * where new ptr points to. ?In the "then" case, rcu_thread_offline > @@ -236,7 +237,7 @@ void synchronize_rcu(void) > ? ? ? ? * committing next rcu_gp_ctr update to memory. Failure to > ? ? ? ? * do so could result in the writer waiting forever while new > ? ? ? ? * readers are always accessing data (no progress). ?Enforce > - ? ? ? ?* compiler-order of load rcu_reader ctr before store to > + ? ? ? ?* compiler-order of load URCU_TLS(rcu_reader).ctr before store to > ? ? ? ? * rcu_gp_ctr. > ? ? ? ? */ > ? ? ? ?cmm_barrier(); > @@ -269,7 +270,7 @@ void synchronize_rcu(void) > ?{ > ? ? ? ?unsigned long was_online; > > - ? ? ? was_online = rcu_reader.ctr; > + ? ? ? was_online = URCU_TLS(rcu_reader).ctr; > > ? ? ? ?/* > ? ? ? ? * Mark the writer thread offline to make sure we don't wait for > @@ -326,11 +327,11 @@ void rcu_thread_online(void) > > ?void rcu_register_thread(void) > ?{ > - ? ? ? rcu_reader.tid = pthread_self(); > - ? ? ? assert(rcu_reader.ctr == 0); > + ? ? ? URCU_TLS(rcu_reader).tid = pthread_self(); > + ? ? ? assert(URCU_TLS(rcu_reader).ctr == 0); > > ? ? ? ?mutex_lock(&rcu_gp_lock); > - ? ? ? cds_list_add(&rcu_reader.node, ®istry); > + ? ? ? cds_list_add(&URCU_TLS(rcu_reader).node, ®istry); > ? ? ? ?mutex_unlock(&rcu_gp_lock); > ? ? ? ?_rcu_thread_online(); > ?} > @@ -343,7 +344,7 @@ void rcu_unregister_thread(void) > ? ? ? ? */ > ? ? ? ?_rcu_thread_offline(); > ? ? ? ?mutex_lock(&rcu_gp_lock); > - ? ? ? cds_list_del(&rcu_reader.node); > + ? ? ? cds_list_del(&URCU_TLS(rcu_reader).node); > ? ? ? ?mutex_unlock(&rcu_gp_lock); > ?} > > diff --git a/urcu.c b/urcu.c > index 3948629..5fb4db8 100644 > --- a/urcu.c > +++ b/urcu.c > @@ -40,6 +40,7 @@ > ?#include "urcu/map/urcu.h" > ?#include "urcu/static/urcu.h" > ?#include "urcu-pointer.h" > +#include "urcu/tls-compat.h" > > ?/* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ > ?#undef _LGPL_SOURCE > @@ -94,11 +95,11 @@ unsigned long rcu_gp_ctr = RCU_GP_COUNT; > ?* Written to only by each individual reader. Read by both the reader and the > ?* writers. > ?*/ > -struct rcu_reader __thread rcu_reader; > +DEFINE_URCU_TLS(struct rcu_reader, rcu_reader); > > ?#ifdef DEBUG_YIELD > ?unsigned int yield_active; > -unsigned int __thread rand_yield; > +DEFINE_URCU_TLS(unsigned int, rand_yield); > ?#endif > > ?static CDS_LIST_HEAD(registry); > @@ -120,9 +121,9 @@ static void mutex_lock(pthread_mutex_t *mutex) > ? ? ? ? ? ? ? ? ? ? ? ?perror("Error in pthread mutex lock"); > ? ? ? ? ? ? ? ? ? ? ? ?exit(-1); > ? ? ? ? ? ? ? ?} > - ? ? ? ? ? ? ? if (CMM_LOAD_SHARED(rcu_reader.need_mb)) { > + ? ? ? ? ? ? ? if (CMM_LOAD_SHARED(URCU_TLS(rcu_reader).need_mb)) { > ? ? ? ? ? ? ? ? ? ? ? ?cmm_smp_mb(); > - ? ? ? ? ? ? ? ? ? ? ? _CMM_STORE_SHARED(rcu_reader.need_mb, 0); > + ? ? ? ? ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader).need_mb, 0); > ? ? ? ? ? ? ? ? ? ? ? ?cmm_smp_mb(); > ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ?poll(NULL,0,10); > @@ -245,7 +246,7 @@ void update_counter_and_wait(void) > ? ? ? ?cmm_smp_mb(); > > ? ? ? ?/* > - ? ? ? ?* Wait for each thread rcu_reader.ctr count to become 0. > + ? ? ? ?* Wait for each thread URCU_TLS(rcu_reader).ctr count to become 0. > ? ? ? ? */ > ? ? ? ?for (;;) { > ? ? ? ? ? ? ? ?wait_loops++; > @@ -277,7 +278,8 @@ void update_counter_and_wait(void) > ?#else /* #ifndef HAS_INCOHERENT_CACHES */ > ? ? ? ? ? ? ? ?/* > ? ? ? ? ? ? ? ? * BUSY-LOOP. Force the reader thread to commit its > - ? ? ? ? ? ? ? ?* rcu_reader.ctr update to memory if we wait for too long. > + ? ? ? ? ? ? ? ?* URCU_TLS(rcu_reader).ctr update to memory if we wait > + ? ? ? ? ? ? ? ?* for too long. > ? ? ? ? ? ? ? ? */ > ? ? ? ? ? ? ? ?if (cds_list_empty(®istry)) { > ? ? ? ? ? ? ? ? ? ? ? ?if (wait_loops == RCU_QS_ACTIVE_ATTEMPTS) { > @@ -328,7 +330,7 @@ void synchronize_rcu(void) > ? ? ? ? * committing next rcu_gp_ctr update to memory. Failure to do so could > ? ? ? ? * result in the writer waiting forever while new readers are always > ? ? ? ? * accessing data (no progress). ?Enforce compiler-order of load > - ? ? ? ?* rcu_reader ctr before store to rcu_gp_ctr. > + ? ? ? ?* URCU_TLS(rcu_reader).ctr before store to rcu_gp_ctr. > ? ? ? ? */ > ? ? ? ?cmm_barrier(); > > @@ -368,20 +370,20 @@ void rcu_read_unlock(void) > > ?void rcu_register_thread(void) > ?{ > - ? ? ? rcu_reader.tid = pthread_self(); > - ? ? ? assert(rcu_reader.need_mb == 0); > - ? ? ? assert(!(rcu_reader.ctr & RCU_GP_CTR_NEST_MASK)); > + ? ? ? URCU_TLS(rcu_reader).tid = pthread_self(); > + ? ? ? assert(URCU_TLS(rcu_reader).need_mb == 0); > + ? ? ? assert(!(URCU_TLS(rcu_reader).ctr & RCU_GP_CTR_NEST_MASK)); > > ? ? ? ?mutex_lock(&rcu_gp_lock); > ? ? ? ?rcu_init(); ? ? /* In case gcc does not support constructor attribute */ > - ? ? ? cds_list_add(&rcu_reader.node, ®istry); > + ? ? ? cds_list_add(&URCU_TLS(rcu_reader).node, ®istry); > ? ? ? ?mutex_unlock(&rcu_gp_lock); > ?} > > ?void rcu_unregister_thread(void) > ?{ > ? ? ? ?mutex_lock(&rcu_gp_lock); > - ? ? ? cds_list_del(&rcu_reader.node); > + ? ? ? cds_list_del(&URCU_TLS(rcu_reader).node); > ? ? ? ?mutex_unlock(&rcu_gp_lock); > ?} > > @@ -405,7 +407,7 @@ static void sigrcu_handler(int signo, siginfo_t *siginfo, void *context) > ? ? ? ? * executed on. > ? ? ? ? */ > ? ? ? ?cmm_smp_mb(); > - ? ? ? _CMM_STORE_SHARED(rcu_reader.need_mb, 0); > + ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader).need_mb, 0); > ? ? ? ?cmm_smp_mb(); > ?} > > diff --git a/urcu/static/urcu-bp.h b/urcu/static/urcu-bp.h > index 8d22163..e7b2eda 100644 > --- a/urcu/static/urcu-bp.h > +++ b/urcu/static/urcu-bp.h > @@ -38,6 +38,7 @@ > ?#include > ?#include > ?#include > +#include > > ?/* > ?* This code section can only be included in LGPL 2.1 compatible source code. > @@ -74,25 +75,25 @@ extern "C" { > ?#define MAX_SLEEP 50 > > ?extern unsigned int yield_active; > -extern unsigned int __thread rand_yield; > +extern DECLARE_URCU_TLS(unsigned int, rand_yield); > > ?static inline void debug_yield_read(void) > ?{ > ? ? ? ?if (yield_active & YIELD_READ) > - ? ? ? ? ? ? ? if (rand_r(&rand_yield) & 0x1) > - ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&rand_yield) % MAX_SLEEP); > + ? ? ? ? ? ? ? if (rand_r(&URCU_TLS(rand_yield)) & 0x1) > + ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&URCU_TLS(rand_yield)) % MAX_SLEEP); > ?} > > ?static inline void debug_yield_write(void) > ?{ > ? ? ? ?if (yield_active & YIELD_WRITE) > - ? ? ? ? ? ? ? if (rand_r(&rand_yield) & 0x1) > - ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&rand_yield) % MAX_SLEEP); > + ? ? ? ? ? ? ? if (rand_r(&URCU_TLS(rand_yield)) & 0x1) > + ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&URCU_TLS(rand_yield)) % MAX_SLEEP); > ?} > > ?static inline void debug_yield_init(void) > ?{ > - ? ? ? rand_yield = time(NULL) ^ pthread_self(); > + ? ? ? URCU_TLS(rand_yield) = time(NULL) ^ pthread_self(); > ?} > ?#else > ?static inline void debug_yield_read(void) > @@ -144,7 +145,7 @@ struct rcu_reader { > ?* Adds a pointer dereference on the read-side, but won't require to unregister > ?* the reader thread. > ?*/ > -extern struct rcu_reader __thread *rcu_reader; > +extern DECLARE_URCU_TLS(struct rcu_reader *, rcu_reader); > > ?static inline int rcu_old_gp_ongoing(long *value) > ?{ > @@ -166,24 +167,24 @@ static inline void _rcu_read_lock(void) > ? ? ? ?long tmp; > > ? ? ? ?/* Check if registered */ > - ? ? ? if (caa_unlikely(!rcu_reader)) > + ? ? ? if (caa_unlikely(!URCU_TLS(rcu_reader))) > ? ? ? ? ? ? ? ?rcu_bp_register(); > > ? ? ? ?cmm_barrier(); ?/* Ensure the compiler does not reorder us with mutex */ > - ? ? ? tmp = rcu_reader->ctr; > + ? ? ? tmp = URCU_TLS(rcu_reader)->ctr; > ? ? ? ?/* > ? ? ? ? * rcu_gp_ctr is > ? ? ? ? * ? RCU_GP_COUNT | (~RCU_GP_CTR_PHASE or RCU_GP_CTR_PHASE) > ? ? ? ? */ > ? ? ? ?if (caa_likely(!(tmp & RCU_GP_CTR_NEST_MASK))) { > - ? ? ? ? ? ? ? _CMM_STORE_SHARED(rcu_reader->ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); > + ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader)->ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); > ? ? ? ? ? ? ? ?/* > ? ? ? ? ? ? ? ? * Set active readers count for outermost nesting level before > ? ? ? ? ? ? ? ? * accessing the pointer. > ? ? ? ? ? ? ? ? */ > ? ? ? ? ? ? ? ?cmm_smp_mb(); > ? ? ? ?} else { > - ? ? ? ? ? ? ? _CMM_STORE_SHARED(rcu_reader->ctr, tmp + RCU_GP_COUNT); > + ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader)->ctr, tmp + RCU_GP_COUNT); > ? ? ? ?} > ?} > > @@ -193,7 +194,7 @@ static inline void _rcu_read_unlock(void) > ? ? ? ? * Finish using rcu before decrementing the pointer. > ? ? ? ? */ > ? ? ? ?cmm_smp_mb(); > - ? ? ? _CMM_STORE_SHARED(rcu_reader->ctr, rcu_reader->ctr - RCU_GP_COUNT); > + ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader)->ctr, URCU_TLS(rcu_reader)->ctr - RCU_GP_COUNT); > ? ? ? ?cmm_barrier(); ?/* Ensure the compiler does not reorder us with mutex */ > ?} > > diff --git a/urcu/static/urcu-qsbr.h b/urcu/static/urcu-qsbr.h > index 68bfc31..22908a4 100644 > --- a/urcu/static/urcu-qsbr.h > +++ b/urcu/static/urcu-qsbr.h > @@ -42,6 +42,7 @@ > ?#include > ?#include > ?#include > +#include > > ?#ifdef __cplusplus > ?extern "C" { > @@ -74,25 +75,25 @@ extern "C" { > ?#define MAX_SLEEP 50 > > ?extern unsigned int yield_active; > -extern unsigned int __thread rand_yield; > +extern DECLARE_URCU_TLS(unsigned int, rand_yield); > > ?static inline void debug_yield_read(void) > ?{ > ? ? ? ?if (yield_active & YIELD_READ) > - ? ? ? ? ? ? ? if (rand_r(&rand_yield) & 0x1) > - ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&rand_yield) % MAX_SLEEP); > + ? ? ? ? ? ? ? if (rand_r(&URCU_TLS(rand_yield)) & 0x1) > + ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&URCU_TLS(rand_yield)) % MAX_SLEEP); > ?} > > ?static inline void debug_yield_write(void) > ?{ > ? ? ? ?if (yield_active & YIELD_WRITE) > - ? ? ? ? ? ? ? if (rand_r(&rand_yield) & 0x1) > - ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&rand_yield) % MAX_SLEEP); > + ? ? ? ? ? ? ? if (rand_r(&URCU_TLS(rand_yield)) & 0x1) > + ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&URCU_TLS(rand_yield)) % MAX_SLEEP); > ?} > > ?static inline void debug_yield_init(void) > ?{ > - ? ? ? rand_yield = time(NULL) ^ pthread_self(); > + ? ? ? URCU_TLS(rand_yield) = time(NULL) ^ pthread_self(); > ?} > ?#else > ?static inline void debug_yield_read(void) > @@ -128,7 +129,7 @@ struct rcu_reader { > ? ? ? ?pthread_t tid; > ?}; > > -extern struct rcu_reader __thread rcu_reader; > +extern DECLARE_URCU_TLS(struct rcu_reader, rcu_reader); > > ?extern int32_t gp_futex; > > @@ -137,8 +138,8 @@ extern int32_t gp_futex; > ?*/ > ?static inline void wake_up_gp(void) > ?{ > - ? ? ? if (caa_unlikely(_CMM_LOAD_SHARED(rcu_reader.waiting))) { > - ? ? ? ? ? ? ? _CMM_STORE_SHARED(rcu_reader.waiting, 0); > + ? ? ? if (caa_unlikely(_CMM_LOAD_SHARED(URCU_TLS(rcu_reader).waiting))) { > + ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader).waiting, 0); > ? ? ? ? ? ? ? ?cmm_smp_mb(); > ? ? ? ? ? ? ? ?if (uatomic_read(&gp_futex) != -1) > ? ? ? ? ? ? ? ? ? ? ? ?return; > @@ -158,7 +159,7 @@ static inline int rcu_gp_ongoing(unsigned long *ctr) > > ?static inline void _rcu_read_lock(void) > ?{ > - ? ? ? rcu_assert(rcu_reader.ctr); > + ? ? ? rcu_assert(URCU_TLS(rcu_reader).ctr); > ?} > > ?static inline void _rcu_read_unlock(void) > @@ -168,8 +169,8 @@ static inline void _rcu_read_unlock(void) > ?static inline void _rcu_quiescent_state(void) > ?{ > ? ? ? ?cmm_smp_mb(); > - ? ? ? _CMM_STORE_SHARED(rcu_reader.ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); > - ? ? ? cmm_smp_mb(); ? /* write rcu_reader.ctr before read futex */ > + ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); > + ? ? ? cmm_smp_mb(); ? /* write URCU_TLS(rcu_reader).ctr before read futex */ > ? ? ? ?wake_up_gp(); > ? ? ? ?cmm_smp_mb(); > ?} > @@ -177,8 +178,8 @@ static inline void _rcu_quiescent_state(void) > ?static inline void _rcu_thread_offline(void) > ?{ > ? ? ? ?cmm_smp_mb(); > - ? ? ? CMM_STORE_SHARED(rcu_reader.ctr, 0); > - ? ? ? cmm_smp_mb(); ? /* write rcu_reader.ctr before read futex */ > + ? ? ? CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, 0); > + ? ? ? cmm_smp_mb(); ? /* write URCU_TLS(rcu_reader).ctr before read futex */ > ? ? ? ?wake_up_gp(); > ? ? ? ?cmm_barrier(); ?/* Ensure the compiler does not reorder us with mutex */ > ?} > @@ -186,7 +187,7 @@ static inline void _rcu_thread_offline(void) > ?static inline void _rcu_thread_online(void) > ?{ > ? ? ? ?cmm_barrier(); ?/* Ensure the compiler does not reorder us with mutex */ > - ? ? ? _CMM_STORE_SHARED(rcu_reader.ctr, CMM_LOAD_SHARED(rcu_gp_ctr)); > + ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, CMM_LOAD_SHARED(rcu_gp_ctr)); > ? ? ? ?cmm_smp_mb(); > ?} > > diff --git a/urcu/static/urcu.h b/urcu/static/urcu.h > index 7ae0185..f27f8b6 100644 > --- a/urcu/static/urcu.h > +++ b/urcu/static/urcu.h > @@ -40,6 +40,7 @@ > ?#include > ?#include > ?#include > +#include > > ?#ifdef __cplusplus > ?extern "C" { > @@ -121,25 +122,25 @@ extern "C" { > ?#endif > > ?extern unsigned int yield_active; > -extern unsigned int __thread rand_yield; > +extern DECLARE_URCU_TLS(unsigned int, rand_yield); > > ?static inline void debug_yield_read(void) > ?{ > ? ? ? ?if (yield_active & YIELD_READ) > - ? ? ? ? ? ? ? if (rand_r(&rand_yield) & 0x1) > - ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&rand_yield) % MAX_SLEEP); > + ? ? ? ? ? ? ? if (rand_r(&URCU_TLS(rand_yield)) & 0x1) > + ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&URCU_TLS(rand_yield)) % MAX_SLEEP); > ?} > > ?static inline void debug_yield_write(void) > ?{ > ? ? ? ?if (yield_active & YIELD_WRITE) > - ? ? ? ? ? ? ? if (rand_r(&rand_yield) & 0x1) > - ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&rand_yield) % MAX_SLEEP); > + ? ? ? ? ? ? ? if (rand_r(&URCU_TLS(rand_yield)) & 0x1) > + ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&URCU_TLS(rand_yield)) % MAX_SLEEP); > ?} > > ?static inline void debug_yield_init(void) > ?{ > - ? ? ? rand_yield = time(NULL) ^ (unsigned long) pthread_self(); > + ? ? ? URCU_TLS(rand_yield) = time(NULL) ^ (unsigned long) pthread_self(); > ?} > ?#else > ?static inline void debug_yield_read(void) > @@ -222,7 +223,7 @@ struct rcu_reader { > ? ? ? ?pthread_t tid; > ?}; > > -extern struct rcu_reader __thread rcu_reader; > +extern DECLARE_URCU_TLS(struct rcu_reader, rcu_reader); > > ?extern int32_t gp_futex; > > @@ -256,20 +257,20 @@ static inline void _rcu_read_lock(void) > ? ? ? ?unsigned long tmp; > > ? ? ? ?cmm_barrier(); ?/* Ensure the compiler does not reorder us with mutex */ > - ? ? ? tmp = rcu_reader.ctr; > + ? ? ? tmp = URCU_TLS(rcu_reader).ctr; > ? ? ? ?/* > ? ? ? ? * rcu_gp_ctr is > ? ? ? ? * ? RCU_GP_COUNT | (~RCU_GP_CTR_PHASE or RCU_GP_CTR_PHASE) > ? ? ? ? */ > ? ? ? ?if (caa_likely(!(tmp & RCU_GP_CTR_NEST_MASK))) { > - ? ? ? ? ? ? ? _CMM_STORE_SHARED(rcu_reader.ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); > + ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); > ? ? ? ? ? ? ? ?/* > ? ? ? ? ? ? ? ? * Set active readers count for outermost nesting level before > ? ? ? ? ? ? ? ? * accessing the pointer. See smp_mb_master(). > ? ? ? ? ? ? ? ? */ > ? ? ? ? ? ? ? ?smp_mb_slave(RCU_MB_GROUP); > ? ? ? ?} else { > - ? ? ? ? ? ? ? _CMM_STORE_SHARED(rcu_reader.ctr, tmp + RCU_GP_COUNT); > + ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, tmp + RCU_GP_COUNT); > ? ? ? ?} > ?} > > @@ -277,19 +278,19 @@ static inline void _rcu_read_unlock(void) > ?{ > ? ? ? ?unsigned long tmp; > > - ? ? ? tmp = rcu_reader.ctr; > + ? ? ? tmp = URCU_TLS(rcu_reader).ctr; > ? ? ? ?/* > ? ? ? ? * Finish using rcu before decrementing the pointer. > ? ? ? ? * See smp_mb_master(). > ? ? ? ? */ > ? ? ? ?if (caa_likely((tmp & RCU_GP_CTR_NEST_MASK) == RCU_GP_COUNT)) { > ? ? ? ? ? ? ? ?smp_mb_slave(RCU_MB_GROUP); > - ? ? ? ? ? ? ? _CMM_STORE_SHARED(rcu_reader.ctr, rcu_reader.ctr - RCU_GP_COUNT); > - ? ? ? ? ? ? ? /* write rcu_reader.ctr before read futex */ > + ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, URCU_TLS(rcu_reader).ctr - RCU_GP_COUNT); > + ? ? ? ? ? ? ? /* write URCU_TLS(rcu_reader).ctr before read futex */ > ? ? ? ? ? ? ? ?smp_mb_slave(RCU_MB_GROUP); > ? ? ? ? ? ? ? ?wake_up_gp(); > ? ? ? ?} else { > - ? ? ? ? ? ? ? _CMM_STORE_SHARED(rcu_reader.ctr, rcu_reader.ctr - RCU_GP_COUNT); > + ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, URCU_TLS(rcu_reader).ctr - RCU_GP_COUNT); > ? ? ? ?} > ? ? ? ?cmm_barrier(); ?/* Ensure the compiler does not reorder us with mutex */ > ?} > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com -------------- next part -------------- A non-text attachment was scrubbed... Name: netbsd-mremap.patch Type: application/octet-stream Size: 1106 bytes Desc: not available URL: From mathieu.desnoyers at efficios.com Wed May 16 11:57:20 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 16 May 2012 11:57:20 -0400 Subject: [lttng-dev] Linux kernel 3.0.27-rt46 + LTTng In-Reply-To: References: <20120509134557.GA21666@Krystal> <20120515165310.GB3377@Krystal> <20120515173304.GA3806@Krystal> <20120516135352.GA29727@Krystal> Message-ID: <20120516155720.GA7918@Krystal> Use git flone with the git:// URL. Please CC lttng-dev at lists.lttng.org for those question. Thanks, Mathieu * Vanni Genua (vannigenua at gmail.com) wrote: > How do I access it? I found this link (http://git.lttng.org/?p=lttng-ust.git), > but how and what do I have to download? No .tar.bz2 file? > thanks. > Vanni > > On Wed, May 16, 2012 at 1:53 PM, Mathieu Desnoyers < > mathieu.desnoyers at efficios.com> wrote: > > > Please try working on the git tree stable-2.0 branch (or on the master > > branch). 2.0.1 is not the latest. > > > > Please submit this information through the bugtracker on > > htpp://bugs.lttng.org , or send it to lttng-dev at lists.lttng.org . > > > > Having many people looking into your various issues will be helpful, > > > > Thanks, > > > > Mathieu > > > > * Vanni Genua (vannigenua at gmail.com) wrote: > > > here are the logs: > > > after having installed userspare-rcu.... > > > *localhost #cd /usr/src/lttng-ust-2.0.1* > > > *localhost #LDFLAGS=-L/usr/local/lib ./configure --build=armv5* > > > ... > > > checking whether the C compiler works... yes > > > checking for C compiler default output file name... a.out > > > checking for suffix of executables... > > > checking whether we are cross compiling... no > > > checking for suffix of object files... o > > > checking whether we are using the GNU C compiler... yes > > > checking whether gcc accepts -g... yes > > > checking for gcc option to accept ISO C89... none needed > > > checking for style of include used by make... GNU > > > checking dependency style of gcc... gcc3 > > > checking for g++... g++ > > > checking whether we are using the GNU C++ compiler... yes > > > checking whether g++ accepts -g... yes > > > checking dependency style of g++... gcc3 > > > checking whether make sets $(MAKE)... (cached) yes > > > checking how to print strings... printf > > > checking for a sed that does not truncate output... (cached) /bin/sed > > > checking for grep that handles long lines and -e... /bin/grep > > > checking for egrep... /bin/grep -E > > > checking for fgrep... /bin/grep -F > > > checking for ld used by gcc... /usr/armv7a-unknown-linux-gnueabi/bin/ld > > > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is GNU > > > ld... s > > > checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B > > > checking the name lister (/usr/bin/nm -B) interface... BSD nm > > > checking whether ln -s works... yes > > > checking the maximum length of command line arguments... 1572864 > > > checking whether the shell understands some XSI constructs... yes > > > checking whether the shell understands "+="... yes > > > checking how to convert armv5-unknown-none file names to > > armv5-unknown-none > > > forp > > > checking how to convert armv5-unknown-none file names to toolchain > > > format... fup > > > checking for /usr/armv7a-unknown-linux-gnueabi/bin/ld option to reload > > > object fr > > > checking for objdump... objdump > > > checking how to recognize dependent libraries... unknown > > > checking for dlltool... no > > > checking how to associate runtime and link libraries... printf %s\n > > > checking for ar... ar > > > checking for archiver @FILE support... @ > > > checking for strip... strip > > > checking for ranlib... ranlib > > > checking command to parse /usr/bin/nm -B output from gcc object... ok > > > checking for sysroot... no > > > checking for mt... no > > > checking if : is a manifest tool... no > > > checking how to run the C preprocessor... gcc -E > > > checking for ANSI C header files... yes > > > checking for sys/types.h... yes > > > checking for sys/stat.h... yes > > > checking for stdlib.h... yes > > > checking for string.h... yes > > > checking for memory.h... yes > > > checking for strings.h... yes > > > checking for inttypes.h... yes > > > checking for stdint.h... yes > > > checking for unistd.h... yes > > > checking for dlfcn.h... yes > > > checking for objdir... .libs > > > checking if gcc supports -fno-rtti -fno-exceptions... no > > > checking for gcc option to produce PIC... -fPIC -DPIC > > > checking if gcc PIC flag -fPIC -DPIC works... yes > > > checking if gcc static flag -static works... yes > > > checking if gcc supports -c -o file.o... yes > > > checking if gcc supports -c -o file.o... (cached) yes > > > checking whether the gcc linker > > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) > > > supps > > > checking whether -lc should be explicitly linked in... no > > > checking dynamic linker characteristics... no > > > checking how to hardcode library paths into programs... immediate > > > checking whether stripping libraries is possible... yes > > > checking if libtool supports shared libraries... no > > > checking whether to build shared libraries... no > > > checking whether to build static libraries... yes > > > checking how to run the C++ preprocessor... g++ -E > > > checking for ld used by g++... /usr/armv7a-unknown-linux-gnueabi/bin/ld > > > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is GNU > > > ld... s > > > checking whether the g++ linker > > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) > > > suppo > > > checking for g++ option to produce PIC... -fPIC -DPIC > > > checking if g++ PIC flag -fPIC -DPIC works... yes > > > checking if g++ static flag -static works... yes > > > checking if g++ supports -c -o file.o... yes > > > checking if g++ supports -c -o file.o... (cached) yes > > > checking whether the g++ linker > > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) > > > suppo > > > checking dynamic linker characteristics... no > > > checking how to hardcode library paths into programs... immediate > > > checking for dlopen in -ldl... yes > > > checking for pthread_create in -lpthread... yes > > > checking for uuid_generate in -luuid... yes > > > checking for inline... inline > > > checking for stdlib.h... (cached) yes > > > checking for GNU libc compatible malloc... yes > > > checking for gettimeofday... yes > > > checking for munmap... yes > > > checking for socket... yes > > > checking for strerror... yes > > > checking for strtol... yes > > > checking for sched_getcpu... yes > > > checking for sysconf... yes > > > checking for makeinfo... yes > > > checking urcu-bp.h usability... yes > > > checking urcu-bp.h presence... yes > > > checking for urcu-bp.h... yes > > > checking caa_likely()... yes > > > checking for synchronize_rcu_bp in -lurcu-bp... yes > > > checking for call_rcu_bp in -lurcu-bp... yes > > > checking library format for the host system... elf32-littlearm > > > configure: creating ./config.status > > > config.status: creating Makefile > > > config.status: creating doc/Makefile > > > config.status: creating doc/examples/Makefile > > > config.status: creating include/Makefile > > > config.status: creating include/lttng/ust-version.h > > > config.status: creating snprintf/Makefile > > > config.status: creating libringbuffer/Makefile > > > config.status: creating liblttng-ust-comm/Makefile > > > config.status: creating liblttng-ust/Makefile > > > config.status: creating liblttng-ust-ctl/Makefile > > > config.status: creating liblttng-ust-fork/Makefile > > > config.status: creating liblttng-ust-java/Makefile > > > config.status: creating liblttng-ust-libc-wrapper/Makefile > > > config.status: creating tools/Makefile > > > config.status: creating tests/Makefile > > > config.status: creating tests/hello/Makefile > > > config.status: creating tests/hello-static-lib/Makefile > > > config.status: creating tests/hello.cxx/Makefile > > > config.status: creating tests/demo/Makefile > > > config.status: creating tests/fork/Makefile > > > config.status: creating tests/ust-basic-tracing/Makefile > > > config.status: creating tests/ust-multi-test/Makefile > > > config.status: creating lttng-ust.pc > > > config.status: creating config.h > > > config.status: config.h is unchanged > > > config.status: creating include/lttng/ust-config.h > > > config.status: include/lttng/ust-config.h is unchanged > > > config.status: executing depfiles commands > > > config.status: executing libtool commands > > > > > > Version name: Annedd'ale > > > New type of beer, 100% from Quebec, flavored with sapin beaumier needles, > > > with . > > > > > > LTTng-UST will be built with the following options: > > > Library format: elf32-littlearm > > > > > > Java support (JNI): Disabled > > > sdt.h integration: Disabled > > > Type 'make' to compile. > > > > > > *localhost lttng-ust-2.0.1 # make clean > > > *Making clean in doc > > > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/doc' > > > Making clean in examples > > > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/doc/examples' > > > rm -rf .libs _libs > > > rm -f *.lo > > > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/doc/examples' > > > Making clean in . > > > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/doc' > > > rm -rf .libs _libs > > > rm -f *.lo > > > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/doc' > > > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/doc' > > > Making clean in tests > > > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/tests' > > > Making clean in hello.cxx > > > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/hello.cxx' > > > rm -rf .libs _libs > > > rm -f hello > > > rm -f *.o > > > rm -f *.lo > > > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/hello.cxx' > > > Making clean in demo > > > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/demo' > > > rm -rf .libs _libs > > > test -z > > "liblttng-ust-provider-ust-tests-demo.laliblttng-ust-provider-ust-testa > > > rm -f "./so_locations" > > > rm -f "./so_locations" > > > rm -f demo > > > rm -f *.o > > > rm -f *.lo > > > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/demo' > > > Making clean in ust-multi-test > > > make[2]: Entering directory > > `/usr/src/lttng-ust-2.0.1/tests/ust-multi-test' > > > rm -rf .libs _libs > > > rm -f ust-multi-test > > > rm -f *.o > > > rm -f *.lo > > > make[2]: Leaving directory > > `/usr/src/lttng-ust-2.0.1/tests/ust-multi-test' > > > Making clean in ust-basic-tracing > > > make[2]: Entering directory > > > `/usr/src/lttng-ust-2.0.1/tests/ust-basic-tracing' > > > rm -rf .libs _libs > > > rm -f ust-basic-tracing > > > rm -f *.o > > > rm -f *.lo > > > make[2]: Leaving directory > > > `/usr/src/lttng-ust-2.0.1/tests/ust-basic-tracing' > > > Making clean in fork > > > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/fork' > > > rm -rf .libs _libs > > > rm -f fork fork2 > > > rm -f *.o > > > rm -f *.lo > > > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/fork' > > > Making clean in hello-static-lib > > > make[2]: Entering directory > > > `/usr/src/lttng-ust-2.0.1/tests/hello-static-lib' > > > rm -rf .libs _libs > > > test -z "liblttng-ust-provider-ust-test-hello.la" || rm -f > > > liblttng-ust-providea > > > rm -f "./so_locations" > > > rm -f hello > > > rm -f *.o > > > rm -f *.lo > > > make[2]: Leaving directory > > `/usr/src/lttng-ust-2.0.1/tests/hello-static-lib' > > > Making clean in hello > > > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/hello' > > > rm -rf .libs _libs > > > rm -f hello > > > rm -f *.o > > > rm -f *.lo > > > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/hello' > > > Making clean in . > > > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/tests' > > > rm -rf .libs _libs > > > test -z "libtap.a" || rm -f libtap.a > > > rm -f *.o > > > rm -f *.lo > > > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests' > > > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests' > > > Making clean in tools > > > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/tools' > > > rm -rf .libs _libs > > > rm -f *.lo > > > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/tools' > > > Making clean in liblttng-ust-libc-wrapper > > > make[1]: Entering directory > > > `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' > > > test -z "liblttng-ust-libc-wrapper.la" || rm -f > > liblttng-ust-libc-wrapper.la > > > rm -f "./so_locations" > > > rm -rf .libs _libs > > > rm -f *.o > > > rm -f *.lo > > > make[1]: Leaving directory > > > `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' > > > Making clean in liblttng-ust-fork > > > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' > > > test -z "liblttng-ust-fork.la" || rm -f liblttng-ust-fork.la > > > rm -f "./so_locations" > > > rm -rf .libs _libs > > > rm -f *.o > > > rm -f *.lo > > > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' > > > Making clean in liblttng-ust-ctl > > > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' > > > test -z "liblttng-ust-ctl.la" || rm -f liblttng-ust-ctl.la > > > rm -f "./so_locations" > > > rm -rf .libs _libs > > > rm -f *.o > > > rm -f *.lo > > > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' > > > Making clean in liblttng-ust > > > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust' > > > test -z "liblttng-ust-tracepoint.la liblttng-ust.la" || rm -f > > > liblttng-ust-traca > > > rm -f "./so_locations" > > > rm -f "./so_locations" > > > rm -rf .libs _libs > > > test -z "liblttng-ust-runtime.la liblttng-ust-support.la" || rm -f > > > liblttng-usta > > > rm -f "./so_locations" > > > rm -f "./so_locations" > > > rm -f *.o > > > rm -f *.lo > > > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust' > > > Making clean in liblttng-ust-comm > > > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' > > > rm -rf .libs _libs > > > test -z "liblttng-ust-comm.la" || rm -f liblttng-ust-comm.la > > > rm -f "./so_locations" > > > rm -f *.o > > > rm -f *.lo > > > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' > > > Making clean in libringbuffer > > > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/libringbuffer' > > > rm -rf .libs _libs > > > test -z "libringbuffer.la" || rm -f libringbuffer.la > > > rm -f "./so_locations" > > > rm -f *.o > > > rm -f *.lo > > > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/libringbuffer' > > > Making clean in snprintf > > > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/snprintf' > > > rm -rf .libs _libs > > > test -z "libustsnprintf.la" || rm -f libustsnprintf.la > > > rm -f "./so_locations" > > > rm -f *.o > > > rm -f *.lo > > > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/snprintf' > > > Making clean in include > > > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/include' > > > rm -rf .libs _libs > > > rm -f *.lo > > > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/include' > > > Making clean in . > > > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1' > > > rm -rf .libs _libs > > > rm -f *.lo > > > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1' > > > * > > > localhost lttng-ust-2.0.1 # make* > > > > > > make all-recursive > > > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1' > > > Making all in . > > > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1' > > > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1' > > > Making all in include > > > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/include' > > > make[2]: Nothing to be done for `all'. > > > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/include' > > > Making all in snprintf > > > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/snprintf' > > > CC libustsnprintf_la-fflush.lo > > > CC libustsnprintf_la-fvwrite.lo > > > CC libustsnprintf_la-mbrtowc_sb.lo > > > CC libustsnprintf_la-snprintf.lo > > > CC libustsnprintf_la-vfprintf.lo > > > CC libustsnprintf_la-wsetup.lo > > > CC libustsnprintf_la-core.lo > > > CC libustsnprintf_la-patient_write.lo > > > CCLD libustsnprintf.la > > > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/snprintf' > > > Making all in libringbuffer > > > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/libringbuffer' > > > CC libringbuffer_la-smp.lo > > > CC libringbuffer_la-shm.lo > > > shm.c: In function 'shm_object_table_append': > > > shm.c:108:9: warning: ignoring return value of 'mktemp', declared with > > > attributt > > > CC libringbuffer_la-ring_buffer_backend.lo > > > CC libringbuffer_la-ring_buffer_frontend.lo > > > CCLD libringbuffer.la > > > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/libringbuffer' > > > Making all in liblttng-ust-comm > > > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' > > > CC lttng-ust-comm.lo > > > CCLD liblttng-ust-comm.la > > > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' > > > Making all in liblttng-ust > > > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust' > > > CC liblttng_ust_tracepoint_la-tracepoint.lo > > > CCLD liblttng-ust-tracepoint.la > > > CC lttng-ust-comm.lo > > > CC lttng-ust-abi.lo > > > CC ltt-probes.lo > > > CC lttng-probe-ust.lo > > > CC lttng-context-vtid.lo > > > CC lttng-context-vpid.lo > > > CC lttng-context-pthread-id.lo > > > CC lttng-context-procname.lo > > > CC ltt-context.lo > > > CC ltt-events.lo > > > CCLD liblttng-ust-runtime.la > > > CC ust-core.lo > > > CC ltt-ring-buffer-client-discard.lo > > > CC ltt-ring-buffer-client-overwrite.lo > > > CC ltt-ring-buffer-metadata-client.lo > > > CCLD liblttng-ust-support.la > > > CCLD liblttng-ust.la > > > copying selected object files to avoid basename conflicts... > > > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust' > > > Making all in liblttng-ust-ctl > > > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' > > > CC ustctl.lo > > > CCLD liblttng-ust-ctl.la > > > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' > > > Making all in liblttng-ust-fork > > > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' > > > CC ustfork.lo > > > CCLD liblttng-ust-fork.la > > > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' > > > Making all in liblttng-ust-libc-wrapper > > > make[2]: Entering directory > > > `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' > > > CC lttng-ust-malloc.lo > > > CCLD liblttng-ust-libc-wrapper.la > > > make[2]: Leaving directory > > > `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' > > > Making all in tools > > > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/tools' > > > make[2]: Nothing to be done for `all'. > > > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/tools' > > > Making all in tests > > > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/tests' > > > Making all in . > > > make[3]: Entering directory `/usr/src/lttng-ust-2.0.1/tests' > > > CC tap.o > > > AR libtap.a > > > make[3]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests' > > > Making all in hello > > > make[3]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/hello' > > > CC hello.o > > > In file included from /usr/include/sys/socket.h:40:0, > > > from /usr/include/netinet/in.h:25, > > > from /usr/include/arpa/inet.h:23, > > > from hello.c:29: > > > /usr/include/bits/socket.h:431:23: warning: 'struct mmsghdr' declared > > > inside pat > > > /usr/include/bits/socket.h:431:23: warning: its scope is only this > > > definition ot > > > CC tp.o > > > In file included from ../../include/lttng/ust-events.h:23:0, > > > from ../../include/lttng/ust-tracepoint-event.h:17, > > > from ../../include/lttng/tracepoint-event.h:41, > > > from ust_tests_hello.h:60, > > > from tp.c:18: > > > /usr/local/include/urcu/hlist.h:3:0: warning: "NULL" redefined > > > /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/include/stddef.h:400:0: > > > note: tn > > > CCLD hello > > > ../../liblttng-ust/.libs/liblttng-ust.a(libringbuffer_la-shm.o): In > > > function `s: > > > /usr/src/lttng-ust-2.0.1/libringbuffer/shm.c:108: warning: the use of > > > `mktemp' ' > > > make[3]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/hello' > > > Making all in hello-static-lib > > > make[3]: Entering directory > > > `/usr/src/lttng-ust-2.0.1/tests/hello-static-lib' > > > CC tp.lo > > > In file included from ../../include/lttng/ust-events.h:23:0, > > > from ../../include/lttng/ust-tracepoint-event.h:17, > > > from ../../include/lttng/tracepoint-event.h:41, > > > from ust_tests_hello.h:60, > > > from tp.c:18: > > > /usr/local/include/urcu/hlist.h:3:0: warning: "NULL" redefined > > > /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/include/stddef.h:400:0: > > > note: tn > > > CCLD liblttng-ust-provider-ust-test-hello.la > > > CC hello.o > > > In file included from /usr/include/sys/socket.h:40:0, > > > from /usr/include/netinet/in.h:25, > > > from /usr/include/arpa/inet.h:23, > > > from hello.c:29: > > > /usr/include/bits/socket.h:431:23: warning: 'struct mmsghdr' declared > > > inside pat > > > /usr/include/bits/socket.h:431:23: warning: its scope is only this > > > definition ot > > > CCLD hello > > > > > /usr/src/lttng-ust-2.0.1/liblttng-ust/.libs/liblttng-ust.a(libringbuffer_la-shm: > > > /usr/src/lttng-ust-2.0.1/libringbuffer/shm.c:108: warning: the use of > > > `mktemp' ' > > > make[3]: Leaving directory > > `/usr/src/lttng-ust-2.0.1/tests/hello-static-lib' > > > Making all in fork > > > make[3]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/fork' > > > CC fork.o > > > In file included from ../../include/lttng/ust-events.h:23:0, > > > from ../../include/lttng/ust-tracepoint-event.h:17, > > > from ../../include/lttng/tracepoint-event.h:41, > > > from ust_tests_fork.h:52, > > > from fork.c:27: > > > /usr/local/include/urcu/hlist.h:3:0: warning: "NULL" redefined > > > /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/include/stddef.h:400:0: > > > note: tn > > > CCLD fork > > > ../../liblttng-ust/.libs/liblttng-ust.a(libringbuffer_la-shm.o): In > > > function `s: > > > /usr/src/lttng-ust-2.0.1/libringbuffer/shm.c:108: warning: the use of > > > `mktemp' ' > > > CC fork2.o > > > In file included from ../../include/lttng/ust-events.h:23:0, > > > from ../../include/lttng/ust-tracepoint-event.h:17, > > > from ../../include/lttng/tracepoint-event.h:41, > > > from ust_tests_fork.h:52, > > > from fork2.c:23: > > > /usr/local/include/urcu/hlist.h:3:0: warning: "NULL" redefined > > > /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/include/stddef.h:400:0: > > > note: tn > > > CCLD fork2 > > > ../../liblttng-ust/.libs/liblttng-ust.a(libringbuffer_la-shm.o): In > > > function `s: > > > /usr/src/lttng-ust-2.0.1/libringbuffer/shm.c:108: warning: the use of > > > `mktemp' ' > > > make[3]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/fork' > > > Making all in ust-basic-tracing > > > make[3]: Entering directory > > > `/usr/src/lttng-ust-2.0.1/tests/ust-basic-tracing' > > > CC ust-basic-tracing.o > > > CCLD ust-basic-tracing > > > ../../libringbuffer/.libs/libringbuffer.a(libringbuffer_la-shm.o): In > > > function : > > > /usr/src/lttng-ust-2.0.1/libringbuffer/shm.c:108: warning: the use of > > > `mktemp' ' > > > make[3]: Leaving directory > > > `/usr/src/lttng-ust-2.0.1/tests/ust-basic-tracing' > > > Making all in ust-multi-test > > > make[3]: Entering directory > > `/usr/src/lttng-ust-2.0.1/tests/ust-multi-test' > > > CC ust-multi-test.o > > > CCLD ust-multi-test > > > ../../libringbuffer/.libs/libringbuffer.a(libringbuffer_la-shm.o): In > > > function : > > > /usr/src/lttng-ust-2.0.1/libringbuffer/shm.c:108: warning: the use of > > > `mktemp' ' > > > make[3]: Leaving directory > > `/usr/src/lttng-ust-2.0.1/tests/ust-multi-test' > > > Making all in demo > > > make[3]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/demo' > > > CC tp.lo > > > In file included from ../../include/lttng/ust-events.h:23:0, > > > from ../../include/lttng/ust-tracepoint-event.h:17, > > > from ../../include/lttng/tracepoint-event.h:41, > > > from ust_tests_demo.h:49, > > > from tp.c:18: > > > /usr/local/include/urcu/hlist.h:3:0: warning: "NULL" redefined > > > /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/include/stddef.h:400:0: > > > note: tn > > > CC tp2.lo > > > In file included from ../../include/lttng/ust-events.h:23:0, > > > from ../../include/lttng/ust-tracepoint-event.h:17, > > > from ../../include/lttng/tracepoint-event.h:41, > > > from ust_tests_demo2.h:56, > > > from tp2.c:18: > > > /usr/local/include/urcu/hlist.h:3:0: warning: "NULL" redefined > > > /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/include/stddef.h:400:0: > > > note: tn > > > CCLD liblttng-ust-provider-ust-tests-demo.la > > > libtool: link: can not build a shared library > > > libtool: link: See the libtool documentation for more information. > > > libtool: link: Fatal configuration error. > > > make[3]: *** [liblttng-ust-provider-ust-tests-demo.la] Error 1 > > > make[3]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/demo' > > > make[2]: *** [all-recursive] Error 1 > > > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests' > > > make[1]: *** [all-recursive] Error 1 > > > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1' > > > make: *** [all] Error 2 > > > > > > > > > > > > It fails... > > > so do you think it can work or is it not suitable for using on armv7 > > > (OMAP4430) Pandaboard? > > > > > > Vanni Genua > > > > > > > > > On Tue, May 15, 2012 at 5:33 PM, Mathieu Desnoyers < > > > mathieu.desnoyers at efficios.com> wrote: > > > > > > > tracepoint.c: > > > > > > > > Fixed in master and stable-2.0 branches (upstream). Thanks for > > > > reporting. Missing stdio.h include. > > > > > > > > hello: > > > > > > > > did you try doing: > > > > > > > > LDFLAGS=-L/usr/local/lib ./configure --build=armv5 > > > > make clean > > > > make > > > > > > > > ? > > > > > > > > For some reason, it fails to see liburcu. > > > > > > > > Thanks, > > > > > > > > Mathieu > > > > > > > > * Vanni Genua (vannigenua at gmail.com) wrote: > > > > > here are the exact files: > > > > > /usr/src/lttng-ust-2.0.1/liblttng-ust/tracepoint.c > > > > > /usr/src/lttng-ust-2.0.1/liblttng_ust/...tests../hello ( it fails > > make > > > > > inside hello directory) > > > > > > > > > > On 5/15/12, Vanni Genua wrote: > > > > > > because i did the following steps on Pandaboard (armv7 OMAP4430) > > with > > > > > > Gentoo: > > > > > > 1) > > > > > > # cd /usr/src/lttng-modules > > > > > > #make clean > > > > > > #make > > > > > > #make modules install > > > > > > #depmode -a > > > > > > > > > > > > and it has gone OK! > > > > > > > > > > > > 2) > > > > > > # cd /usr/src/userspace-rcu-0.6.7 > > > > > > #make clean > > > > > > #make > > > > > > #make install > > > > > > #ldconfig > > > > > > > > > > > > and Gentoo installed userspace-rcu-0.6.7 correctly:OK! > > > > > > > > > > > > 3) > > > > > > > > > > > > #cd /usr/src/lttng-ust-2.0.1 (cos 2.0.2 was harder to compile...) > > > > > > # ./configure > > > > > > it gave me unsupported armv71 architecture so I did the following: > > > > > > #./configure --build armv5 > > > > > > and configuration went OK! > > > > > > #make > > > > > > and it give me a stucking error: hello (the hello word test > > program) > > > > > > undefined reference to function rcu_dereference_sym_bp > > > > > > also in tracepoint.c it has undefined first use of NULL ( I > > solved > > > > > > it by adding #define NULL 0) > > > > > > Tomorrow I'll copy the exact error lines when I go back to work. > > > > > > Any idea? > > > > > > Thanks > > > > > > Vanni > > > > > > > > > > > > > > > > > > On 5/15/12, Mathieu Desnoyers > > wrote: > > > > > >> userspace rcu works on arm v7. See its README file, under > > > > "ARCHITECTURES > > > > > >> SUPPORTED". > > > > > >> > > > > > >> Thanks, > > > > > >> > > > > > >> Mathieu > > > > > >> > > > > > >> * Vanni Genua (vannigenua at gmail.com) wrote: > > > > > >>> Hi, > > > > > >>> look here: > > > > > >>> > > > > > > http://gentoo.linuxhowtos.org/portage/dev-libs/userspace-rcu?show=knownbugs > > > > > >>> so can LTTng not work on armv7 architecture? > > > > > >>> Thanks. > > > > > >>> Vanni > > > > > >>> > > > > > >>> On Mon, May 14, 2012 at 11:04 AM, Vanni Genua < > > vannigenua at gmail.com> > > > > > >>> wrote: > > > > > >>> > > > > > >>> > Ok, > > > > > >>> > and what about emerging liburcu on Gentoo? It seems necessary > > for > > > > > >>> > installing lttng-tools. On http://lttng.org/urcu I found > > sources > > > > > >>> > packages > > > > > >>> > , but there is also a git repository: are they the same? So, > > > > should I > > > > > >>> > download these sources and then compile and install them on > > Gentoo? > > > > > >>> > Thanks. > > > > > >>> > Vanni Genua > > > > > >>> > > > > > > >>> > > > > > > >>> > On Wed, May 9, 2012 at 1:45 PM, Mathieu Desnoyers < > > > > > >>> > mathieu.desnoyers at efficios.com> wrote: > > > > > >>> > > > > > > >>> >> * Vanni Genua (vannigenua at gmail.com) wrote: > > > > > >>> >> > hi there, > > > > > >>> >> > I have some troubles in uinstalling lttng-modules.2.0.2 on > > > > kernel > > > > > >>> >> > 3.0.27-r46, I have top install them on the Pandaboard > > (OMAP4430) > > > > > >>> >> > using > > > > > >>> >> > Gentoo. > > > > > >>> >> > I just did make and it returns the following error > > messages: > > > > > >>> >> > *localhost lttng-modules-2.0.2 # make > > > > > >>> >> > make -C /lib/modules/3.0.27-rt46/build > > > > > >>> >> > M=/usr/src/lttng-modules-2.0.2 > > > > > >>> >> > modules > > > > > >>> >> > make: *** /lib/modules/3.0.27-rt46/build: No such file or > > > > > >>> >> > directory. > > > > > >>> >> Stop. > > > > > >>> >> > make: *** [default] Error 2 > > > > > >>> >> > > > > > > >>> >> > *As a matter of fact the directory lib/modules doesn't > > exist. > > > > Also > > > > > >>> >> there is > > > > > >>> >> > no /usr/src/linux directory on the pandaboard. > > > > > >>> >> > Pandaboard is running Gentoo OS from an SD card, on which > > there > > > > is > > > > > >>> >> > a > > > > > >>> >> > crosscompiled uImage of the kernel 3.0.27-rt46 and a Gentoo > > > > stage3. > > > > > >>> >> > > > > > > >>> >> > So I cannot do make and make modules_install for getting the > > > > lttng > > > > > >>> >> modules > > > > > >>> >> > installed. > > > > > >>> >> > Any idea? > > > > > >>> >> > > > > > >>> >> You'll have to cross-compile the modules on your SDK (see the > > > > Linux > > > > > >>> >> kernel make help for make modules_install env. var.), and then > > > > copy > > > > > >>> >> the > > > > > >>> >> modules to your target. Having your SDK setup for building > > > > modules is > > > > > >>> >> distro-specific, so you should ask further questions on how to > > > > > >>> >> install > > > > > >>> >> the SDK to your Linux distro support. > > > > > >>> >> > > > > > >>> >> Thanks, > > > > > >>> >> > > > > > >>> >> Mathieu > > > > > >>> >> > > > > > >>> >> > Thanks > > > > > >>> >> > Vanni > > > > > >>> >> > > > > > > >>> >> > ** > > > > > >>> >> > > > > > > >>> >> > > > > > > >>> >> > On Tue, May 8, 2012 at 3:04 PM, Vanni Genua < > > > > vannigenua at gmail.com> > > > > > >>> >> wrote: > > > > > >>> >> > > > > > > >>> >> > > Ok thanks. > > > > > >>> >> > > Vanni > > > > > >>> >> > > > > > > > >>> >> > > > > > > > >>> >> > > On Tue, May 8, 2012 at 3:00 PM, Mathieu Desnoyers < > > > > > >>> >> > > mathieu.desnoyers at efficios.com> wrote: > > > > > >>> >> > > > > > > > >>> >> > >> * Vanni Genua (vannigenua at gmail.com) wrote: > > > > > >>> >> > >> > Hi there, > > > > > >>> >> > >> > I have installed Gentoo (kernel 3.0.27 with rt46 real > > time > > > > > >>> >> > >> > patch) > > > > > >>> >> on > > > > > >>> >> > >> > Pandaboard (OMAP4430). > > > > > >>> >> > >> > Does LTTng support Linux kernel 3.0.27-rt46? > > > > > >>> >> > >> > If LTTng works with this kernel version, which are the > > > > LTTng > > > > > >>> >> modules for > > > > > >>> >> > >> > patching the kernel? > > > > > >>> >> > >> > > > > > >>> >> > >> lttng 2.0 should work with kernels 2.6.38 and more > > recent, > > > > which > > > > > >>> >> > >> includes 3.0. So you should try it out. See > > http://lttng.orgfor > > > > > >>> >> > >> details. It _should_ work with -rt, although testing > > feedback > > > > > >>> >> > >> would > > > > > >>> >> be > > > > > >>> >> > >> welcome. > > > > > >>> >> > >> > > > > > >>> >> > >> Thanks, > > > > > >>> >> > >> > > > > > >>> >> > >> Mathieu > > > > > >>> >> > >> > > > > > >>> >> > >> > Thanks. > > > > > >>> >> > >> > Vanni Genua > > > > > >>> >> > >> > > > > > >>> >> > >> -- > > > > > >>> >> > >> Mathieu Desnoyers > > > > > >>> >> > >> Operating System Efficiency R&D Consultant > > > > > >>> >> > >> EfficiOS Inc. > > > > > >>> >> > >> http://www.efficios.com > > > > > >>> >> > >> > > > > > >>> >> > > > > > > > >>> >> > > > > > > > >>> >> > > > > > >>> >> -- > > > > > >>> >> Mathieu Desnoyers > > > > > >>> >> Operating System Efficiency R&D Consultant > > > > > >>> >> EfficiOS Inc. > > > > > >>> >> http://www.efficios.com > > > > > >>> >> > > > > > >>> > > > > > > >>> > > > > > > >> > > > > > >> -- > > > > > >> Mathieu Desnoyers > > > > > >> Operating System Efficiency R&D Consultant > > > > > >> EfficiOS Inc. > > > > > >> http://www.efficios.com > > > > > >> > > > > > > > > > > > > > > -- > > > > Mathieu Desnoyers > > > > Operating System Efficiency R&D Consultant > > > > EfficiOS Inc. > > > > http://www.efficios.com > > > > > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed May 16 11:58:32 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 16 May 2012 11:58:32 -0400 Subject: [lttng-dev] Linux kernel 3.0.27-rt46 + LTTng In-Reply-To: References: <20120515165310.GB3377@Krystal> <20120515173304.GA3806@Krystal> <20120516135352.GA29727@Krystal> Message-ID: <20120516155832.GB7918@Krystal> See README file. Thanks, Mathieu * Vanni Genua (vannigenua at gmail.com) wrote: > missing .configure file, look this: > localhost ~ # cd /usr/src/lttng-ust-33661f9/ > localhost lttng-ust-33661f9 # ./configure > -bash: ./configure: No such file or directory > > > On Wed, May 16, 2012 at 2:24 PM, Vanni Genua wrote: > > > How do I access it? I found this link ( > > http://git.lttng.org/?p=lttng-ust.git), but how and what do I have to > > download? No .tar.bz2 file? > > thanks. > > Vanni > > > > > > On Wed, May 16, 2012 at 1:53 PM, Mathieu Desnoyers < > > mathieu.desnoyers at efficios.com> wrote: > > > >> Please try working on the git tree stable-2.0 branch (or on the master > >> branch). 2.0.1 is not the latest. > >> > >> Please submit this information through the bugtracker on > >> htpp://bugs.lttng.org , or send it to lttng-dev at lists.lttng.org . > >> > >> Having many people looking into your various issues will be helpful, > >> > >> Thanks, > >> > >> Mathieu > >> > >> * Vanni Genua (vannigenua at gmail.com) wrote: > >> > here are the logs: > >> > after having installed userspare-rcu.... > >> > *localhost #cd /usr/src/lttng-ust-2.0.1* > >> > *localhost #LDFLAGS=-L/usr/local/lib ./configure --build=armv5* > >> > ... > >> > checking whether the C compiler works... yes > >> > checking for C compiler default output file name... a.out > >> > checking for suffix of executables... > >> > checking whether we are cross compiling... no > >> > checking for suffix of object files... o > >> > checking whether we are using the GNU C compiler... yes > >> > checking whether gcc accepts -g... yes > >> > checking for gcc option to accept ISO C89... none needed > >> > checking for style of include used by make... GNU > >> > checking dependency style of gcc... gcc3 > >> > checking for g++... g++ > >> > checking whether we are using the GNU C++ compiler... yes > >> > checking whether g++ accepts -g... yes > >> > checking dependency style of g++... gcc3 > >> > checking whether make sets $(MAKE)... (cached) yes > >> > checking how to print strings... printf > >> > checking for a sed that does not truncate output... (cached) /bin/sed > >> > checking for grep that handles long lines and -e... /bin/grep > >> > checking for egrep... /bin/grep -E > >> > checking for fgrep... /bin/grep -F > >> > checking for ld used by gcc... /usr/armv7a-unknown-linux-gnueabi/bin/ld > >> > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is GNU > >> > ld... s > >> > checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B > >> > checking the name lister (/usr/bin/nm -B) interface... BSD nm > >> > checking whether ln -s works... yes > >> > checking the maximum length of command line arguments... 1572864 > >> > checking whether the shell understands some XSI constructs... yes > >> > checking whether the shell understands "+="... yes > >> > checking how to convert armv5-unknown-none file names to > >> armv5-unknown-none > >> > forp > >> > checking how to convert armv5-unknown-none file names to toolchain > >> > format... fup > >> > checking for /usr/armv7a-unknown-linux-gnueabi/bin/ld option to reload > >> > object fr > >> > checking for objdump... objdump > >> > checking how to recognize dependent libraries... unknown > >> > checking for dlltool... no > >> > checking how to associate runtime and link libraries... printf %s\n > >> > checking for ar... ar > >> > checking for archiver @FILE support... @ > >> > checking for strip... strip > >> > checking for ranlib... ranlib > >> > checking command to parse /usr/bin/nm -B output from gcc object... ok > >> > checking for sysroot... no > >> > checking for mt... no > >> > checking if : is a manifest tool... no > >> > checking how to run the C preprocessor... gcc -E > >> > checking for ANSI C header files... yes > >> > checking for sys/types.h... yes > >> > checking for sys/stat.h... yes > >> > checking for stdlib.h... yes > >> > checking for string.h... yes > >> > checking for memory.h... yes > >> > checking for strings.h... yes > >> > checking for inttypes.h... yes > >> > checking for stdint.h... yes > >> > checking for unistd.h... yes > >> > checking for dlfcn.h... yes > >> > checking for objdir... .libs > >> > checking if gcc supports -fno-rtti -fno-exceptions... no > >> > checking for gcc option to produce PIC... -fPIC -DPIC > >> > checking if gcc PIC flag -fPIC -DPIC works... yes > >> > checking if gcc static flag -static works... yes > >> > checking if gcc supports -c -o file.o... yes > >> > checking if gcc supports -c -o file.o... (cached) yes > >> > checking whether the gcc linker > >> (/usr/armv7a-unknown-linux-gnueabi/bin/ld) > >> > supps > >> > checking whether -lc should be explicitly linked in... no > >> > checking dynamic linker characteristics... no > >> > checking how to hardcode library paths into programs... immediate > >> > checking whether stripping libraries is possible... yes > >> > checking if libtool supports shared libraries... no > >> > checking whether to build shared libraries... no > >> > checking whether to build static libraries... yes > >> > checking how to run the C++ preprocessor... g++ -E > >> > checking for ld used by g++... /usr/armv7a-unknown-linux-gnueabi/bin/ld > >> > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is GNU > >> > ld... s > >> > checking whether the g++ linker > >> (/usr/armv7a-unknown-linux-gnueabi/bin/ld) > >> > suppo > >> > checking for g++ option to produce PIC... -fPIC -DPIC > >> > checking if g++ PIC flag -fPIC -DPIC works... yes > >> > checking if g++ static flag -static works... yes > >> > checking if g++ supports -c -o file.o... yes > >> > checking if g++ supports -c -o file.o... (cached) yes > >> > checking whether the g++ linker > >> (/usr/armv7a-unknown-linux-gnueabi/bin/ld) > >> > suppo > >> > checking dynamic linker characteristics... no > >> > checking how to hardcode library paths into programs... immediate > >> > checking for dlopen in -ldl... yes > >> > checking for pthread_create in -lpthread... yes > >> > checking for uuid_generate in -luuid... yes > >> > checking for inline... inline > >> > checking for stdlib.h... (cached) yes > >> > checking for GNU libc compatible malloc... yes > >> > checking for gettimeofday... yes > >> > checking for munmap... yes > >> > checking for socket... yes > >> > checking for strerror... yes > >> > checking for strtol... yes > >> > checking for sched_getcpu... yes > >> > checking for sysconf... yes > >> > checking for makeinfo... yes > >> > checking urcu-bp.h usability... yes > >> > checking urcu-bp.h presence... yes > >> > checking for urcu-bp.h... yes > >> > checking caa_likely()... yes > >> > checking for synchronize_rcu_bp in -lurcu-bp... yes > >> > checking for call_rcu_bp in -lurcu-bp... yes > >> > checking library format for the host system... elf32-littlearm > >> > configure: creating ./config.status > >> > config.status: creating Makefile > >> > config.status: creating doc/Makefile > >> > config.status: creating doc/examples/Makefile > >> > config.status: creating include/Makefile > >> > config.status: creating include/lttng/ust-version.h > >> > config.status: creating snprintf/Makefile > >> > config.status: creating libringbuffer/Makefile > >> > config.status: creating liblttng-ust-comm/Makefile > >> > config.status: creating liblttng-ust/Makefile > >> > config.status: creating liblttng-ust-ctl/Makefile > >> > config.status: creating liblttng-ust-fork/Makefile > >> > config.status: creating liblttng-ust-java/Makefile > >> > config.status: creating liblttng-ust-libc-wrapper/Makefile > >> > config.status: creating tools/Makefile > >> > config.status: creating tests/Makefile > >> > config.status: creating tests/hello/Makefile > >> > config.status: creating tests/hello-static-lib/Makefile > >> > config.status: creating tests/hello.cxx/Makefile > >> > config.status: creating tests/demo/Makefile > >> > config.status: creating tests/fork/Makefile > >> > config.status: creating tests/ust-basic-tracing/Makefile > >> > config.status: creating tests/ust-multi-test/Makefile > >> > config.status: creating lttng-ust.pc > >> > config.status: creating config.h > >> > config.status: config.h is unchanged > >> > config.status: creating include/lttng/ust-config.h > >> > config.status: include/lttng/ust-config.h is unchanged > >> > config.status: executing depfiles commands > >> > config.status: executing libtool commands > >> > > >> > Version name: Annedd'ale > >> > New type of beer, 100% from Quebec, flavored with sapin beaumier > >> needles, > >> > with . > >> > > >> > LTTng-UST will be built with the following options: > >> > Library format: elf32-littlearm > >> > > >> > Java support (JNI): Disabled > >> > sdt.h integration: Disabled > >> > Type 'make' to compile. > >> > > >> > *localhost lttng-ust-2.0.1 # make clean > >> > *Making clean in doc > >> > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/doc' > >> > Making clean in examples > >> > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/doc/examples' > >> > rm -rf .libs _libs > >> > rm -f *.lo > >> > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/doc/examples' > >> > Making clean in . > >> > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/doc' > >> > rm -rf .libs _libs > >> > rm -f *.lo > >> > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/doc' > >> > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/doc' > >> > Making clean in tests > >> > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/tests' > >> > Making clean in hello.cxx > >> > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/hello.cxx' > >> > rm -rf .libs _libs > >> > rm -f hello > >> > rm -f *.o > >> > rm -f *.lo > >> > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/hello.cxx' > >> > Making clean in demo > >> > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/demo' > >> > rm -rf .libs _libs > >> > test -z > >> "liblttng-ust-provider-ust-tests-demo.laliblttng-ust-provider-ust-testa > >> > rm -f "./so_locations" > >> > rm -f "./so_locations" > >> > rm -f demo > >> > rm -f *.o > >> > rm -f *.lo > >> > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/demo' > >> > Making clean in ust-multi-test > >> > make[2]: Entering directory > >> `/usr/src/lttng-ust-2.0.1/tests/ust-multi-test' > >> > rm -rf .libs _libs > >> > rm -f ust-multi-test > >> > rm -f *.o > >> > rm -f *.lo > >> > make[2]: Leaving directory > >> `/usr/src/lttng-ust-2.0.1/tests/ust-multi-test' > >> > Making clean in ust-basic-tracing > >> > make[2]: Entering directory > >> > `/usr/src/lttng-ust-2.0.1/tests/ust-basic-tracing' > >> > rm -rf .libs _libs > >> > rm -f ust-basic-tracing > >> > rm -f *.o > >> > rm -f *.lo > >> > make[2]: Leaving directory > >> > `/usr/src/lttng-ust-2.0.1/tests/ust-basic-tracing' > >> > Making clean in fork > >> > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/fork' > >> > rm -rf .libs _libs > >> > rm -f fork fork2 > >> > rm -f *.o > >> > rm -f *.lo > >> > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/fork' > >> > Making clean in hello-static-lib > >> > make[2]: Entering directory > >> > `/usr/src/lttng-ust-2.0.1/tests/hello-static-lib' > >> > rm -rf .libs _libs > >> > test -z "liblttng-ust-provider-ust-test-hello.la" || rm -f > >> > liblttng-ust-providea > >> > rm -f "./so_locations" > >> > rm -f hello > >> > rm -f *.o > >> > rm -f *.lo > >> > make[2]: Leaving directory > >> `/usr/src/lttng-ust-2.0.1/tests/hello-static-lib' > >> > Making clean in hello > >> > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/hello' > >> > rm -rf .libs _libs > >> > rm -f hello > >> > rm -f *.o > >> > rm -f *.lo > >> > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/hello' > >> > Making clean in . > >> > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/tests' > >> > rm -rf .libs _libs > >> > test -z "libtap.a" || rm -f libtap.a > >> > rm -f *.o > >> > rm -f *.lo > >> > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests' > >> > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests' > >> > Making clean in tools > >> > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/tools' > >> > rm -rf .libs _libs > >> > rm -f *.lo > >> > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/tools' > >> > Making clean in liblttng-ust-libc-wrapper > >> > make[1]: Entering directory > >> > `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' > >> > test -z "liblttng-ust-libc-wrapper.la" || rm -f > >> liblttng-ust-libc-wrapper.la > >> > rm -f "./so_locations" > >> > rm -rf .libs _libs > >> > rm -f *.o > >> > rm -f *.lo > >> > make[1]: Leaving directory > >> > `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' > >> > Making clean in liblttng-ust-fork > >> > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' > >> > test -z "liblttng-ust-fork.la" || rm -f liblttng-ust-fork.la > >> > rm -f "./so_locations" > >> > rm -rf .libs _libs > >> > rm -f *.o > >> > rm -f *.lo > >> > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' > >> > Making clean in liblttng-ust-ctl > >> > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' > >> > test -z "liblttng-ust-ctl.la" || rm -f liblttng-ust-ctl.la > >> > rm -f "./so_locations" > >> > rm -rf .libs _libs > >> > rm -f *.o > >> > rm -f *.lo > >> > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' > >> > Making clean in liblttng-ust > >> > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust' > >> > test -z "liblttng-ust-tracepoint.la liblttng-ust.la" || rm -f > >> > liblttng-ust-traca > >> > rm -f "./so_locations" > >> > rm -f "./so_locations" > >> > rm -rf .libs _libs > >> > test -z "liblttng-ust-runtime.la liblttng-ust-support.la" || rm -f > >> > liblttng-usta > >> > rm -f "./so_locations" > >> > rm -f "./so_locations" > >> > rm -f *.o > >> > rm -f *.lo > >> > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust' > >> > Making clean in liblttng-ust-comm > >> > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' > >> > rm -rf .libs _libs > >> > test -z "liblttng-ust-comm.la" || rm -f liblttng-ust-comm.la > >> > rm -f "./so_locations" > >> > rm -f *.o > >> > rm -f *.lo > >> > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' > >> > Making clean in libringbuffer > >> > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/libringbuffer' > >> > rm -rf .libs _libs > >> > test -z "libringbuffer.la" || rm -f libringbuffer.la > >> > rm -f "./so_locations" > >> > rm -f *.o > >> > rm -f *.lo > >> > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/libringbuffer' > >> > Making clean in snprintf > >> > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/snprintf' > >> > rm -rf .libs _libs > >> > test -z "libustsnprintf.la" || rm -f libustsnprintf.la > >> > rm -f "./so_locations" > >> > rm -f *.o > >> > rm -f *.lo > >> > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/snprintf' > >> > Making clean in include > >> > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1/include' > >> > rm -rf .libs _libs > >> > rm -f *.lo > >> > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1/include' > >> > Making clean in . > >> > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1' > >> > rm -rf .libs _libs > >> > rm -f *.lo > >> > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1' > >> > * > >> > localhost lttng-ust-2.0.1 # make* > >> > > >> > make all-recursive > >> > make[1]: Entering directory `/usr/src/lttng-ust-2.0.1' > >> > Making all in . > >> > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1' > >> > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1' > >> > Making all in include > >> > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/include' > >> > make[2]: Nothing to be done for `all'. > >> > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/include' > >> > Making all in snprintf > >> > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/snprintf' > >> > CC libustsnprintf_la-fflush.lo > >> > CC libustsnprintf_la-fvwrite.lo > >> > CC libustsnprintf_la-mbrtowc_sb.lo > >> > CC libustsnprintf_la-snprintf.lo > >> > CC libustsnprintf_la-vfprintf.lo > >> > CC libustsnprintf_la-wsetup.lo > >> > CC libustsnprintf_la-core.lo > >> > CC libustsnprintf_la-patient_write.lo > >> > CCLD libustsnprintf.la > >> > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/snprintf' > >> > Making all in libringbuffer > >> > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/libringbuffer' > >> > CC libringbuffer_la-smp.lo > >> > CC libringbuffer_la-shm.lo > >> > shm.c: In function 'shm_object_table_append': > >> > shm.c:108:9: warning: ignoring return value of 'mktemp', declared with > >> > attributt > >> > CC libringbuffer_la-ring_buffer_backend.lo > >> > CC libringbuffer_la-ring_buffer_frontend.lo > >> > CCLD libringbuffer.la > >> > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/libringbuffer' > >> > Making all in liblttng-ust-comm > >> > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' > >> > CC lttng-ust-comm.lo > >> > CCLD liblttng-ust-comm.la > >> > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' > >> > Making all in liblttng-ust > >> > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust' > >> > CC liblttng_ust_tracepoint_la-tracepoint.lo > >> > CCLD liblttng-ust-tracepoint.la > >> > CC lttng-ust-comm.lo > >> > CC lttng-ust-abi.lo > >> > CC ltt-probes.lo > >> > CC lttng-probe-ust.lo > >> > CC lttng-context-vtid.lo > >> > CC lttng-context-vpid.lo > >> > CC lttng-context-pthread-id.lo > >> > CC lttng-context-procname.lo > >> > CC ltt-context.lo > >> > CC ltt-events.lo > >> > CCLD liblttng-ust-runtime.la > >> > CC ust-core.lo > >> > CC ltt-ring-buffer-client-discard.lo > >> > CC ltt-ring-buffer-client-overwrite.lo > >> > CC ltt-ring-buffer-metadata-client.lo > >> > CCLD liblttng-ust-support.la > >> > CCLD liblttng-ust.la > >> > copying selected object files to avoid basename conflicts... > >> > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust' > >> > Making all in liblttng-ust-ctl > >> > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' > >> > CC ustctl.lo > >> > CCLD liblttng-ust-ctl.la > >> > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' > >> > Making all in liblttng-ust-fork > >> > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' > >> > CC ustfork.lo > >> > CCLD liblttng-ust-fork.la > >> > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' > >> > Making all in liblttng-ust-libc-wrapper > >> > make[2]: Entering directory > >> > `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' > >> > CC lttng-ust-malloc.lo > >> > CCLD liblttng-ust-libc-wrapper.la > >> > make[2]: Leaving directory > >> > `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' > >> > Making all in tools > >> > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/tools' > >> > make[2]: Nothing to be done for `all'. > >> > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/tools' > >> > Making all in tests > >> > make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/tests' > >> > Making all in . > >> > make[3]: Entering directory `/usr/src/lttng-ust-2.0.1/tests' > >> > CC tap.o > >> > AR libtap.a > >> > make[3]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests' > >> > Making all in hello > >> > make[3]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/hello' > >> > CC hello.o > >> > In file included from /usr/include/sys/socket.h:40:0, > >> > from /usr/include/netinet/in.h:25, > >> > from /usr/include/arpa/inet.h:23, > >> > from hello.c:29: > >> > /usr/include/bits/socket.h:431:23: warning: 'struct mmsghdr' declared > >> > inside pat > >> > /usr/include/bits/socket.h:431:23: warning: its scope is only this > >> > definition ot > >> > CC tp.o > >> > In file included from ../../include/lttng/ust-events.h:23:0, > >> > from ../../include/lttng/ust-tracepoint-event.h:17, > >> > from ../../include/lttng/tracepoint-event.h:41, > >> > from ust_tests_hello.h:60, > >> > from tp.c:18: > >> > /usr/local/include/urcu/hlist.h:3:0: warning: "NULL" redefined > >> > /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/include/stddef.h:400:0: > >> > note: tn > >> > CCLD hello > >> > ../../liblttng-ust/.libs/liblttng-ust.a(libringbuffer_la-shm.o): In > >> > function `s: > >> > /usr/src/lttng-ust-2.0.1/libringbuffer/shm.c:108: warning: the use of > >> > `mktemp' ' > >> > make[3]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/hello' > >> > Making all in hello-static-lib > >> > make[3]: Entering directory > >> > `/usr/src/lttng-ust-2.0.1/tests/hello-static-lib' > >> > CC tp.lo > >> > In file included from ../../include/lttng/ust-events.h:23:0, > >> > from ../../include/lttng/ust-tracepoint-event.h:17, > >> > from ../../include/lttng/tracepoint-event.h:41, > >> > from ust_tests_hello.h:60, > >> > from tp.c:18: > >> > /usr/local/include/urcu/hlist.h:3:0: warning: "NULL" redefined > >> > /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/include/stddef.h:400:0: > >> > note: tn > >> > CCLD liblttng-ust-provider-ust-test-hello.la > >> > CC hello.o > >> > In file included from /usr/include/sys/socket.h:40:0, > >> > from /usr/include/netinet/in.h:25, > >> > from /usr/include/arpa/inet.h:23, > >> > from hello.c:29: > >> > /usr/include/bits/socket.h:431:23: warning: 'struct mmsghdr' declared > >> > inside pat > >> > /usr/include/bits/socket.h:431:23: warning: its scope is only this > >> > definition ot > >> > CCLD hello > >> > > >> /usr/src/lttng-ust-2.0.1/liblttng-ust/.libs/liblttng-ust.a(libringbuffer_la-shm: > >> > /usr/src/lttng-ust-2.0.1/libringbuffer/shm.c:108: warning: the use of > >> > `mktemp' ' > >> > make[3]: Leaving directory > >> `/usr/src/lttng-ust-2.0.1/tests/hello-static-lib' > >> > Making all in fork > >> > make[3]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/fork' > >> > CC fork.o > >> > In file included from ../../include/lttng/ust-events.h:23:0, > >> > from ../../include/lttng/ust-tracepoint-event.h:17, > >> > from ../../include/lttng/tracepoint-event.h:41, > >> > from ust_tests_fork.h:52, > >> > from fork.c:27: > >> > /usr/local/include/urcu/hlist.h:3:0: warning: "NULL" redefined > >> > /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/include/stddef.h:400:0: > >> > note: tn > >> > CCLD fork > >> > ../../liblttng-ust/.libs/liblttng-ust.a(libringbuffer_la-shm.o): In > >> > function `s: > >> > /usr/src/lttng-ust-2.0.1/libringbuffer/shm.c:108: warning: the use of > >> > `mktemp' ' > >> > CC fork2.o > >> > In file included from ../../include/lttng/ust-events.h:23:0, > >> > from ../../include/lttng/ust-tracepoint-event.h:17, > >> > from ../../include/lttng/tracepoint-event.h:41, > >> > from ust_tests_fork.h:52, > >> > from fork2.c:23: > >> > /usr/local/include/urcu/hlist.h:3:0: warning: "NULL" redefined > >> > /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/include/stddef.h:400:0: > >> > note: tn > >> > CCLD fork2 > >> > ../../liblttng-ust/.libs/liblttng-ust.a(libringbuffer_la-shm.o): In > >> > function `s: > >> > /usr/src/lttng-ust-2.0.1/libringbuffer/shm.c:108: warning: the use of > >> > `mktemp' ' > >> > make[3]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/fork' > >> > Making all in ust-basic-tracing > >> > make[3]: Entering directory > >> > `/usr/src/lttng-ust-2.0.1/tests/ust-basic-tracing' > >> > CC ust-basic-tracing.o > >> > CCLD ust-basic-tracing > >> > ../../libringbuffer/.libs/libringbuffer.a(libringbuffer_la-shm.o): In > >> > function : > >> > /usr/src/lttng-ust-2.0.1/libringbuffer/shm.c:108: warning: the use of > >> > `mktemp' ' > >> > make[3]: Leaving directory > >> > `/usr/src/lttng-ust-2.0.1/tests/ust-basic-tracing' > >> > Making all in ust-multi-test > >> > make[3]: Entering directory > >> `/usr/src/lttng-ust-2.0.1/tests/ust-multi-test' > >> > CC ust-multi-test.o > >> > CCLD ust-multi-test > >> > ../../libringbuffer/.libs/libringbuffer.a(libringbuffer_la-shm.o): In > >> > function : > >> > /usr/src/lttng-ust-2.0.1/libringbuffer/shm.c:108: warning: the use of > >> > `mktemp' ' > >> > make[3]: Leaving directory > >> `/usr/src/lttng-ust-2.0.1/tests/ust-multi-test' > >> > Making all in demo > >> > make[3]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/demo' > >> > CC tp.lo > >> > In file included from ../../include/lttng/ust-events.h:23:0, > >> > from ../../include/lttng/ust-tracepoint-event.h:17, > >> > from ../../include/lttng/tracepoint-event.h:41, > >> > from ust_tests_demo.h:49, > >> > from tp.c:18: > >> > /usr/local/include/urcu/hlist.h:3:0: warning: "NULL" redefined > >> > /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/include/stddef.h:400:0: > >> > note: tn > >> > CC tp2.lo > >> > In file included from ../../include/lttng/ust-events.h:23:0, > >> > from ../../include/lttng/ust-tracepoint-event.h:17, > >> > from ../../include/lttng/tracepoint-event.h:41, > >> > from ust_tests_demo2.h:56, > >> > from tp2.c:18: > >> > /usr/local/include/urcu/hlist.h:3:0: warning: "NULL" redefined > >> > /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/include/stddef.h:400:0: > >> > note: tn > >> > CCLD liblttng-ust-provider-ust-tests-demo.la > >> > libtool: link: can not build a shared library > >> > libtool: link: See the libtool documentation for more information. > >> > libtool: link: Fatal configuration error. > >> > make[3]: *** [liblttng-ust-provider-ust-tests-demo.la] Error 1 > >> > make[3]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/demo' > >> > make[2]: *** [all-recursive] Error 1 > >> > make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests' > >> > make[1]: *** [all-recursive] Error 1 > >> > make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1' > >> > make: *** [all] Error 2 > >> > > >> > > >> > > >> > It fails... > >> > so do you think it can work or is it not suitable for using on armv7 > >> > (OMAP4430) Pandaboard? > >> > > >> > Vanni Genua > >> > > >> > > >> > On Tue, May 15, 2012 at 5:33 PM, Mathieu Desnoyers < > >> > mathieu.desnoyers at efficios.com> wrote: > >> > > >> > > tracepoint.c: > >> > > > >> > > Fixed in master and stable-2.0 branches (upstream). Thanks for > >> > > reporting. Missing stdio.h include. > >> > > > >> > > hello: > >> > > > >> > > did you try doing: > >> > > > >> > > LDFLAGS=-L/usr/local/lib ./configure --build=armv5 > >> > > make clean > >> > > make > >> > > > >> > > ? > >> > > > >> > > For some reason, it fails to see liburcu. > >> > > > >> > > Thanks, > >> > > > >> > > Mathieu > >> > > > >> > > * Vanni Genua (vannigenua at gmail.com) wrote: > >> > > > here are the exact files: > >> > > > /usr/src/lttng-ust-2.0.1/liblttng-ust/tracepoint.c > >> > > > /usr/src/lttng-ust-2.0.1/liblttng_ust/...tests../hello ( it fails > >> make > >> > > > inside hello directory) > >> > > > > >> > > > On 5/15/12, Vanni Genua wrote: > >> > > > > because i did the following steps on Pandaboard (armv7 OMAP4430) > >> with > >> > > > > Gentoo: > >> > > > > 1) > >> > > > > # cd /usr/src/lttng-modules > >> > > > > #make clean > >> > > > > #make > >> > > > > #make modules install > >> > > > > #depmode -a > >> > > > > > >> > > > > and it has gone OK! > >> > > > > > >> > > > > 2) > >> > > > > # cd /usr/src/userspace-rcu-0.6.7 > >> > > > > #make clean > >> > > > > #make > >> > > > > #make install > >> > > > > #ldconfig > >> > > > > > >> > > > > and Gentoo installed userspace-rcu-0.6.7 correctly:OK! > >> > > > > > >> > > > > 3) > >> > > > > > >> > > > > #cd /usr/src/lttng-ust-2.0.1 (cos 2.0.2 was harder to compile...) > >> > > > > # ./configure > >> > > > > it gave me unsupported armv71 architecture so I did the following: > >> > > > > #./configure --build armv5 > >> > > > > and configuration went OK! > >> > > > > #make > >> > > > > and it give me a stucking error: hello (the hello word test > >> program) > >> > > > > undefined reference to function rcu_dereference_sym_bp > >> > > > > also in tracepoint.c it has undefined first use of NULL ( I > >> solved > >> > > > > it by adding #define NULL 0) > >> > > > > Tomorrow I'll copy the exact error lines when I go back to work. > >> > > > > Any idea? > >> > > > > Thanks > >> > > > > Vanni > >> > > > > > >> > > > > > >> > > > > On 5/15/12, Mathieu Desnoyers > >> wrote: > >> > > > >> userspace rcu works on arm v7. See its README file, under > >> > > "ARCHITECTURES > >> > > > >> SUPPORTED". > >> > > > >> > >> > > > >> Thanks, > >> > > > >> > >> > > > >> Mathieu > >> > > > >> > >> > > > >> * Vanni Genua (vannigenua at gmail.com) wrote: > >> > > > >>> Hi, > >> > > > >>> look here: > >> > > > >>> > >> > > > >> http://gentoo.linuxhowtos.org/portage/dev-libs/userspace-rcu?show=knownbugs > >> > > > >>> so can LTTng not work on armv7 architecture? > >> > > > >>> Thanks. > >> > > > >>> Vanni > >> > > > >>> > >> > > > >>> On Mon, May 14, 2012 at 11:04 AM, Vanni Genua < > >> vannigenua at gmail.com> > >> > > > >>> wrote: > >> > > > >>> > >> > > > >>> > Ok, > >> > > > >>> > and what about emerging liburcu on Gentoo? It seems necessary > >> for > >> > > > >>> > installing lttng-tools. On http://lttng.org/urcu I found > >> sources > >> > > > >>> > packages > >> > > > >>> > , but there is also a git repository: are they the same? So, > >> > > should I > >> > > > >>> > download these sources and then compile and install them on > >> Gentoo? > >> > > > >>> > Thanks. > >> > > > >>> > Vanni Genua > >> > > > >>> > > >> > > > >>> > > >> > > > >>> > On Wed, May 9, 2012 at 1:45 PM, Mathieu Desnoyers < > >> > > > >>> > mathieu.desnoyers at efficios.com> wrote: > >> > > > >>> > > >> > > > >>> >> * Vanni Genua (vannigenua at gmail.com) wrote: > >> > > > >>> >> > hi there, > >> > > > >>> >> > I have some troubles in uinstalling lttng-modules.2.0.2 on > >> > > kernel > >> > > > >>> >> > 3.0.27-r46, I have top install them on the Pandaboard > >> (OMAP4430) > >> > > > >>> >> > using > >> > > > >>> >> > Gentoo. > >> > > > >>> >> > I just did make and it returns the following error > >> messages: > >> > > > >>> >> > *localhost lttng-modules-2.0.2 # make > >> > > > >>> >> > make -C /lib/modules/3.0.27-rt46/build > >> > > > >>> >> > M=/usr/src/lttng-modules-2.0.2 > >> > > > >>> >> > modules > >> > > > >>> >> > make: *** /lib/modules/3.0.27-rt46/build: No such file or > >> > > > >>> >> > directory. > >> > > > >>> >> Stop. > >> > > > >>> >> > make: *** [default] Error 2 > >> > > > >>> >> > > >> > > > >>> >> > *As a matter of fact the directory lib/modules doesn't > >> exist. > >> > > Also > >> > > > >>> >> there is > >> > > > >>> >> > no /usr/src/linux directory on the pandaboard. > >> > > > >>> >> > Pandaboard is running Gentoo OS from an SD card, on which > >> there > >> > > is > >> > > > >>> >> > a > >> > > > >>> >> > crosscompiled uImage of the kernel 3.0.27-rt46 and a Gentoo > >> > > stage3. > >> > > > >>> >> > > >> > > > >>> >> > So I cannot do make and make modules_install for getting > >> the > >> > > lttng > >> > > > >>> >> modules > >> > > > >>> >> > installed. > >> > > > >>> >> > Any idea? > >> > > > >>> >> > >> > > > >>> >> You'll have to cross-compile the modules on your SDK (see the > >> > > Linux > >> > > > >>> >> kernel make help for make modules_install env. var.), and > >> then > >> > > copy > >> > > > >>> >> the > >> > > > >>> >> modules to your target. Having your SDK setup for building > >> > > modules is > >> > > > >>> >> distro-specific, so you should ask further questions on how > >> to > >> > > > >>> >> install > >> > > > >>> >> the SDK to your Linux distro support. > >> > > > >>> >> > >> > > > >>> >> Thanks, > >> > > > >>> >> > >> > > > >>> >> Mathieu > >> > > > >>> >> > >> > > > >>> >> > Thanks > >> > > > >>> >> > Vanni > >> > > > >>> >> > > >> > > > >>> >> > ** > >> > > > >>> >> > > >> > > > >>> >> > > >> > > > >>> >> > On Tue, May 8, 2012 at 3:04 PM, Vanni Genua < > >> > > vannigenua at gmail.com> > >> > > > >>> >> wrote: > >> > > > >>> >> > > >> > > > >>> >> > > Ok thanks. > >> > > > >>> >> > > Vanni > >> > > > >>> >> > > > >> > > > >>> >> > > > >> > > > >>> >> > > On Tue, May 8, 2012 at 3:00 PM, Mathieu Desnoyers < > >> > > > >>> >> > > mathieu.desnoyers at efficios.com> wrote: > >> > > > >>> >> > > > >> > > > >>> >> > >> * Vanni Genua (vannigenua at gmail.com) wrote: > >> > > > >>> >> > >> > Hi there, > >> > > > >>> >> > >> > I have installed Gentoo (kernel 3.0.27 with rt46 real > >> time > >> > > > >>> >> > >> > patch) > >> > > > >>> >> on > >> > > > >>> >> > >> > Pandaboard (OMAP4430). > >> > > > >>> >> > >> > Does LTTng support Linux kernel 3.0.27-rt46? > >> > > > >>> >> > >> > If LTTng works with this kernel version, which are the > >> > > LTTng > >> > > > >>> >> modules for > >> > > > >>> >> > >> > patching the kernel? > >> > > > >>> >> > >> > >> > > > >>> >> > >> lttng 2.0 should work with kernels 2.6.38 and more > >> recent, > >> > > which > >> > > > >>> >> > >> includes 3.0. So you should try it out. See > >> http://lttng.orgfor > >> > > > >>> >> > >> details. It _should_ work with -rt, although testing > >> feedback > >> > > > >>> >> > >> would > >> > > > >>> >> be > >> > > > >>> >> > >> welcome. > >> > > > >>> >> > >> > >> > > > >>> >> > >> Thanks, > >> > > > >>> >> > >> > >> > > > >>> >> > >> Mathieu > >> > > > >>> >> > >> > >> > > > >>> >> > >> > Thanks. > >> > > > >>> >> > >> > Vanni Genua > >> > > > >>> >> > >> > >> > > > >>> >> > >> -- > >> > > > >>> >> > >> Mathieu Desnoyers > >> > > > >>> >> > >> Operating System Efficiency R&D Consultant > >> > > > >>> >> > >> EfficiOS Inc. > >> > > > >>> >> > >> http://www.efficios.com > >> > > > >>> >> > >> > >> > > > >>> >> > > > >> > > > >>> >> > > > >> > > > >>> >> > >> > > > >>> >> -- > >> > > > >>> >> Mathieu Desnoyers > >> > > > >>> >> Operating System Efficiency R&D Consultant > >> > > > >>> >> EfficiOS Inc. > >> > > > >>> >> http://www.efficios.com > >> > > > >>> >> > >> > > > >>> > > >> > > > >>> > > >> > > > >> > >> > > > >> -- > >> > > > >> Mathieu Desnoyers > >> > > > >> Operating System Efficiency R&D Consultant > >> > > > >> EfficiOS Inc. > >> > > > >> http://www.efficios.com > >> > > > >> > >> > > > > > >> > > > >> > > -- > >> > > Mathieu Desnoyers > >> > > Operating System Efficiency R&D Consultant > >> > > EfficiOS Inc. > >> > > http://www.efficios.com > >> > > > >> > >> -- > >> Mathieu Desnoyers > >> Operating System Efficiency R&D Consultant > >> EfficiOS Inc. > >> http://www.efficios.com > >> > > > > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From paulmck at linux.vnet.ibm.com Wed May 16 13:18:03 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Wed, 16 May 2012 10:18:03 -0700 Subject: [lttng-dev] [RFC PATCH urcu] Document uatomic operations In-Reply-To: <20120515121003.GA31468@Krystal> References: <20120515023901.GA22786@Krystal> <20120515040936.GB2412@linux.vnet.ibm.com> <20120515121003.GA31468@Krystal> Message-ID: <20120516171803.GB2441@linux.vnet.ibm.com> On Tue, May 15, 2012 at 08:10:03AM -0400, Mathieu Desnoyers wrote: > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > On Mon, May 14, 2012 at 10:39:01PM -0400, Mathieu Desnoyers wrote: > > > Document each atomic operation provided by urcu/uatomic.h, along with > > > their memory barrier guarantees. > > > > Great to see the documentation!!! Some comments below. > > > > Thanx, Paul > > > > > Signed-off-by: Mathieu Desnoyers > > > --- > > > diff --git a/doc/Makefile.am b/doc/Makefile.am > > > index bec1d7c..db9811c 100644 > > > --- a/doc/Makefile.am > > > +++ b/doc/Makefile.am > > > @@ -1 +1 @@ > > > -dist_doc_DATA = rcu-api.txt > > > +dist_doc_DATA = rcu-api.txt uatomic-api.txt > > > diff --git a/doc/uatomic-api.txt b/doc/uatomic-api.txt > > > new file mode 100644 > > > index 0000000..3605acf > > > --- /dev/null > > > +++ b/doc/uatomic-api.txt > > > @@ -0,0 +1,80 @@ > > > +Userspace RCU Atomic Operations API > > > +by Mathieu Desnoyers and Paul E. McKenney > > > + > > > + > > > +This document describes the API. Those are the atomic > > > +operations provided by the Userspace RCU library. The general rule > > > +regarding memory barriers is that only uatomic_xchg(), > > > +uatomic_cmpxchg(), uatomic_add_return(), and uatomic_sub_return() imply > > > +full memory barriers before and after the atomic operation. Other > > > +primitives don't guarantee any memory barrier. > > > + > > > +Only atomic operations performed on integers ("int" and "long", signed > > > +and unsigned) are supported on all architectures. Some architectures > > > +also support 1-byte and 2-byte atomic operations. Those respectively > > > +have UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT defined when > > > +uatomic.h is included. An architecture trying to perform an atomic write > > > +to a type size not supported by the architecture will trigger an illegal > > > +instruction. > > > + > > > +In the description below, "type" is a type that can be atomically > > > +written to by the architecture. It needs to be at most word-sized, and > > > +its alignment needs to greater or equal to its size. > > > + > > > +type uatomic_set(type *addr, type v) > > > + > > > + Atomically write @v into @addr. > > > > Wouldn't this instead be "void uatomic_set(type *addr, type v)"? > > Well, in that case, we'd need to change the macro. Currently, > _uatomic_set maps directly to: > > #define _uatomic_set(addr, v) CMM_STORE_SHARED(*(addr), (v)) > > and CMM_STORE_SHARED returns v. The question becomes: should we change > _uatomic_set or CMM_STORE_SHARED so they don't return anything, or > document that they return something ? > > One thing I noticed is that linters often complain that the return value > of CMM_STORE_SHARED is never used. One thing we could look into is to > try some gcc attributes and/or linter annotations to flag this return > value as possibly unused. Thoughts ? Hmmm... Does the following work? #define _uatomic_set(addr, v) ((void)CMM_STORE_SHARED(*(addr), (v))) > > By "Atomically write @v into @addr", what is meant is that no concurrent > > operation that reads from addr will see partial effects of uatomic_set(), > > correct? In other words, the concurrent read will either see v or > > the old value, not a mush of the two. > > yep. I added that clarification. > > > > > > + > > > +type uatomic_read(type *addr) > > > + > > > + Atomically read @v from @addr. > > > > Similar comments on the meaning of "atomically". This may sound picky, > > but people coming from an x86 environment might otherwise assume that > > there is lock prefix involved... > > same. > > > > > > + > > > +type uatomic_cmpxchg(type *addr, type old, type new) > > > + > > > + Atomically check if @addr contains @old. If true, then replace > > > + the content of @addr by @new. Return the value previously > > > + contained by @addr. This function imply a full memory barrier > > > + before and after the atomic operation. > > > > Suggest "then atomically replace" or some such. It might not hurt > > to add that this is an atomic read-modify-write operation. > > Updated to: > > type uatomic_cmpxchg(type *addr, type old, type new) > > An atomic read-modify-write operation that performs this > sequence of operations atomically: check if @addr contains @old. > If true, then replace the content of @addr by @new. Return the > value previously contained by @addr. This function imply a full > memory barrier before and after the atomic operation. > > > > > Similar comments on the other value-returning atomics. > > Will do something similar. > > > > > > + > > > +type uatomic_xchg(type *addr, type new) > > > + > > > + Atomically replace the content of @addr by @new, and return the > > > + value previously contained by @addr. This function imply a full > > > + memory barrier before and after the atomic operation. > > > + > > > +type uatomic_add_return(type *addr, type v) > > > +type uatomic_sub_return(type *addr, type v) > > > + > > > + Atomically increment/decrement the content of @addr by @v, and > > > + return the resulting value. This function imply a full memory > > > + barrier before and after the atomic operation. > > > + > > > +void uatomic_and(type *addr, type mask) > > > +void uatomic_or(type *addr, type mask) > > > + > > > + Atomically write the result of bitwise "and"/"or" between the > > > + content of @addr and @mask into @addr. Memory barriers are > > > + provided by explicitly using cmm_smp_mb__before_uatomic_and(), > > > + cmm_smp_mb__after_uatomic_and(), > > > + cmm_smp_mb__before_uatomic_or(), and > > > + cmm_smp_mb__after_uatomic_or(). > > > > I suggest replacing "Memory barriers are provided ..." with something like > > "These operations do not necessarily imply memory barriers. If memory > > barriers are needed, they may be provided ...". Then perhaps add a > > sentence stating that the advantage of using the four __before_/__after_ > > primitives is that they are no-ops on architectures in which the underlying > > atomic instructions implicitly supply the needed memory barriers. > > > > Simlar comments on the other non-value-returning atomic operations below. > > OK, done. > > Here is the update: > > > diff --git a/doc/Makefile.am b/doc/Makefile.am > index 27d3793..3422653 100644 > --- a/doc/Makefile.am > +++ b/doc/Makefile.am > @@ -1 +1 @@ > -dist_doc_DATA = rcu-api.txt cds-api.txt > +dist_doc_DATA = rcu-api.txt cds-api.txt uatomic-api.txt > diff --git a/doc/uatomic-api.txt b/doc/uatomic-api.txt > new file mode 100644 > index 0000000..3ad8fbb > --- /dev/null > +++ b/doc/uatomic-api.txt > @@ -0,0 +1,102 @@ > +Userspace RCU Atomic Operations API > +by Mathieu Desnoyers and Paul E. McKenney > + > + > +This document describes the API. Those are the atomic > +operations provided by the Userspace RCU library. The general rule > +regarding memory barriers is that only uatomic_xchg(), > +uatomic_cmpxchg(), uatomic_add_return(), and uatomic_sub_return() imply > +full memory barriers before and after the atomic operation. Other > +primitives don't guarantee any memory barrier. > + > +Only atomic operations performed on integers ("int" and "long", signed > +and unsigned) are supported on all architectures. Some architectures > +also support 1-byte and 2-byte atomic operations. Those respectively > +have UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT defined when > +uatomic.h is included. An architecture trying to perform an atomic write > +to a type size not supported by the architecture will trigger an illegal > +instruction. > + > +In the description below, "type" is a type that can be atomically > +written to by the architecture. It needs to be at most word-sized, and > +its alignment needs to greater or equal to its size. > + > +type uatomic_set(type *addr, type v) > + > + Atomically write @v into @addr. By "atomically", we mean that no > + concurrent operation that reads from addr will see partial > + effects of uatomic_set(). Good clarification! If this is to return the value written, it should say so. (I would prefer no return, as this is the most common usage and the value written is easily available anyway.) > +type uatomic_read(type *addr) > + > + Atomically read @v from @addr. By "atomically", we mean that > + uatomic_read() cannot see a partial effect of any concurrent > + uatomic update. > + > +type uatomic_cmpxchg(type *addr, type old, type new) > + > + An atomic read-modify-write operation that performs this > + sequence of operations atomically: check if @addr contains @old. > + If true, then replace the content of @addr by @new. Return the > + value previously contained by @addr. This function imply a full > + memory barrier before and after the atomic operation. Good clarification! (And below as well.) > +type uatomic_xchg(type *addr, type new) > + > + An atomic read-modify-write operation that performs this sequence > + of operations atomically: replace the content of @addr by @new, > + and return the value previously contained by @addr. This > + function imply a full memory barrier before and after the atomic > + operation. > + > +type uatomic_add_return(type *addr, type v) > +type uatomic_sub_return(type *addr, type v) > + > + An atomic read-modify-write operation that performs this > + sequence of operations atomically: increment/decrement the > + content of @addr by @v, and return the resulting value. This > + function imply a full memory barrier before and after the atomic > + operation. > + > +void uatomic_and(type *addr, type mask) > +void uatomic_or(type *addr, type mask) > + > + Atomically write the result of bitwise "and"/"or" between the > + content of @addr and @mask into @addr. > + These operations do not necessarily imply memory barriers. > + If memory barriers are needed, they may be provided by > + explicitly using > + cmm_smp_mb__before_uatomic_and(), > + cmm_smp_mb__after_uatomic_and(), > + cmm_smp_mb__before_uatomic_or(), and > + cmm_smp_mb__after_uatomic_or(). These explicit barriers are > + np-ops on architectures in which the underlying atomic > + instructions implicitly supply the needed memory barriers. Good as well for these! Thanx, Paul > +void uatomic_add(type *addr, type v) > +void uatomic_sub(type *addr, type v) > + > + Atomically increment/decrement the content of @addr by @v. > + These operations do not necessarily imply memory barriers. > + If memory barriers are needed, they may be provided by > + explicitly using > + cmm_smp_mb__before_uatomic_add(), > + cmm_smp_mb__after_uatomic_add(), > + cmm_smp_mb__before_uatomic_sub(), and > + cmm_smp_mb__after_uatomic_sub(). These explicit barriers are > + np-ops on architectures in which the underlying atomic > + instructions implicitly supply the needed memory barriers. > + > +void uatomic_inc(type *addr) > +void uatomic_dec(type *addr) > + > + Atomically increment/decrement the content of @addr by 1. > + These operations do not necessarily imply memory barriers. > + If memory barriers are needed, they may be provided by > + explicitly using > + cmm_smp_mb__before_uatomic_inc(), > + cmm_smp_mb__after_uatomic_inc(), > + cmm_smp_mb__before_uatomic_dec(), and > + cmm_smp_mb__after_uatomic_dec(). These explicit barriers are > + np-ops on architectures in which the underlying atomic > + instructions implicitly supply the needed memory barriers. > > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > From paulmck at linux.vnet.ibm.com Wed May 16 13:27:35 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Wed, 16 May 2012 10:27:35 -0700 Subject: [lttng-dev] [RFC PATCH urcu] Implement urcu/tls-compat.h In-Reply-To: <20120516135658.GB29920@Krystal> References: <20120516135658.GB29920@Krystal> Message-ID: <20120516172735.GD2441@linux.vnet.ibm.com> On Wed, May 16, 2012 at 09:56:58AM -0400, Mathieu Desnoyers wrote: > Suggested-by: Marek Vavru?a > Signed-off-by: Mathieu Desnoyers Interesting! Jeffrey Yasskin of Google was suggesting use of pthread_get_specific() over __thread even where __thread was available. His justification is that pthread_get_specific() allows destructors. Not sure I agree with him in the case of userspace RCU due to performance issues, but thought I would pass his advice along. Thanx, Paul > --- > diff --git a/Makefile.am b/Makefile.am > index 0a369fd..6263057 100644 > --- a/Makefile.am > +++ b/Makefile.am > @@ -18,7 +18,8 @@ nobase_dist_include_HEADERS = urcu/compiler.h urcu/hlist.h urcu/list.h \ > urcu/ref.h urcu/cds.h urcu/urcu_ref.h urcu/urcu-futex.h \ > urcu/uatomic_arch.h urcu/rculfhash.h \ > $(top_srcdir)/urcu/map/*.h \ > - $(top_srcdir)/urcu/static/*.h > + $(top_srcdir)/urcu/static/*.h \ > + urcu/tls-compat.h > nobase_nodist_include_HEADERS = urcu/arch.h urcu/uatomic.h urcu/config.h > > EXTRA_DIST = $(top_srcdir)/urcu/arch/*.h $(top_srcdir)/urcu/uatomic/*.h \ > diff --git a/urcu/tls-compat.h b/urcu/tls-compat.h > new file mode 100644 > index 0000000..d7c7537 > --- /dev/null > +++ b/urcu/tls-compat.h > @@ -0,0 +1,99 @@ > +#ifndef _URCU_TLS_COMPAT_H > +#define _URCU_TLS_COMPAT_H > + > +/* > + * urcu/tls-compat.h > + * > + * Userspace RCU library - Thread-Local Storage Compatibility Header > + * > + * Copyright 2012 - Mathieu Desnoyers > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > +#include > +#include > +#include > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#ifdef CONFIG_RCU_TLS /* Based on ax_tls.m4 */ > + > +# define DECLARE_URCU_TLS(type, name) \ > + CONFIG_RCU_TLS type __tls_ ## name > + > +# define DEFINE_URCU_TLS(type, name) \ > + CONFIG_RCU_TLS type __tls_ ## name > + > +# define URCU_TLS(name) (__tls_ ## name) > + > +#else /* #ifndef CONFIG_RCU_TLS */ > + > +# include > + > +struct urcu_tls { > + pthread_key_t key; > + pthread_mutex_t init_mutex; > + int init_done; > +}; > + > +# define DECLARE_URCU_TLS(type, name) \ > + type *__tls_access_ ## name(void) > + > +/* > + * Note: we don't free memory at process exit, since it will be dealt > + * with by the OS. > + */ > +# define DEFINE_URCU_TLS(type, name) \ > + type *__tls_access_ ## name(void) \ > + { \ > + static struct urcu_tls __tls_ ## name = { \ > + .init_mutex = PTHREAD_MUTEX_INITIALIZER,\ > + .init_done = 0, \ > + }; \ > + void *__tls_p; \ > + if (!__tls_ ## name.init_done) { \ > + /* Mutex to protect concurrent init */ \ > + pthread_mutex_lock(&__tls_ ## name.init_mutex); \ > + if (!__tls_ ## name.init_done) { \ > + (void) pthread_key_create(&__tls_ ## name.key, \ > + free); \ > + cmm_smp_wmb(); /* create key before write init_done */ \ > + __tls_ ## name.init_done = 1; \ > + } \ > + pthread_mutex_unlock(&__tls_ ## name.init_mutex); \ > + } \ > + cmm_smp_rmb(); /* read init_done before getting key */ \ > + __tls_p = pthread_getspecific(__tls_ ## name.key); \ > + if (caa_unlikely(__tls_p == NULL)) { \ > + __tls_p = calloc(1, sizeof(type)); \ > + (void) pthread_setspecific(__tls_ ## name.key, \ > + __tls_p); \ > + } \ > + return __tls_p; \ > + } > + > +# define URCU_TLS(name) (*__tls_access_ ## name()) > + > +#endif /* #else #ifndef CONFIG_RCU_TLS */ > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* _URCU_TLS_COMPAT_H */ > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > From vannigenua at gmail.com Wed May 16 12:02:03 2012 From: vannigenua at gmail.com (Vanni Genua) Date: Wed, 16 May 2012 16:02:03 +0000 Subject: [lttng-dev] HOW TO DOWNLOAD LTTng 2.0 stable? Message-ID: what are the steps to download LTTng-ust stable 2.0? git clone from which URL? Thanks -------------- next part -------------- An HTML attachment was scrubbed... URL: From mathieu.desnoyers at efficios.com Wed May 16 14:06:48 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 16 May 2012 14:06:48 -0400 Subject: [lttng-dev] [RFC PATCH urcu] Implement urcu/tls-compat.h In-Reply-To: <20120516172735.GD2441@linux.vnet.ibm.com> References: <20120516135658.GB29920@Krystal> <20120516172735.GD2441@linux.vnet.ibm.com> Message-ID: <20120516180648.GA16045@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > On Wed, May 16, 2012 at 09:56:58AM -0400, Mathieu Desnoyers wrote: > > Suggested-by: Marek Vavru?a > > Signed-off-by: Mathieu Desnoyers > > Interesting! Jeffrey Yasskin of Google was suggesting use of > pthread_get_specific() over __thread even where __thread was available. > His justification is that pthread_get_specific() allows destructors. > Not sure I agree with him in the case of userspace RCU due to performance > issues, but thought I would pass his advice along. AFAIU, __thread information gets reclaimed when a thread exits, so I don't think there is any real-life difference in our case: usually the rcu_unregister will be called just before thread exit. So I agree with you that __thread should provide us better performance in the most frequent paths, so I'm in favor of leaving __thread whenever it's available. Thanks, Mathieu > > Thanx, Paul > > > --- > > diff --git a/Makefile.am b/Makefile.am > > index 0a369fd..6263057 100644 > > --- a/Makefile.am > > +++ b/Makefile.am > > @@ -18,7 +18,8 @@ nobase_dist_include_HEADERS = urcu/compiler.h urcu/hlist.h urcu/list.h \ > > urcu/ref.h urcu/cds.h urcu/urcu_ref.h urcu/urcu-futex.h \ > > urcu/uatomic_arch.h urcu/rculfhash.h \ > > $(top_srcdir)/urcu/map/*.h \ > > - $(top_srcdir)/urcu/static/*.h > > + $(top_srcdir)/urcu/static/*.h \ > > + urcu/tls-compat.h > > nobase_nodist_include_HEADERS = urcu/arch.h urcu/uatomic.h urcu/config.h > > > > EXTRA_DIST = $(top_srcdir)/urcu/arch/*.h $(top_srcdir)/urcu/uatomic/*.h \ > > diff --git a/urcu/tls-compat.h b/urcu/tls-compat.h > > new file mode 100644 > > index 0000000..d7c7537 > > --- /dev/null > > +++ b/urcu/tls-compat.h > > @@ -0,0 +1,99 @@ > > +#ifndef _URCU_TLS_COMPAT_H > > +#define _URCU_TLS_COMPAT_H > > + > > +/* > > + * urcu/tls-compat.h > > + * > > + * Userspace RCU library - Thread-Local Storage Compatibility Header > > + * > > + * Copyright 2012 - Mathieu Desnoyers > > + * > > + * This library is free software; you can redistribute it and/or > > + * modify it under the terms of the GNU Lesser General Public > > + * License as published by the Free Software Foundation; either > > + * version 2.1 of the License, or (at your option) any later version. > > + * > > + * This library is distributed in the hope that it will be useful, > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > > + * Lesser General Public License for more details. > > + * > > + * You should have received a copy of the GNU Lesser General Public > > + * License along with this library; if not, write to the Free Software > > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > + > > +#ifdef __cplusplus > > +extern "C" { > > +#endif > > + > > +#ifdef CONFIG_RCU_TLS /* Based on ax_tls.m4 */ > > + > > +# define DECLARE_URCU_TLS(type, name) \ > > + CONFIG_RCU_TLS type __tls_ ## name > > + > > +# define DEFINE_URCU_TLS(type, name) \ > > + CONFIG_RCU_TLS type __tls_ ## name > > + > > +# define URCU_TLS(name) (__tls_ ## name) > > + > > +#else /* #ifndef CONFIG_RCU_TLS */ > > + > > +# include > > + > > +struct urcu_tls { > > + pthread_key_t key; > > + pthread_mutex_t init_mutex; > > + int init_done; > > +}; > > + > > +# define DECLARE_URCU_TLS(type, name) \ > > + type *__tls_access_ ## name(void) > > + > > +/* > > + * Note: we don't free memory at process exit, since it will be dealt > > + * with by the OS. > > + */ > > +# define DEFINE_URCU_TLS(type, name) \ > > + type *__tls_access_ ## name(void) \ > > + { \ > > + static struct urcu_tls __tls_ ## name = { \ > > + .init_mutex = PTHREAD_MUTEX_INITIALIZER,\ > > + .init_done = 0, \ > > + }; \ > > + void *__tls_p; \ > > + if (!__tls_ ## name.init_done) { \ > > + /* Mutex to protect concurrent init */ \ > > + pthread_mutex_lock(&__tls_ ## name.init_mutex); \ > > + if (!__tls_ ## name.init_done) { \ > > + (void) pthread_key_create(&__tls_ ## name.key, \ > > + free); \ > > + cmm_smp_wmb(); /* create key before write init_done */ \ > > + __tls_ ## name.init_done = 1; \ > > + } \ > > + pthread_mutex_unlock(&__tls_ ## name.init_mutex); \ > > + } \ > > + cmm_smp_rmb(); /* read init_done before getting key */ \ > > + __tls_p = pthread_getspecific(__tls_ ## name.key); \ > > + if (caa_unlikely(__tls_p == NULL)) { \ > > + __tls_p = calloc(1, sizeof(type)); \ > > + (void) pthread_setspecific(__tls_ ## name.key, \ > > + __tls_p); \ > > + } \ > > + return __tls_p; \ > > + } > > + > > +# define URCU_TLS(name) (*__tls_access_ ## name()) > > + > > +#endif /* #else #ifndef CONFIG_RCU_TLS */ > > + > > +#ifdef __cplusplus > > +} > > +#endif > > + > > +#endif /* _URCU_TLS_COMPAT_H */ > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From alexandre.montplaisir at polymtl.ca Wed May 16 14:11:12 2012 From: alexandre.montplaisir at polymtl.ca (Alexandre Montplaisir) Date: Wed, 16 May 2012 14:11:12 -0400 Subject: [lttng-dev] HOW TO DOWNLOAD LTTng 2.0 stable? In-Reply-To: References: Message-ID: <4FB3EDC0.7080006@polymtl.ca> On 12-05-16 12:02 PM, Vanni Genua wrote: > what are the steps to download LTTng-ust stable 2.0? > git clone from which URL? > Thanks > The links on the download page: http://lttng.org/download all link to the latest stable versions. At the bottom there are also links to the git trees. In the lttng-ust tree, there is a branch "stable-2.0" if you want to pull from the latest stable branch. Cheers, -- Alexandre Montplaisir DORSAL lab, ?cole Polytechnique de Montr?al From mathieu.desnoyers at efficios.com Wed May 16 14:17:42 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 16 May 2012 14:17:42 -0400 Subject: [lttng-dev] [RFC PATCH urcu] Document uatomic operations In-Reply-To: <20120516171803.GB2441@linux.vnet.ibm.com> References: <20120515023901.GA22786@Krystal> <20120515040936.GB2412@linux.vnet.ibm.com> <20120515121003.GA31468@Krystal> <20120516171803.GB2441@linux.vnet.ibm.com> Message-ID: <20120516181742.GB16045@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > On Tue, May 15, 2012 at 08:10:03AM -0400, Mathieu Desnoyers wrote: > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > On Mon, May 14, 2012 at 10:39:01PM -0400, Mathieu Desnoyers wrote: > > > > Document each atomic operation provided by urcu/uatomic.h, along with > > > > their memory barrier guarantees. > > > > > > Great to see the documentation!!! Some comments below. > > > > > > Thanx, Paul > > > > > > > Signed-off-by: Mathieu Desnoyers > > > > --- > > > > diff --git a/doc/Makefile.am b/doc/Makefile.am > > > > index bec1d7c..db9811c 100644 > > > > --- a/doc/Makefile.am > > > > +++ b/doc/Makefile.am > > > > @@ -1 +1 @@ > > > > -dist_doc_DATA = rcu-api.txt > > > > +dist_doc_DATA = rcu-api.txt uatomic-api.txt > > > > diff --git a/doc/uatomic-api.txt b/doc/uatomic-api.txt > > > > new file mode 100644 > > > > index 0000000..3605acf > > > > --- /dev/null > > > > +++ b/doc/uatomic-api.txt > > > > @@ -0,0 +1,80 @@ > > > > +Userspace RCU Atomic Operations API > > > > +by Mathieu Desnoyers and Paul E. McKenney > > > > + > > > > + > > > > +This document describes the API. Those are the atomic > > > > +operations provided by the Userspace RCU library. The general rule > > > > +regarding memory barriers is that only uatomic_xchg(), > > > > +uatomic_cmpxchg(), uatomic_add_return(), and uatomic_sub_return() imply > > > > +full memory barriers before and after the atomic operation. Other > > > > +primitives don't guarantee any memory barrier. > > > > + > > > > +Only atomic operations performed on integers ("int" and "long", signed > > > > +and unsigned) are supported on all architectures. Some architectures > > > > +also support 1-byte and 2-byte atomic operations. Those respectively > > > > +have UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT defined when > > > > +uatomic.h is included. An architecture trying to perform an atomic write > > > > +to a type size not supported by the architecture will trigger an illegal > > > > +instruction. > > > > + > > > > +In the description below, "type" is a type that can be atomically > > > > +written to by the architecture. It needs to be at most word-sized, and > > > > +its alignment needs to greater or equal to its size. > > > > + > > > > +type uatomic_set(type *addr, type v) > > > > + > > > > + Atomically write @v into @addr. > > > > > > Wouldn't this instead be "void uatomic_set(type *addr, type v)"? > > > > Well, in that case, we'd need to change the macro. Currently, > > _uatomic_set maps directly to: > > > > #define _uatomic_set(addr, v) CMM_STORE_SHARED(*(addr), (v)) > > > > and CMM_STORE_SHARED returns v. The question becomes: should we change > > _uatomic_set or CMM_STORE_SHARED so they don't return anything, or > > document that they return something ? > > > > One thing I noticed is that linters often complain that the return value > > of CMM_STORE_SHARED is never used. One thing we could look into is to > > try some gcc attributes and/or linter annotations to flag this return > > value as possibly unused. Thoughts ? > > Hmmm... > > Does the following work? > > #define _uatomic_set(addr, v) ((void)CMM_STORE_SHARED(*(addr), (v))) Well, it would work, yes, but then we would not be consistent between return values or no return values of: uatomic_set() rcu_assign_pointer() rcu_set_pointer() if you notice, in the Linux kernel, rcu_assign_pointer returns the new pointer value. But you are right that atomic_set() does not return anything. So which consistency would be best to keep ? Thanks, Mathieu > > > > By "Atomically write @v into @addr", what is meant is that no concurrent > > > operation that reads from addr will see partial effects of uatomic_set(), > > > correct? In other words, the concurrent read will either see v or > > > the old value, not a mush of the two. > > > > yep. I added that clarification. > > > > > > > > > + > > > > +type uatomic_read(type *addr) > > > > + > > > > + Atomically read @v from @addr. > > > > > > Similar comments on the meaning of "atomically". This may sound picky, > > > but people coming from an x86 environment might otherwise assume that > > > there is lock prefix involved... > > > > same. > > > > > > > > > + > > > > +type uatomic_cmpxchg(type *addr, type old, type new) > > > > + > > > > + Atomically check if @addr contains @old. If true, then replace > > > > + the content of @addr by @new. Return the value previously > > > > + contained by @addr. This function imply a full memory barrier > > > > + before and after the atomic operation. > > > > > > Suggest "then atomically replace" or some such. It might not hurt > > > to add that this is an atomic read-modify-write operation. > > > > Updated to: > > > > type uatomic_cmpxchg(type *addr, type old, type new) > > > > An atomic read-modify-write operation that performs this > > sequence of operations atomically: check if @addr contains @old. > > If true, then replace the content of @addr by @new. Return the > > value previously contained by @addr. This function imply a full > > memory barrier before and after the atomic operation. > > > > > > > > Similar comments on the other value-returning atomics. > > > > Will do something similar. > > > > > > > > > + > > > > +type uatomic_xchg(type *addr, type new) > > > > + > > > > + Atomically replace the content of @addr by @new, and return the > > > > + value previously contained by @addr. This function imply a full > > > > + memory barrier before and after the atomic operation. > > > > + > > > > +type uatomic_add_return(type *addr, type v) > > > > +type uatomic_sub_return(type *addr, type v) > > > > + > > > > + Atomically increment/decrement the content of @addr by @v, and > > > > + return the resulting value. This function imply a full memory > > > > + barrier before and after the atomic operation. > > > > + > > > > +void uatomic_and(type *addr, type mask) > > > > +void uatomic_or(type *addr, type mask) > > > > + > > > > + Atomically write the result of bitwise "and"/"or" between the > > > > + content of @addr and @mask into @addr. Memory barriers are > > > > + provided by explicitly using cmm_smp_mb__before_uatomic_and(), > > > > + cmm_smp_mb__after_uatomic_and(), > > > > + cmm_smp_mb__before_uatomic_or(), and > > > > + cmm_smp_mb__after_uatomic_or(). > > > > > > I suggest replacing "Memory barriers are provided ..." with something like > > > "These operations do not necessarily imply memory barriers. If memory > > > barriers are needed, they may be provided ...". Then perhaps add a > > > sentence stating that the advantage of using the four __before_/__after_ > > > primitives is that they are no-ops on architectures in which the underlying > > > atomic instructions implicitly supply the needed memory barriers. > > > > > > Simlar comments on the other non-value-returning atomic operations below. > > > > OK, done. > > > > Here is the update: > > > > > > diff --git a/doc/Makefile.am b/doc/Makefile.am > > index 27d3793..3422653 100644 > > --- a/doc/Makefile.am > > +++ b/doc/Makefile.am > > @@ -1 +1 @@ > > -dist_doc_DATA = rcu-api.txt cds-api.txt > > +dist_doc_DATA = rcu-api.txt cds-api.txt uatomic-api.txt > > diff --git a/doc/uatomic-api.txt b/doc/uatomic-api.txt > > new file mode 100644 > > index 0000000..3ad8fbb > > --- /dev/null > > +++ b/doc/uatomic-api.txt > > @@ -0,0 +1,102 @@ > > +Userspace RCU Atomic Operations API > > +by Mathieu Desnoyers and Paul E. McKenney > > + > > + > > +This document describes the API. Those are the atomic > > +operations provided by the Userspace RCU library. The general rule > > +regarding memory barriers is that only uatomic_xchg(), > > +uatomic_cmpxchg(), uatomic_add_return(), and uatomic_sub_return() imply > > +full memory barriers before and after the atomic operation. Other > > +primitives don't guarantee any memory barrier. > > + > > +Only atomic operations performed on integers ("int" and "long", signed > > +and unsigned) are supported on all architectures. Some architectures > > +also support 1-byte and 2-byte atomic operations. Those respectively > > +have UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT defined when > > +uatomic.h is included. An architecture trying to perform an atomic write > > +to a type size not supported by the architecture will trigger an illegal > > +instruction. > > + > > +In the description below, "type" is a type that can be atomically > > +written to by the architecture. It needs to be at most word-sized, and > > +its alignment needs to greater or equal to its size. > > + > > +type uatomic_set(type *addr, type v) > > + > > + Atomically write @v into @addr. By "atomically", we mean that no > > + concurrent operation that reads from addr will see partial > > + effects of uatomic_set(). > > Good clarification! > > If this is to return the value written, it should say so. (I would prefer > no return, as this is the most common usage and the value written is easily > available anyway.) > > > +type uatomic_read(type *addr) > > + > > + Atomically read @v from @addr. By "atomically", we mean that > > + uatomic_read() cannot see a partial effect of any concurrent > > + uatomic update. > > + > > +type uatomic_cmpxchg(type *addr, type old, type new) > > + > > + An atomic read-modify-write operation that performs this > > + sequence of operations atomically: check if @addr contains @old. > > + If true, then replace the content of @addr by @new. Return the > > + value previously contained by @addr. This function imply a full > > + memory barrier before and after the atomic operation. > > Good clarification! (And below as well.) > > > +type uatomic_xchg(type *addr, type new) > > + > > + An atomic read-modify-write operation that performs this sequence > > + of operations atomically: replace the content of @addr by @new, > > + and return the value previously contained by @addr. This > > + function imply a full memory barrier before and after the atomic > > + operation. > > + > > +type uatomic_add_return(type *addr, type v) > > +type uatomic_sub_return(type *addr, type v) > > + > > + An atomic read-modify-write operation that performs this > > + sequence of operations atomically: increment/decrement the > > + content of @addr by @v, and return the resulting value. This > > + function imply a full memory barrier before and after the atomic > > + operation. > > + > > +void uatomic_and(type *addr, type mask) > > +void uatomic_or(type *addr, type mask) > > + > > + Atomically write the result of bitwise "and"/"or" between the > > + content of @addr and @mask into @addr. > > + These operations do not necessarily imply memory barriers. > > + If memory barriers are needed, they may be provided by > > + explicitly using > > + cmm_smp_mb__before_uatomic_and(), > > + cmm_smp_mb__after_uatomic_and(), > > + cmm_smp_mb__before_uatomic_or(), and > > + cmm_smp_mb__after_uatomic_or(). These explicit barriers are > > + np-ops on architectures in which the underlying atomic > > + instructions implicitly supply the needed memory barriers. > > Good as well for these! > > Thanx, Paul > > > +void uatomic_add(type *addr, type v) > > +void uatomic_sub(type *addr, type v) > > + > > + Atomically increment/decrement the content of @addr by @v. > > + These operations do not necessarily imply memory barriers. > > + If memory barriers are needed, they may be provided by > > + explicitly using > > + cmm_smp_mb__before_uatomic_add(), > > + cmm_smp_mb__after_uatomic_add(), > > + cmm_smp_mb__before_uatomic_sub(), and > > + cmm_smp_mb__after_uatomic_sub(). These explicit barriers are > > + np-ops on architectures in which the underlying atomic > > + instructions implicitly supply the needed memory barriers. > > + > > +void uatomic_inc(type *addr) > > +void uatomic_dec(type *addr) > > + > > + Atomically increment/decrement the content of @addr by 1. > > + These operations do not necessarily imply memory barriers. > > + If memory barriers are needed, they may be provided by > > + explicitly using > > + cmm_smp_mb__before_uatomic_inc(), > > + cmm_smp_mb__after_uatomic_inc(), > > + cmm_smp_mb__before_uatomic_dec(), and > > + cmm_smp_mb__after_uatomic_dec(). These explicit barriers are > > + np-ops on architectures in which the underlying atomic > > + instructions implicitly supply the needed memory barriers. > > > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed May 16 14:29:50 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 16 May 2012 14:29:50 -0400 Subject: [lttng-dev] [RFC PATCH urcu] Use urcu/tls-compat.h In-Reply-To: References: <20120516135802.GC29920@Krystal> Message-ID: <20120516182950.GA16854@Krystal> * Marek Vavru?a (marek.vavrusa at nic.cz) wrote: > Matthieu, > > thanks a lot for sorting the issues with the patch. Things have been > very busy for last couple weeks. > Anyway there's another problem with NetBSD 5, as it has implemented > mremap() call. Unfortunately > the syntax is different from Linux one. I have made a patch that just > prevents name clash, but that's not 100% correct. liburcu should > probably detect mremap version on configure and then use the correct > implementation via wrapper. I did a few minor modifications to your patch. It's pushed as: commit c7eaf61c307ee909eb2dcebb956e73776f1a0441 Author: Mathieu Desnoyers Date: Wed May 16 14:30:09 2012 -0400 Fix mremap wrapper for NetBSD 5 NetBSD 5 implements a mremap with a different semantic. Rename our wrapper symbol name so it does not clash with the NetBSD 5 symbol. Eventually, we could envision doing a special-case that uses the NetBSD 5 version instead of the fallback, but let's first get it working before going into optimization land. Suggested-by: Marek Vavru?a Signed-off-by: Mathieu Desnoyers Thanks! Mathieu > > Kind regards, > Marek > > On 16 May 2012 15:58, Mathieu Desnoyers wrote: > > Provides compatibility for OpenBSD, NetBSD and Darwin. > > > > Suggested-by: Marek Vavru?a > > Signed-off-by: Mathieu Desnoyers > > --- > > diff --git a/tests/test_mutex.c b/tests/test_mutex.c > > index 3f84bbf..ba184a4 100644 > > --- a/tests/test_mutex.c > > +++ b/tests/test_mutex.c > > @@ -35,6 +35,7 @@ > > ?#include > > > > ?#include > > +#include > > > > ?#ifdef __linux__ > > ?#include > > @@ -155,8 +156,8 @@ static int test_duration_read(void) > > ? ? ? ?return !test_stop; > > ?} > > > > -static unsigned long long __thread nr_writes; > > -static unsigned long long __thread nr_reads; > > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > > > ?static > > ?unsigned long long __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *tot_nr_writes; > > @@ -208,12 +209,12 @@ void *thr_reader(void *data) > > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > > ? ? ? ? ? ? ? ?pthread_mutex_unlock(&lock); > > - ? ? ? ? ? ? ? nr_reads++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ?} > > > > - ? ? ? tot_nr_reads[tidx] = nr_reads; > > + ? ? ? tot_nr_reads[tidx] = URCU_TLS(nr_reads); > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > > ? ? ? ?return ((void*)1); > > @@ -241,7 +242,7 @@ void *thr_writer(void *data) > > ? ? ? ? ? ? ? ?if (caa_unlikely(wduration)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wduration); > > ? ? ? ? ? ? ? ?pthread_mutex_unlock(&lock); > > - ? ? ? ? ? ? ? nr_writes++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > > @@ -250,7 +251,7 @@ void *thr_writer(void *data) > > > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > > - ? ? ? tot_nr_writes[wtidx] = nr_writes; > > + ? ? ? tot_nr_writes[wtidx] = URCU_TLS(nr_writes); > > ? ? ? ?return ((void*)2); > > ?} > > > > diff --git a/tests/test_perthreadlock.c b/tests/test_perthreadlock.c > > index fa9c89a..6ff0412 100644 > > --- a/tests/test_perthreadlock.c > > +++ b/tests/test_perthreadlock.c > > @@ -35,6 +35,7 @@ > > ?#include > > > > ?#include > > +#include > > > > ?#ifdef __linux__ > > ?#include > > @@ -159,8 +160,8 @@ static int test_duration_read(void) > > ? ? ? ?return !test_stop; > > ?} > > > > -static unsigned long long __thread nr_writes; > > -static unsigned long long __thread nr_reads; > > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > > > ?static > > ?unsigned long long __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *tot_nr_writes; > > @@ -212,12 +213,12 @@ void *thr_reader(void *data) > > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > > ? ? ? ? ? ? ? ?pthread_mutex_unlock(&per_thread_lock[tidx].lock); > > - ? ? ? ? ? ? ? nr_reads++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ?} > > > > - ? ? ? tot_nr_reads[tidx] = nr_reads; > > + ? ? ? tot_nr_reads[tidx] = URCU_TLS(nr_reads); > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > > ? ? ? ?return ((void*)1); > > @@ -250,7 +251,7 @@ void *thr_writer(void *data) > > ? ? ? ? ? ? ? ?for (tidx = (long)nr_readers - 1; tidx >= 0; tidx--) { > > ? ? ? ? ? ? ? ? ? ? ? ?pthread_mutex_unlock(&per_thread_lock[tidx].lock); > > ? ? ? ? ? ? ? ?} > > - ? ? ? ? ? ? ? nr_writes++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > > @@ -259,7 +260,7 @@ void *thr_writer(void *data) > > > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > > - ? ? ? tot_nr_writes[wtidx] = nr_writes; > > + ? ? ? tot_nr_writes[wtidx] = URCU_TLS(nr_writes); > > ? ? ? ?return ((void*)2); > > ?} > > > > diff --git a/tests/test_rwlock.c b/tests/test_rwlock.c > > index 34d8c07..ccbc9d1 100644 > > --- a/tests/test_rwlock.c > > +++ b/tests/test_rwlock.c > > @@ -35,6 +35,7 @@ > > ?#include > > > > ?#include > > +#include > > > > ?#ifdef __linux__ > > ?#include > > @@ -156,8 +157,8 @@ static int test_duration_read(void) > > ? ? ? ?return !test_stop; > > ?} > > > > -static unsigned long long __thread nr_writes; > > -static unsigned long long __thread nr_reads; > > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > > > ?static unsigned int nr_readers; > > ?static unsigned int nr_writers; > > @@ -204,12 +205,12 @@ void *thr_reader(void *_count) > > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > > ? ? ? ? ? ? ? ?pthread_rwlock_unlock(&lock); > > - ? ? ? ? ? ? ? nr_reads++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ?} > > > > - ? ? ? *count = nr_reads; > > + ? ? ? *count = URCU_TLS(nr_reads); > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > > ? ? ? ?return ((void*)1); > > @@ -237,7 +238,7 @@ void *thr_writer(void *_count) > > ? ? ? ? ? ? ? ?if (caa_unlikely(wduration)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wduration); > > ? ? ? ? ? ? ? ?pthread_rwlock_unlock(&lock); > > - ? ? ? ? ? ? ? nr_writes++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > > @@ -246,7 +247,7 @@ void *thr_writer(void *_count) > > > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > > - ? ? ? *count = nr_writes; > > + ? ? ? *count = URCU_TLS(nr_writes); > > ? ? ? ?return ((void*)2); > > ?} > > > > diff --git a/tests/test_urcu.c b/tests/test_urcu.c > > index 870f133..1b1b94b 100644 > > --- a/tests/test_urcu.c > > +++ b/tests/test_urcu.c > > @@ -35,6 +35,7 @@ > > ?#include > > > > ?#include > > +#include > > > > ?#ifdef __linux__ > > ?#include > > @@ -154,8 +155,8 @@ static int test_duration_read(void) > > ? ? ? ?return !test_stop; > > ?} > > > > -static unsigned long long __thread nr_writes; > > -static unsigned long long __thread nr_reads; > > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > > > ?static unsigned int nr_readers; > > ?static unsigned int nr_writers; > > @@ -242,7 +243,7 @@ void *thr_reader(void *_count) > > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > > ? ? ? ? ? ? ? ?rcu_read_unlock(); > > - ? ? ? ? ? ? ? nr_reads++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ?} > > @@ -253,7 +254,7 @@ void *thr_reader(void *_count) > > ? ? ? ?rcu_register_thread(); > > ? ? ? ?rcu_unregister_thread(); > > > > - ? ? ? *count = nr_reads; > > + ? ? ? *count = URCU_TLS(nr_reads); > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > > ? ? ? ?return ((void*)1); > > @@ -287,7 +288,7 @@ void *thr_writer(void *_count) > > ? ? ? ? ? ? ? ? ? ? ? ?old->a = 0; > > ? ? ? ? ? ? ? ?test_array_free(old); > > ? ? ? ? ? ? ? ?rcu_copy_mutex_unlock(); > > - ? ? ? ? ? ? ? nr_writes++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > > @@ -296,7 +297,7 @@ void *thr_writer(void *_count) > > > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > > - ? ? ? *count = nr_writes; > > + ? ? ? *count = URCU_TLS(nr_writes); > > ? ? ? ?return ((void*)2); > > ?} > > > > diff --git a/tests/test_urcu_assign.c b/tests/test_urcu_assign.c > > index 42d70c2..31e22e5 100644 > > --- a/tests/test_urcu_assign.c > > +++ b/tests/test_urcu_assign.c > > @@ -35,6 +35,7 @@ > > ?#include > > > > ?#include > > +#include > > > > ?#ifdef __linux__ > > ?#include > > @@ -154,8 +155,8 @@ static int test_duration_read(void) > > ? ? ? ?return !test_stop; > > ?} > > > > -static unsigned long long __thread nr_writes; > > -static unsigned long long __thread nr_reads; > > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > > > ?static unsigned int nr_readers; > > ?static unsigned int nr_writers; > > @@ -242,14 +243,14 @@ void *thr_reader(void *_count) > > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > > ? ? ? ? ? ? ? ?rcu_read_unlock(); > > - ? ? ? ? ? ? ? nr_reads++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ?} > > > > ? ? ? ?rcu_unregister_thread(); > > > > - ? ? ? *count = nr_reads; > > + ? ? ? *count = URCU_TLS(nr_reads); > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > > ? ? ? ?return ((void*)1); > > @@ -284,7 +285,7 @@ void *thr_writer(void *_count) > > ? ? ? ? ? ? ? ? ? ? ? ?old->a = 0; > > ? ? ? ? ? ? ? ?test_array_free(old); > > ? ? ? ? ? ? ? ?rcu_copy_mutex_unlock(); > > - ? ? ? ? ? ? ? nr_writes++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > > @@ -293,7 +294,7 @@ void *thr_writer(void *_count) > > > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > > - ? ? ? *count = nr_writes; > > + ? ? ? *count = URCU_TLS(nr_writes); > > ? ? ? ?return ((void*)2); > > ?} > > > > diff --git a/tests/test_urcu_bp.c b/tests/test_urcu_bp.c > > index 857913f..41caeb0 100644 > > --- a/tests/test_urcu_bp.c > > +++ b/tests/test_urcu_bp.c > > @@ -35,6 +35,7 @@ > > ?#include > > > > ?#include > > +#include > > > > ?#ifdef __linux__ > > ?#include > > @@ -154,8 +155,8 @@ static int test_duration_read(void) > > ? ? ? ?return !test_stop; > > ?} > > > > -static unsigned long long __thread nr_writes; > > -static unsigned long long __thread nr_reads; > > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > > > ?static unsigned int nr_readers; > > ?static unsigned int nr_writers; > > @@ -242,14 +243,14 @@ void *thr_reader(void *_count) > > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > > ? ? ? ? ? ? ? ?rcu_read_unlock(); > > - ? ? ? ? ? ? ? nr_reads++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ?} > > > > ? ? ? ?rcu_unregister_thread(); > > > > - ? ? ? *count = nr_reads; > > + ? ? ? *count = URCU_TLS(nr_reads); > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > > ? ? ? ?return ((void*)1); > > @@ -283,7 +284,7 @@ void *thr_writer(void *_count) > > ? ? ? ? ? ? ? ? ? ? ? ?old->a = 0; > > ? ? ? ? ? ? ? ?test_array_free(old); > > ? ? ? ? ? ? ? ?rcu_copy_mutex_unlock(); > > - ? ? ? ? ? ? ? nr_writes++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > > @@ -292,7 +293,7 @@ void *thr_writer(void *_count) > > > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > > - ? ? ? *count = nr_writes; > > + ? ? ? *count = URCU_TLS(nr_writes); > > ? ? ? ?return ((void*)2); > > ?} > > > > diff --git a/tests/test_urcu_defer.c b/tests/test_urcu_defer.c > > index 1575e9c..cd9780b 100644 > > --- a/tests/test_urcu_defer.c > > +++ b/tests/test_urcu_defer.c > > @@ -35,6 +35,7 @@ > > ?#include > > > > ?#include > > +#include > > > > ?#ifdef __linux__ > > ?#include > > @@ -155,8 +156,8 @@ static int test_duration_read(void) > > ? ? ? ?return !test_stop; > > ?} > > > > -static unsigned long long __thread nr_writes; > > -static unsigned long long __thread nr_reads; > > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > > > ?static > > ?unsigned long long __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *tot_nr_writes; > > @@ -213,14 +214,14 @@ void *thr_reader(void *_count) > > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > > ? ? ? ? ? ? ? ?rcu_read_unlock(); > > - ? ? ? ? ? ? ? nr_reads++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ?} > > > > ? ? ? ?rcu_unregister_thread(); > > > > - ? ? ? *count = nr_reads; > > + ? ? ? *count = URCU_TLS(nr_reads); > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > > ? ? ? ?return ((void*)1); > > @@ -271,7 +272,7 @@ void *thr_writer(void *data) > > ? ? ? ? ? ? ? ?defer_rcu(test_cb2, (void *)-2L); > > ? ? ? ? ? ? ? ?defer_rcu(test_cb2, (void *)-4L); > > ? ? ? ? ? ? ? ?defer_rcu(test_cb2, (void *)-2L); > > - ? ? ? ? ? ? ? nr_writes++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > > @@ -282,7 +283,7 @@ void *thr_writer(void *data) > > > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > > - ? ? ? tot_nr_writes[wtidx] = nr_writes; > > + ? ? ? tot_nr_writes[wtidx] = URCU_TLS(nr_writes); > > ? ? ? ?return ((void*)2); > > ?} > > > > diff --git a/tests/test_urcu_gc.c b/tests/test_urcu_gc.c > > index 21c5d56..3a42506 100644 > > --- a/tests/test_urcu_gc.c > > +++ b/tests/test_urcu_gc.c > > @@ -35,6 +35,7 @@ > > ?#include > > > > ?#include > > +#include > > > > ?#ifdef __linux__ > > ?#include > > @@ -163,8 +164,8 @@ static int test_duration_read(void) > > ? ? ? ?return !test_stop; > > ?} > > > > -static unsigned long long __thread nr_writes; > > -static unsigned long long __thread nr_reads; > > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > > > ?static > > ?unsigned long long __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *tot_nr_writes; > > @@ -221,14 +222,14 @@ void *thr_reader(void *_count) > > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > > ? ? ? ? ? ? ? ?rcu_read_unlock(); > > - ? ? ? ? ? ? ? nr_reads++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ?} > > > > ? ? ? ?rcu_unregister_thread(); > > > > - ? ? ? *count = nr_reads; > > + ? ? ? *count = URCU_TLS(nr_reads); > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > > ? ? ? ?return ((void*)1); > > @@ -294,7 +295,7 @@ void *thr_writer(void *data) > > ? ? ? ? ? ? ? ?if (caa_unlikely(wduration)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wduration); > > ? ? ? ? ? ? ? ?rcu_gc_reclaim(wtidx, old); > > - ? ? ? ? ? ? ? nr_writes++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > > @@ -303,7 +304,7 @@ void *thr_writer(void *data) > > > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > > - ? ? ? tot_nr_writes[wtidx] = nr_writes; > > + ? ? ? tot_nr_writes[wtidx] = URCU_TLS(nr_writes); > > ? ? ? ?return ((void*)2); > > ?} > > > > diff --git a/tests/test_urcu_hash.c b/tests/test_urcu_hash.c > > index 2223413..5710de0 100644 > > --- a/tests/test_urcu_hash.c > > +++ b/tests/test_urcu_hash.c > > @@ -82,13 +82,13 @@ int (*get_populate_hash_cb(void))(void) > > ? ? ? ?return test_hash_cb[test_choice].populate_hash; > > ?} > > > > -unsigned int __thread rand_lookup; > > -unsigned long __thread nr_add; > > -unsigned long __thread nr_addexist; > > -unsigned long __thread nr_del; > > -unsigned long __thread nr_delnoent; > > -unsigned long __thread lookup_fail; > > -unsigned long __thread lookup_ok; > > +DEFINE_URCU_TLS(unsigned int, rand_lookup); > > +DEFINE_URCU_TLS(unsigned long, nr_add); > > +DEFINE_URCU_TLS(unsigned long, nr_addexist); > > +DEFINE_URCU_TLS(unsigned long, nr_del); > > +DEFINE_URCU_TLS(unsigned long, nr_delnoent); > > +DEFINE_URCU_TLS(unsigned long, lookup_fail); > > +DEFINE_URCU_TLS(unsigned long, lookup_ok); > > > > ?struct cds_lfht *test_ht; > > > > @@ -126,8 +126,8 @@ int use_affinity = 0; > > > > ?pthread_mutex_t affinity_mutex = PTHREAD_MUTEX_INITIALIZER; > > > > -unsigned long long __thread nr_writes; > > -unsigned long long __thread nr_reads; > > +DEFINE_URCU_TLS(unsigned long long, nr_writes); > > +DEFINE_URCU_TLS(unsigned long long, nr_reads); > > > > ?unsigned int nr_readers; > > ?unsigned int nr_writers; > > diff --git a/tests/test_urcu_hash.h b/tests/test_urcu_hash.h > > index 083e71c..fe13c36 100644 > > --- a/tests/test_urcu_hash.h > > +++ b/tests/test_urcu_hash.h > > @@ -37,6 +37,8 @@ > > ?#include > > ?#include > > > > +#include > > + > > ?#ifdef __linux__ > > ?#include > > ?#endif > > @@ -102,13 +104,13 @@ struct wr_count { > > ? ? ? ?unsigned long remove; > > ?}; > > > > -extern unsigned int __thread rand_lookup; > > -extern unsigned long __thread nr_add; > > -extern unsigned long __thread nr_addexist; > > -extern unsigned long __thread nr_del; > > -extern unsigned long __thread nr_delnoent; > > -extern unsigned long __thread lookup_fail; > > -extern unsigned long __thread lookup_ok; > > +extern DECLARE_URCU_TLS(unsigned int, rand_lookup); > > +extern DECLARE_URCU_TLS(unsigned long, nr_add); > > +extern DECLARE_URCU_TLS(unsigned long, nr_addexist); > > +extern DECLARE_URCU_TLS(unsigned long, nr_del); > > +extern DECLARE_URCU_TLS(unsigned long, nr_delnoent); > > +extern DECLARE_URCU_TLS(unsigned long, lookup_fail); > > +extern DECLARE_URCU_TLS(unsigned long, lookup_ok); > > > > ?extern struct cds_lfht *test_ht; > > > > @@ -214,8 +216,8 @@ static inline int test_duration_read(void) > > ? ? ? ?return !test_stop; > > ?} > > > > -extern unsigned long long __thread nr_writes; > > -extern unsigned long long __thread nr_reads; > > +extern DECLARE_URCU_TLS(unsigned long long, nr_writes); > > +extern DECLARE_URCU_TLS(unsigned long long, nr_reads); > > > > ?extern unsigned int nr_readers; > > ?extern unsigned int nr_writers; > > diff --git a/tests/test_urcu_hash_rw.c b/tests/test_urcu_hash_rw.c > > index 7310344..a789236 100644 > > --- a/tests/test_urcu_hash_rw.c > > +++ b/tests/test_urcu_hash_rw.c > > @@ -80,7 +80,7 @@ void *test_hash_rw_thr_reader(void *_count) > > ? ? ? ?for (;;) { > > ? ? ? ? ? ? ? ?rcu_read_lock(); > > ? ? ? ? ? ? ? ?cds_lfht_test_lookup(test_ht, > > - ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&rand_lookup) % lookup_pool_size) + lookup_pool_offset), > > + ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % lookup_pool_size) + lookup_pool_offset), > > ? ? ? ? ? ? ? ? ? ? ? ?sizeof(void *), &iter); > > ? ? ? ? ? ? ? ?node = cds_lfht_iter_get_test_node(&iter); > > ? ? ? ? ? ? ? ?if (node == NULL) { > > @@ -88,28 +88,29 @@ void *test_hash_rw_thr_reader(void *_count) > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?printf("[ERROR] Lookup cannot find initial node.\n"); > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?exit(-1); > > ? ? ? ? ? ? ? ? ? ? ? ?} > > - ? ? ? ? ? ? ? ? ? ? ? lookup_fail++; > > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(lookup_fail)++; > > ? ? ? ? ? ? ? ?} else { > > - ? ? ? ? ? ? ? ? ? ? ? lookup_ok++; > > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(lookup_ok)++; > > ? ? ? ? ? ? ? ?} > > ? ? ? ? ? ? ? ?debug_yield_read(); > > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > > ? ? ? ? ? ? ? ?rcu_read_unlock(); > > - ? ? ? ? ? ? ? nr_reads++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > - ? ? ? ? ? ? ? if (caa_unlikely((nr_reads & ((1 << 10) - 1)) == 0)) > > + ? ? ? ? ? ? ? if (caa_unlikely((URCU_TLS(nr_reads) & ((1 << 10) - 1)) == 0)) > > ? ? ? ? ? ? ? ? ? ? ? ?rcu_quiescent_state(); > > ? ? ? ?} > > > > ? ? ? ?rcu_unregister_thread(); > > > > - ? ? ? *count = nr_reads; > > + ? ? ? *count = URCU_TLS(nr_reads); > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > > ? ? ? ?printf_verbose("readid : %lx, lookupfail %lu, lookupok %lu\n", > > - ? ? ? ? ? ? ? ? ? ? ? pthread_self(), lookup_fail, lookup_ok); > > + ? ? ? ? ? ? ? ? ? ? ? pthread_self(), URCU_TLS(lookup_fail), > > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(lookup_ok)); > > ? ? ? ?return ((void*)1); > > > > ?} > > @@ -136,10 +137,10 @@ void *test_hash_rw_thr_writer(void *_count) > > > > ? ? ? ?for (;;) { > > ? ? ? ? ? ? ? ?if ((addremove == AR_ADD || add_only) > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? || (addremove == AR_RANDOM && rand_r(&rand_lookup) & 1)) { > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? || (addremove == AR_RANDOM && rand_r(&URCU_TLS(rand_lookup)) & 1)) { > > ? ? ? ? ? ? ? ? ? ? ? ?node = malloc(sizeof(struct lfht_test_node)); > > ? ? ? ? ? ? ? ? ? ? ? ?lfht_test_node_init(node, > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&rand_lookup) % write_pool_size) + write_pool_offset), > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset), > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(void *)); > > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_lock(); > > ? ? ? ? ? ? ? ? ? ? ? ?if (add_unique) { > > @@ -159,36 +160,36 @@ void *test_hash_rw_thr_writer(void *_count) > > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_unlock(); > > ? ? ? ? ? ? ? ? ? ? ? ?if (add_unique && ret_node != &node->node) { > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?free(node); > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_addexist++; > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_addexist)++; > > ? ? ? ? ? ? ? ? ? ? ? ?} else { > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (add_replace && ret_node) { > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?call_rcu(&to_test_node(ret_node)->head, > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?free_node_cb); > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_addexist++; > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_addexist)++; > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} else { > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_add++; > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_add)++; > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} > > ? ? ? ? ? ? ? ? ? ? ? ?} > > ? ? ? ? ? ? ? ?} else { > > ? ? ? ? ? ? ? ? ? ? ? ?/* May delete */ > > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_lock(); > > ? ? ? ? ? ? ? ? ? ? ? ?cds_lfht_test_lookup(test_ht, > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&rand_lookup) % write_pool_size) + write_pool_offset), > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset), > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(void *), &iter); > > ? ? ? ? ? ? ? ? ? ? ? ?ret = cds_lfht_del(test_ht, cds_lfht_iter_get_node(&iter)); > > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_unlock(); > > ? ? ? ? ? ? ? ? ? ? ? ?if (ret == 0) { > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?node = cds_lfht_iter_get_test_node(&iter); > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?call_rcu(&node->head, free_node_cb); > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_del++; > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_del)++; > > ? ? ? ? ? ? ? ? ? ? ? ?} else > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_delnoent++; > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_delnoent)++; > > ? ? ? ? ? ? ? ?} > > ?#if 0 > > - ? ? ? ? ? ? ? //if (nr_writes % 100000 == 0) { > > - ? ? ? ? ? ? ? if (nr_writes % 1000 == 0) { > > + ? ? ? ? ? ? ? //if (URCU_TLS(nr_writes) % 100000 == 0) { > > + ? ? ? ? ? ? ? if (URCU_TLS(nr_writes) % 1000 == 0) { > > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_lock(); > > - ? ? ? ? ? ? ? ? ? ? ? if (rand_r(&rand_lookup) & 1) { > > + ? ? ? ? ? ? ? ? ? ? ? if (rand_r(&URCU_TLS(rand_lookup)) & 1) { > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ht_resize(test_ht, 1); > > ? ? ? ? ? ? ? ? ? ? ? ?} else { > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ht_resize(test_ht, -1); > > @@ -196,12 +197,12 @@ void *test_hash_rw_thr_writer(void *_count) > > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_unlock(); > > ? ? ? ? ? ? ? ?} > > ?#endif //0 > > - ? ? ? ? ? ? ? nr_writes++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wdelay); > > - ? ? ? ? ? ? ? if (caa_unlikely((nr_writes & ((1 << 10) - 1)) == 0)) > > + ? ? ? ? ? ? ? if (caa_unlikely((URCU_TLS(nr_writes) & ((1 << 10) - 1)) == 0)) > > ? ? ? ? ? ? ? ? ? ? ? ?rcu_quiescent_state(); > > ? ? ? ?} > > > > @@ -210,12 +211,13 @@ void *test_hash_rw_thr_writer(void *_count) > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > > ? ? ? ?printf_verbose("info id %lx: nr_add %lu, nr_addexist %lu, nr_del %lu, " > > - ? ? ? ? ? ? ? ? ? ? ? "nr_delnoent %lu\n", pthread_self(), nr_add, > > - ? ? ? ? ? ? ? ? ? ? ? nr_addexist, nr_del, nr_delnoent); > > - ? ? ? count->update_ops = nr_writes; > > - ? ? ? count->add = nr_add; > > - ? ? ? count->add_exist = nr_addexist; > > - ? ? ? count->remove = nr_del; > > + ? ? ? ? ? ? ? ? ? ? ? "nr_delnoent %lu\n", pthread_self(), URCU_TLS(nr_add), > > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_addexist), URCU_TLS(nr_del), > > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_delnoent)); > > + ? ? ? count->update_ops = URCU_TLS(nr_writes); > > + ? ? ? count->add = URCU_TLS(nr_add); > > + ? ? ? count->add_exist = URCU_TLS(nr_addexist); > > + ? ? ? count->remove = URCU_TLS(nr_del); > > ? ? ? ?return ((void*)2); > > ?} > > > > @@ -235,10 +237,10 @@ int test_hash_rw_populate_hash(void) > > ?"larger random pool (-p option). This may take a while...\n", init_populate, init_pool_size); > > ? ? ? ?} > > > > - ? ? ? while (nr_add < init_populate) { > > + ? ? ? while (URCU_TLS(nr_add) < init_populate) { > > ? ? ? ? ? ? ? ?node = malloc(sizeof(struct lfht_test_node)); > > ? ? ? ? ? ? ? ?lfht_test_node_init(node, > > - ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&rand_lookup) % init_pool_size) + init_pool_offset), > > + ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % init_pool_size) + init_pool_offset), > > ? ? ? ? ? ? ? ? ? ? ? ?sizeof(void *)); > > ? ? ? ? ? ? ? ?rcu_read_lock(); > > ? ? ? ? ? ? ? ?if (add_unique) { > > @@ -258,16 +260,16 @@ int test_hash_rw_populate_hash(void) > > ? ? ? ? ? ? ? ?rcu_read_unlock(); > > ? ? ? ? ? ? ? ?if (add_unique && ret_node != &node->node) { > > ? ? ? ? ? ? ? ? ? ? ? ?free(node); > > - ? ? ? ? ? ? ? ? ? ? ? nr_addexist++; > > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_addexist)++; > > ? ? ? ? ? ? ? ?} else { > > ? ? ? ? ? ? ? ? ? ? ? ?if (add_replace && ret_node) { > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?call_rcu(&to_test_node(ret_node)->head, free_node_cb); > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_addexist++; > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_addexist)++; > > ? ? ? ? ? ? ? ? ? ? ? ?} else { > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_add++; > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_add)++; > > ? ? ? ? ? ? ? ? ? ? ? ?} > > ? ? ? ? ? ? ? ?} > > - ? ? ? ? ? ? ? nr_writes++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > > ? ? ? ?} > > ? ? ? ?return 0; > > ?} > > diff --git a/tests/test_urcu_hash_unique.c b/tests/test_urcu_hash_unique.c > > index c934feb..610f479 100644 > > --- a/tests/test_urcu_hash_unique.c > > +++ b/tests/test_urcu_hash_unique.c > > @@ -98,20 +98,21 @@ void *test_hash_unique_thr_reader(void *_count) > > ? ? ? ? ? ? ? ?debug_yield_read(); > > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > > - ? ? ? ? ? ? ? nr_reads++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > - ? ? ? ? ? ? ? if (caa_unlikely((nr_reads & ((1 << 10) - 1)) == 0)) > > + ? ? ? ? ? ? ? if (caa_unlikely((URCU_TLS(nr_reads) & ((1 << 10) - 1)) == 0)) > > ? ? ? ? ? ? ? ? ? ? ? ?rcu_quiescent_state(); > > ? ? ? ?} > > > > ? ? ? ?rcu_unregister_thread(); > > > > - ? ? ? *count = nr_reads; > > + ? ? ? *count = URCU_TLS(nr_reads); > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > > ? ? ? ?printf_verbose("readid : %lx, lookupfail %lu, lookupok %lu\n", > > - ? ? ? ? ? ? ? ? ? ? ? pthread_self(), lookup_fail, lookup_ok); > > + ? ? ? ? ? ? ? ? ? ? ? pthread_self(), URCU_TLS(lookup_fail), > > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(lookup_ok)); > > ? ? ? ?return ((void*)1); > > > > ?} > > @@ -142,13 +143,13 @@ void *test_hash_unique_thr_writer(void *_count) > > ? ? ? ? ? ? ? ? * add unique/add replace with new node key from range. > > ? ? ? ? ? ? ? ? */ > > ? ? ? ? ? ? ? ?if (1 || (addremove == AR_ADD || add_only) > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? || (addremove == AR_RANDOM && rand_r(&rand_lookup) & 1)) { > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? || (addremove == AR_RANDOM && rand_r(&URCU_TLS(rand_lookup)) & 1)) { > > ? ? ? ? ? ? ? ? ? ? ? ?node = malloc(sizeof(struct lfht_test_node)); > > ? ? ? ? ? ? ? ? ? ? ? ?lfht_test_node_init(node, > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&rand_lookup) % write_pool_size) + write_pool_offset), > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset), > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(void *)); > > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_lock(); > > - ? ? ? ? ? ? ? ? ? ? ? loc_add_unique = rand_r(&rand_lookup) & 1; > > + ? ? ? ? ? ? ? ? ? ? ? loc_add_unique = rand_r(&URCU_TLS(rand_lookup)) & 1; > > ? ? ? ? ? ? ? ? ? ? ? ?if (loc_add_unique) { > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ret_node = cds_lfht_add_unique(test_ht, > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?test_hash(node->key, node->key_len, TEST_HASH_SEED), > > @@ -168,39 +169,39 @@ void *test_hash_unique_thr_writer(void *_count) > > ? ? ? ? ? ? ? ? ? ? ? ?if (loc_add_unique) { > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (ret_node != &node->node) { > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?free(node); > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_addexist++; > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_addexist)++; > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} else { > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_add++; > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_add)++; > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} > > ? ? ? ? ? ? ? ? ? ? ? ?} else { > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (ret_node) { > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?call_rcu(&to_test_node(ret_node)->head, > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?free_node_cb); > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_addexist++; > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_addexist)++; > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} else { > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_add++; > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_add)++; > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} > > ? ? ? ? ? ? ? ? ? ? ? ?} > > ? ? ? ? ? ? ? ?} else { > > ? ? ? ? ? ? ? ? ? ? ? ?/* May delete */ > > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_lock(); > > ? ? ? ? ? ? ? ? ? ? ? ?cds_lfht_test_lookup(test_ht, > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&rand_lookup) % write_pool_size) + write_pool_offset), > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset), > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(void *), &iter); > > ? ? ? ? ? ? ? ? ? ? ? ?ret = cds_lfht_del(test_ht, cds_lfht_iter_get_node(&iter)); > > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_unlock(); > > ? ? ? ? ? ? ? ? ? ? ? ?if (ret == 0) { > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?node = cds_lfht_iter_get_test_node(&iter); > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?call_rcu(&node->head, free_node_cb); > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_del++; > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_del)++; > > ? ? ? ? ? ? ? ? ? ? ? ?} else > > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nr_delnoent++; > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_delnoent)++; > > ? ? ? ? ? ? ? ?} > > ?#if 0 > > - ? ? ? ? ? ? ? //if (nr_writes % 100000 == 0) { > > - ? ? ? ? ? ? ? if (nr_writes % 1000 == 0) { > > + ? ? ? ? ? ? ? //if (URCU_TLS(nr_writes) % 100000 == 0) { > > + ? ? ? ? ? ? ? if (URCU_TLS(nr_writes) % 1000 == 0) { > > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_lock(); > > - ? ? ? ? ? ? ? ? ? ? ? if (rand_r(&rand_lookup) & 1) { > > + ? ? ? ? ? ? ? ? ? ? ? if (rand_r(&URCU_TLS(rand_lookup)) & 1) { > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ht_resize(test_ht, 1); > > ? ? ? ? ? ? ? ? ? ? ? ?} else { > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ht_resize(test_ht, -1); > > @@ -208,12 +209,12 @@ void *test_hash_unique_thr_writer(void *_count) > > ? ? ? ? ? ? ? ? ? ? ? ?rcu_read_unlock(); > > ? ? ? ? ? ? ? ?} > > ?#endif //0 > > - ? ? ? ? ? ? ? nr_writes++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wdelay); > > - ? ? ? ? ? ? ? if (caa_unlikely((nr_writes & ((1 << 10) - 1)) == 0)) > > + ? ? ? ? ? ? ? if (caa_unlikely((URCU_TLS(nr_writes) & ((1 << 10) - 1)) == 0)) > > ? ? ? ? ? ? ? ? ? ? ? ?rcu_quiescent_state(); > > ? ? ? ?} > > > > @@ -222,12 +223,13 @@ void *test_hash_unique_thr_writer(void *_count) > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > > ? ? ? ?printf_verbose("info id %lx: nr_add %lu, nr_addexist %lu, nr_del %lu, " > > - ? ? ? ? ? ? ? ? ? ? ? "nr_delnoent %lu\n", pthread_self(), nr_add, > > - ? ? ? ? ? ? ? ? ? ? ? nr_addexist, nr_del, nr_delnoent); > > - ? ? ? count->update_ops = nr_writes; > > - ? ? ? count->add = nr_add; > > - ? ? ? count->add_exist = nr_addexist; > > - ? ? ? count->remove = nr_del; > > + ? ? ? ? ? ? ? ? ? ? ? "nr_delnoent %lu\n", pthread_self(), URCU_TLS(nr_add), > > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_addexist), URCU_TLS(nr_del), > > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_delnoent)); > > + ? ? ? count->update_ops = URCU_TLS(nr_writes); > > + ? ? ? count->add = URCU_TLS(nr_add); > > + ? ? ? count->add_exist = URCU_TLS(nr_addexist); > > + ? ? ? count->remove = URCU_TLS(nr_del); > > ? ? ? ?return ((void*)2); > > ?} > > > > @@ -247,10 +249,10 @@ int test_hash_unique_populate_hash(void) > > ?"larger random pool (-p option). This may take a while...\n", init_populate, init_pool_size); > > ? ? ? ?} > > > > - ? ? ? while (nr_add < init_populate) { > > + ? ? ? while (URCU_TLS(nr_add) < init_populate) { > > ? ? ? ? ? ? ? ?node = malloc(sizeof(struct lfht_test_node)); > > ? ? ? ? ? ? ? ?lfht_test_node_init(node, > > - ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&rand_lookup) % init_pool_size) + init_pool_offset), > > + ? ? ? ? ? ? ? ? ? ? ? (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % init_pool_size) + init_pool_offset), > > ? ? ? ? ? ? ? ? ? ? ? ?sizeof(void *)); > > ? ? ? ? ? ? ? ?rcu_read_lock(); > > ? ? ? ? ? ? ? ?ret_node = cds_lfht_add_replace(test_ht, > > @@ -259,11 +261,11 @@ int test_hash_unique_populate_hash(void) > > ? ? ? ? ? ? ? ?rcu_read_unlock(); > > ? ? ? ? ? ? ? ?if (ret_node) { > > ? ? ? ? ? ? ? ? ? ? ? ?call_rcu(&to_test_node(ret_node)->head, free_node_cb); > > - ? ? ? ? ? ? ? ? ? ? ? nr_addexist++; > > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_addexist)++; > > ? ? ? ? ? ? ? ?} else { > > - ? ? ? ? ? ? ? ? ? ? ? nr_add++; > > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_add)++; > > ? ? ? ? ? ? ? ?} > > - ? ? ? ? ? ? ? nr_writes++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > > ? ? ? ?} > > ? ? ? ?return 0; > > ?} > > diff --git a/tests/test_urcu_lfq.c b/tests/test_urcu_lfq.c > > index 01a2781..66ddd41 100644 > > --- a/tests/test_urcu_lfq.c > > +++ b/tests/test_urcu_lfq.c > > @@ -38,6 +38,7 @@ > > ?#include > > > > ?#include > > +#include > > > > ?#ifdef __linux__ > > ?#include > > @@ -148,11 +149,11 @@ static int test_duration_enqueue(void) > > ? ? ? ?return !test_stop; > > ?} > > > > -static unsigned long long __thread nr_dequeues; > > -static unsigned long long __thread nr_enqueues; > > +static DEFINE_URCU_TLS(unsigned long long, nr_dequeues); > > +static DEFINE_URCU_TLS(unsigned long long, nr_enqueues); > > > > -static unsigned long long __thread nr_successful_dequeues; > > -static unsigned long long __thread nr_successful_enqueues; > > +static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); > > +static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); > > > > ?static unsigned int nr_enqueuers; > > ?static unsigned int nr_dequeuers; > > @@ -188,24 +189,24 @@ void *thr_enqueuer(void *_count) > > ? ? ? ? ? ? ? ?rcu_read_lock(); > > ? ? ? ? ? ? ? ?cds_lfq_enqueue_rcu(&q, &node->list); > > ? ? ? ? ? ? ? ?rcu_read_unlock(); > > - ? ? ? ? ? ? ? nr_successful_enqueues++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_successful_enqueues)++; > > > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wdelay); > > ?fail: > > - ? ? ? ? ? ? ? nr_enqueues++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_enqueues)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_enqueue())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ?} > > > > ? ? ? ?rcu_unregister_thread(); > > > > - ? ? ? count[0] = nr_enqueues; > > - ? ? ? count[1] = nr_successful_enqueues; > > + ? ? ? count[0] = URCU_TLS(nr_enqueues); > > + ? ? ? count[1] = URCU_TLS(nr_successful_enqueues); > > ? ? ? ?printf_verbose("enqueuer thread_end, thread id : %lx, tid %lu, " > > ? ? ? ? ? ? ? ? ? ? ? "enqueues %llu successful_enqueues %llu\n", > > - ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), nr_enqueues, > > - ? ? ? ? ? ? ? ? ? ? ?nr_successful_enqueues); > > + ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), > > + ? ? ? ? ? ? ? ? ? ? ?URCU_TLS(nr_enqueues), URCU_TLS(nr_successful_enqueues)); > > ? ? ? ?return ((void*)1); > > > > ?} > > @@ -251,10 +252,10 @@ void *thr_dequeuer(void *_count) > > > > ? ? ? ? ? ? ? ?if (node) { > > ? ? ? ? ? ? ? ? ? ? ? ?call_rcu(&node->rcu, free_node_cb); > > - ? ? ? ? ? ? ? ? ? ? ? nr_successful_dequeues++; > > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_successful_dequeues)++; > > ? ? ? ? ? ? ? ?} > > > > - ? ? ? ? ? ? ? nr_dequeues++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_dequeues)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_dequeue())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > > @@ -265,10 +266,10 @@ void *thr_dequeuer(void *_count) > > ? ? ? ?rcu_defer_unregister_thread(); > > ? ? ? ?printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " > > ? ? ? ? ? ? ? ? ? ? ? "dequeues %llu, successful_dequeues %llu\n", > > - ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), nr_dequeues, > > - ? ? ? ? ? ? ? ? ? ? ?nr_successful_dequeues); > > - ? ? ? count[0] = nr_dequeues; > > - ? ? ? count[1] = nr_successful_dequeues; > > + ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), > > + ? ? ? ? ? ? ? ? ? ? ?URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues)); > > + ? ? ? count[0] = URCU_TLS(nr_dequeues); > > + ? ? ? count[1] = URCU_TLS(nr_successful_dequeues); > > ? ? ? ?return ((void*)2); > > ?} > > > > diff --git a/tests/test_urcu_lfs.c b/tests/test_urcu_lfs.c > > index b48a35f..88bf65d 100644 > > --- a/tests/test_urcu_lfs.c > > +++ b/tests/test_urcu_lfs.c > > @@ -38,6 +38,7 @@ > > ?#include > > > > ?#include > > +#include > > > > ?#ifdef __linux__ > > ?#include > > @@ -148,11 +149,11 @@ static int test_duration_enqueue(void) > > ? ? ? ?return !test_stop; > > ?} > > > > -static unsigned long long __thread nr_dequeues; > > -static unsigned long long __thread nr_enqueues; > > +static DEFINE_URCU_TLS(unsigned long long, nr_dequeues); > > +static DEFINE_URCU_TLS(unsigned long long, nr_enqueues); > > > > -static unsigned long long __thread nr_successful_dequeues; > > -static unsigned long long __thread nr_successful_enqueues; > > +static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); > > +static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); > > > > ?static unsigned int nr_enqueuers; > > ?static unsigned int nr_dequeuers; > > @@ -187,24 +188,24 @@ void *thr_enqueuer(void *_count) > > ? ? ? ? ? ? ? ?cds_lfs_node_init_rcu(&node->list); > > ? ? ? ? ? ? ? ?/* No rcu read-side is needed for push */ > > ? ? ? ? ? ? ? ?cds_lfs_push_rcu(&s, &node->list); > > - ? ? ? ? ? ? ? nr_successful_enqueues++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_successful_enqueues)++; > > > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wdelay); > > ?fail: > > - ? ? ? ? ? ? ? nr_enqueues++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_enqueues)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_enqueue())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ?} > > > > ? ? ? ?rcu_unregister_thread(); > > > > - ? ? ? count[0] = nr_enqueues; > > - ? ? ? count[1] = nr_successful_enqueues; > > + ? ? ? count[0] = URCU_TLS(nr_enqueues); > > + ? ? ? count[1] = URCU_TLS(nr_successful_enqueues); > > ? ? ? ?printf_verbose("enqueuer thread_end, thread id : %lx, tid %lu, " > > ? ? ? ? ? ? ? ? ? ? ? "enqueues %llu successful_enqueues %llu\n", > > - ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), nr_enqueues, > > - ? ? ? ? ? ? ? ? ? ? ?nr_successful_enqueues); > > + ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), > > + ? ? ? ? ? ? ? ? ? ? ?URCU_TLS(nr_enqueues), URCU_TLS(nr_successful_enqueues)); > > ? ? ? ?return ((void*)1); > > > > ?} > > @@ -249,9 +250,9 @@ void *thr_dequeuer(void *_count) > > ? ? ? ? ? ? ? ?rcu_read_unlock(); > > ? ? ? ? ? ? ? ?if (node) { > > ? ? ? ? ? ? ? ? ? ? ? ?call_rcu(&node->rcu, free_node_cb); > > - ? ? ? ? ? ? ? ? ? ? ? nr_successful_dequeues++; > > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_successful_dequeues)++; > > ? ? ? ? ? ? ? ?} > > - ? ? ? ? ? ? ? nr_dequeues++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_dequeues)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_dequeue())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > > @@ -263,10 +264,10 @@ void *thr_dequeuer(void *_count) > > > > ? ? ? ?printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " > > ? ? ? ? ? ? ? ? ? ? ? "dequeues %llu, successful_dequeues %llu\n", > > - ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), nr_dequeues, > > - ? ? ? ? ? ? ? ? ? ? ?nr_successful_dequeues); > > - ? ? ? count[0] = nr_dequeues; > > - ? ? ? count[1] = nr_successful_dequeues; > > + ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), > > + ? ? ? ? ? ? ? ? ? ? ?URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues)); > > + ? ? ? count[0] = URCU_TLS(nr_dequeues); > > + ? ? ? count[1] = URCU_TLS(nr_successful_dequeues); > > ? ? ? ?return ((void*)2); > > ?} > > > > diff --git a/tests/test_urcu_qsbr.c b/tests/test_urcu_qsbr.c > > index b986fd8..421fb07 100644 > > --- a/tests/test_urcu_qsbr.c > > +++ b/tests/test_urcu_qsbr.c > > @@ -35,6 +35,7 @@ > > ?#include > > > > ?#include > > +#include > > > > ?#ifdef __linux__ > > ?#include > > @@ -153,8 +154,8 @@ static int test_duration_read(void) > > ? ? ? ?return !test_stop; > > ?} > > > > -static unsigned long long __thread nr_writes; > > -static unsigned long long __thread nr_reads; > > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > > > ?static unsigned int nr_readers; > > ?static unsigned int nr_writers; > > @@ -241,9 +242,9 @@ void *thr_reader(void *_count) > > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > > ? ? ? ? ? ? ? ?rcu_read_unlock(); > > - ? ? ? ? ? ? ? nr_reads++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > > ? ? ? ? ? ? ? ?/* QS each 1024 reads */ > > - ? ? ? ? ? ? ? if (caa_unlikely((nr_reads & ((1 << 10) - 1)) == 0)) > > + ? ? ? ? ? ? ? if (caa_unlikely((URCU_TLS(nr_reads) & ((1 << 10) - 1)) == 0)) > > ? ? ? ? ? ? ? ? ? ? ? ?rcu_quiescent_state(); > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > @@ -255,7 +256,7 @@ void *thr_reader(void *_count) > > ? ? ? ?rcu_register_thread(); > > ? ? ? ?rcu_unregister_thread(); > > > > - ? ? ? *count = nr_reads; > > + ? ? ? *count = URCU_TLS(nr_reads); > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > > ? ? ? ?return ((void*)1); > > @@ -290,7 +291,7 @@ void *thr_writer(void *_count) > > ? ? ? ? ? ? ? ? ? ? ? ?old->a = 0; > > ? ? ? ? ? ? ? ?test_array_free(old); > > ? ? ? ? ? ? ? ?rcu_copy_mutex_unlock(); > > - ? ? ? ? ? ? ? nr_writes++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > > @@ -299,7 +300,7 @@ void *thr_writer(void *_count) > > > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > > - ? ? ? *count = nr_writes; > > + ? ? ? *count = URCU_TLS(nr_writes); > > ? ? ? ?return ((void*)2); > > ?} > > > > diff --git a/tests/test_urcu_qsbr_gc.c b/tests/test_urcu_qsbr_gc.c > > index 9deb0aa..561a475 100644 > > --- a/tests/test_urcu_qsbr_gc.c > > +++ b/tests/test_urcu_qsbr_gc.c > > @@ -35,6 +35,7 @@ > > ?#include > > > > ?#include > > +#include > > > > ?#ifdef __linux__ > > ?#include > > @@ -159,8 +160,8 @@ static int test_duration_read(void) > > ? ? ? ?return !test_stop; > > ?} > > > > -static unsigned long long __thread nr_writes; > > -static unsigned long long __thread nr_reads; > > +static DEFINE_URCU_TLS(unsigned long long, nr_writes); > > +static DEFINE_URCU_TLS(unsigned long long, nr_reads); > > > > ?static unsigned int nr_readers; > > ?static unsigned int nr_writers; > > @@ -217,9 +218,9 @@ void *thr_reader(void *_count) > > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(rduration); > > ? ? ? ? ? ? ? ?_rcu_read_unlock(); > > - ? ? ? ? ? ? ? nr_reads++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_reads)++; > > ? ? ? ? ? ? ? ?/* QS each 1024 reads */ > > - ? ? ? ? ? ? ? if (caa_unlikely((nr_reads & ((1 << 10) - 1)) == 0)) > > + ? ? ? ? ? ? ? if (caa_unlikely((URCU_TLS(nr_reads) & ((1 << 10) - 1)) == 0)) > > ? ? ? ? ? ? ? ? ? ? ? ?_rcu_quiescent_state(); > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_read())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > @@ -227,7 +228,7 @@ void *thr_reader(void *_count) > > > > ? ? ? ?rcu_unregister_thread(); > > > > - ? ? ? *count = nr_reads; > > + ? ? ? *count = URCU_TLS(nr_reads); > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"reader", pthread_self(), (unsigned long)gettid()); > > ? ? ? ?return ((void*)1); > > @@ -293,7 +294,7 @@ void *thr_writer(void *data) > > ? ? ? ? ? ? ? ?if (caa_unlikely(wduration)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wduration); > > ? ? ? ? ? ? ? ?rcu_gc_reclaim(wtidx, old); > > - ? ? ? ? ? ? ? nr_writes++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_writes)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_write())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > > @@ -302,7 +303,7 @@ void *thr_writer(void *data) > > > > ? ? ? ?printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", > > ? ? ? ? ? ? ? ? ? ? ? ?"writer", pthread_self(), (unsigned long)gettid()); > > - ? ? ? tot_nr_writes[wtidx] = nr_writes; > > + ? ? ? tot_nr_writes[wtidx] = URCU_TLS(nr_writes); > > ? ? ? ?return ((void*)2); > > ?} > > > > diff --git a/tests/test_urcu_wfq.c b/tests/test_urcu_wfq.c > > index 83ec635..75a9275 100644 > > --- a/tests/test_urcu_wfq.c > > +++ b/tests/test_urcu_wfq.c > > @@ -38,6 +38,7 @@ > > ?#include > > > > ?#include > > +#include > > > > ?#ifdef __linux__ > > ?#include > > @@ -147,11 +148,11 @@ static int test_duration_enqueue(void) > > ? ? ? ?return !test_stop; > > ?} > > > > -static unsigned long long __thread nr_dequeues; > > -static unsigned long long __thread nr_enqueues; > > +static DEFINE_URCU_TLS(unsigned long long, nr_dequeues); > > +static DEFINE_URCU_TLS(unsigned long long, nr_enqueues); > > > > -static unsigned long long __thread nr_successful_dequeues; > > -static unsigned long long __thread nr_successful_enqueues; > > +static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); > > +static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); > > > > ?static unsigned int nr_enqueuers; > > ?static unsigned int nr_dequeuers; > > @@ -178,22 +179,22 @@ void *thr_enqueuer(void *_count) > > ? ? ? ? ? ? ? ? ? ? ? ?goto fail; > > ? ? ? ? ? ? ? ?cds_wfq_node_init(node); > > ? ? ? ? ? ? ? ?cds_wfq_enqueue(&q, node); > > - ? ? ? ? ? ? ? nr_successful_enqueues++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_successful_enqueues)++; > > > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wdelay); > > ?fail: > > - ? ? ? ? ? ? ? nr_enqueues++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_enqueues)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_enqueue())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ?} > > > > - ? ? ? count[0] = nr_enqueues; > > - ? ? ? count[1] = nr_successful_enqueues; > > + ? ? ? count[0] = URCU_TLS(nr_enqueues); > > + ? ? ? count[1] = URCU_TLS(nr_successful_enqueues); > > ? ? ? ?printf_verbose("enqueuer thread_end, thread id : %lx, tid %lu, " > > ? ? ? ? ? ? ? ? ? ? ? "enqueues %llu successful_enqueues %llu\n", > > - ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), nr_enqueues, > > - ? ? ? ? ? ? ? ? ? ? ?nr_successful_enqueues); > > + ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), > > + ? ? ? ? ? ? ? ? ? ? ?URCU_TLS(nr_enqueues), URCU_TLS(nr_successful_enqueues)); > > ? ? ? ?return ((void*)1); > > > > ?} > > @@ -217,10 +218,10 @@ void *thr_dequeuer(void *_count) > > > > ? ? ? ? ? ? ? ?if (node) { > > ? ? ? ? ? ? ? ? ? ? ? ?free(node); > > - ? ? ? ? ? ? ? ? ? ? ? nr_successful_dequeues++; > > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_successful_dequeues)++; > > ? ? ? ? ? ? ? ?} > > > > - ? ? ? ? ? ? ? nr_dequeues++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_dequeues)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_dequeue())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > > @@ -229,10 +230,10 @@ void *thr_dequeuer(void *_count) > > > > ? ? ? ?printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " > > ? ? ? ? ? ? ? ? ? ? ? "dequeues %llu, successful_dequeues %llu\n", > > - ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), nr_dequeues, > > - ? ? ? ? ? ? ? ? ? ? ?nr_successful_dequeues); > > - ? ? ? count[0] = nr_dequeues; > > - ? ? ? count[1] = nr_successful_dequeues; > > + ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), > > + ? ? ? ? ? ? ? ? ? ? ?URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues)); > > + ? ? ? count[0] = URCU_TLS(nr_dequeues); > > + ? ? ? count[1] = URCU_TLS(nr_successful_dequeues); > > ? ? ? ?return ((void*)2); > > ?} > > > > diff --git a/tests/test_urcu_wfs.c b/tests/test_urcu_wfs.c > > index 7746a1d..be09944 100644 > > --- a/tests/test_urcu_wfs.c > > +++ b/tests/test_urcu_wfs.c > > @@ -38,6 +38,7 @@ > > ?#include > > > > ?#include > > +#include > > > > ?#ifdef __linux__ > > ?#include > > @@ -147,11 +148,11 @@ static int test_duration_enqueue(void) > > ? ? ? ?return !test_stop; > > ?} > > > > -static unsigned long long __thread nr_dequeues; > > -static unsigned long long __thread nr_enqueues; > > +static DEFINE_URCU_TLS(unsigned long long, nr_dequeues); > > +static DEFINE_URCU_TLS(unsigned long long, nr_enqueues); > > > > -static unsigned long long __thread nr_successful_dequeues; > > -static unsigned long long __thread nr_successful_enqueues; > > +static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); > > +static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); > > > > ?static unsigned int nr_enqueuers; > > ?static unsigned int nr_dequeuers; > > @@ -178,22 +179,22 @@ void *thr_enqueuer(void *_count) > > ? ? ? ? ? ? ? ? ? ? ? ?goto fail; > > ? ? ? ? ? ? ? ?cds_wfs_node_init(node); > > ? ? ? ? ? ? ? ?cds_wfs_push(&s, node); > > - ? ? ? ? ? ? ? nr_successful_enqueues++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_successful_enqueues)++; > > > > ? ? ? ? ? ? ? ?if (caa_unlikely(wdelay)) > > ? ? ? ? ? ? ? ? ? ? ? ?loop_sleep(wdelay); > > ?fail: > > - ? ? ? ? ? ? ? nr_enqueues++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_enqueues)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_enqueue())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ?} > > > > - ? ? ? count[0] = nr_enqueues; > > - ? ? ? count[1] = nr_successful_enqueues; > > + ? ? ? count[0] = URCU_TLS(nr_enqueues); > > + ? ? ? count[1] = URCU_TLS(nr_successful_enqueues); > > ? ? ? ?printf_verbose("enqueuer thread_end, thread id : %lx, tid %lu, " > > ? ? ? ? ? ? ? ? ? ? ? "enqueues %llu successful_enqueues %llu\n", > > - ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), nr_enqueues, > > - ? ? ? ? ? ? ? ? ? ? ?nr_successful_enqueues); > > + ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), > > + ? ? ? ? ? ? ? ? ? ? ?URCU_TLS(nr_enqueues), URCU_TLS(nr_successful_enqueues)); > > ? ? ? ?return ((void*)1); > > > > ?} > > @@ -217,10 +218,10 @@ void *thr_dequeuer(void *_count) > > > > ? ? ? ? ? ? ? ?if (node) { > > ? ? ? ? ? ? ? ? ? ? ? ?free(node); > > - ? ? ? ? ? ? ? ? ? ? ? nr_successful_dequeues++; > > + ? ? ? ? ? ? ? ? ? ? ? URCU_TLS(nr_successful_dequeues)++; > > ? ? ? ? ? ? ? ?} > > > > - ? ? ? ? ? ? ? nr_dequeues++; > > + ? ? ? ? ? ? ? URCU_TLS(nr_dequeues)++; > > ? ? ? ? ? ? ? ?if (caa_unlikely(!test_duration_dequeue())) > > ? ? ? ? ? ? ? ? ? ? ? ?break; > > ? ? ? ? ? ? ? ?if (caa_unlikely(rduration)) > > @@ -229,10 +230,10 @@ void *thr_dequeuer(void *_count) > > > > ? ? ? ?printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " > > ? ? ? ? ? ? ? ? ? ? ? "dequeues %llu, successful_dequeues %llu\n", > > - ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), nr_dequeues, > > - ? ? ? ? ? ? ? ? ? ? ?nr_successful_dequeues); > > - ? ? ? count[0] = nr_dequeues; > > - ? ? ? count[1] = nr_successful_dequeues; > > + ? ? ? ? ? ? ? ? ? ? ?pthread_self(), (unsigned long)gettid(), > > + ? ? ? ? ? ? ? ? ? ? ?URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues)); > > + ? ? ? count[0] = URCU_TLS(nr_dequeues); > > + ? ? ? count[1] = URCU_TLS(nr_successful_dequeues); > > ? ? ? ?return ((void*)2); > > ?} > > > > diff --git a/urcu-bp.c b/urcu-bp.c > > index 08b4b55..bb657d7 100644 > > --- a/urcu-bp.c > > +++ b/urcu-bp.c > > @@ -40,6 +40,7 @@ > > ?#include "urcu/map/urcu-bp.h" > > ?#include "urcu/static/urcu-bp.h" > > ?#include "urcu-pointer.h" > > +#include "urcu/tls-compat.h" > > > > ?/* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ > > ?#undef _LGPL_SOURCE > > @@ -94,7 +95,7 @@ static pthread_mutex_t rcu_gp_lock = PTHREAD_MUTEX_INITIALIZER; > > > > ?#ifdef DEBUG_YIELD > > ?unsigned int yield_active; > > -unsigned int __thread rand_yield; > > +DEFINE_URCU_TLS(unsigned int, rand_yield); > > ?#endif > > > > ?/* > > @@ -109,7 +110,7 @@ long rcu_gp_ctr = RCU_GP_COUNT; > > ?* Pointer to registry elements. Written to only by each individual reader. Read > > ?* by both the reader and the writers. > > ?*/ > > -struct rcu_reader __thread *rcu_reader; > > +DEFINE_URCU_TLS(struct rcu_reader *, rcu_reader); > > > > ?static CDS_LIST_HEAD(registry); > > > > @@ -322,7 +323,7 @@ static void add_thread(void) > > ? ? ? ?rcu_reader_reg->tid = pthread_self(); > > ? ? ? ?assert(rcu_reader_reg->ctr == 0); > > ? ? ? ?cds_list_add(&rcu_reader_reg->node, ®istry); > > - ? ? ? rcu_reader = rcu_reader_reg; > > + ? ? ? URCU_TLS(rcu_reader) = rcu_reader_reg; > > ?} > > > > ?/* Called with signals off and mutex locked */ > > @@ -363,7 +364,7 @@ void rcu_bp_register(void) > > ? ? ? ?/* > > ? ? ? ? * Check if a signal concurrently registered our thread since > > ? ? ? ? * the check in rcu_read_lock(). */ > > - ? ? ? if (rcu_reader) > > + ? ? ? if (URCU_TLS(rcu_reader)) > > ? ? ? ? ? ? ? ?goto end; > > > > ? ? ? ?mutex_lock(&rcu_gp_lock); > > diff --git a/urcu-call-rcu-impl.h b/urcu-call-rcu-impl.h > > index 36e3cf4..8ed2ab3 100644 > > --- a/urcu-call-rcu-impl.h > > +++ b/urcu-call-rcu-impl.h > > @@ -40,6 +40,7 @@ > > ?#include "urcu-pointer.h" > > ?#include "urcu/list.h" > > ?#include "urcu/futex.h" > > +#include "urcu/tls-compat.h" > > > > ?/* Data structure that identifies a call_rcu thread. */ > > > > @@ -62,7 +63,7 @@ CDS_LIST_HEAD(call_rcu_data_list); > > > > ?/* Link a thread using call_rcu() to its call_rcu thread. */ > > > > -static __thread struct call_rcu_data *thread_call_rcu_data; > > +static DEFINE_URCU_TLS(struct call_rcu_data *, thread_call_rcu_data); > > > > ?/* Guard call_rcu thread creation. */ > > > > @@ -232,7 +233,7 @@ static void *call_rcu_thread(void *arg) > > ? ? ? ? */ > > ? ? ? ?rcu_register_thread(); > > > > - ? ? ? thread_call_rcu_data = crdp; > > + ? ? ? URCU_TLS(thread_call_rcu_data) = crdp; > > ? ? ? ?if (!rt) { > > ? ? ? ? ? ? ? ?uatomic_dec(&crdp->futex); > > ? ? ? ? ? ? ? ?/* Decrement futex before reading call_rcu list */ > > @@ -470,8 +471,8 @@ struct call_rcu_data *get_call_rcu_data(void) > > ?{ > > ? ? ? ?struct call_rcu_data *crd; > > > > - ? ? ? if (thread_call_rcu_data != NULL) > > - ? ? ? ? ? ? ? return thread_call_rcu_data; > > + ? ? ? if (URCU_TLS(thread_call_rcu_data) != NULL) > > + ? ? ? ? ? ? ? return URCU_TLS(thread_call_rcu_data); > > > > ? ? ? ?if (maxcpus > 0) { > > ? ? ? ? ? ? ? ?crd = get_cpu_call_rcu_data(sched_getcpu()); > > @@ -488,7 +489,7 @@ struct call_rcu_data *get_call_rcu_data(void) > > > > ?struct call_rcu_data *get_thread_call_rcu_data(void) > > ?{ > > - ? ? ? return thread_call_rcu_data; > > + ? ? ? return URCU_TLS(thread_call_rcu_data); > > ?} > > > > ?/* > > @@ -504,7 +505,7 @@ struct call_rcu_data *get_thread_call_rcu_data(void) > > > > ?void set_thread_call_rcu_data(struct call_rcu_data *crdp) > > ?{ > > - ? ? ? thread_call_rcu_data = crdp; > > + ? ? ? URCU_TLS(thread_call_rcu_data) = crdp; > > ?} > > > > ?/* > > @@ -746,7 +747,7 @@ void call_rcu_after_fork_child(void) > > ? ? ? ?maxcpus_reset(); > > ? ? ? ?free(per_cpu_call_rcu_data); > > ? ? ? ?rcu_set_pointer(&per_cpu_call_rcu_data, NULL); > > - ? ? ? thread_call_rcu_data = NULL; > > + ? ? ? URCU_TLS(thread_call_rcu_data) = NULL; > > > > ? ? ? ?/* Dispose of all of the rest of the call_rcu_data structures. */ > > ? ? ? ?cds_list_for_each_entry_safe(crdp, next, &call_rcu_data_list, list) { > > diff --git a/urcu-defer-impl.h b/urcu-defer-impl.h > > index 4d1ca5e..f65e410 100644 > > --- a/urcu-defer-impl.h > > +++ b/urcu-defer-impl.h > > @@ -48,6 +48,7 @@ > > ?#include > > ?#include > > ?#include > > +#include > > > > ?/* > > ?* Number of entries in the per-thread defer queue. Must be power of 2. > > @@ -130,7 +131,7 @@ static int32_t defer_thread_stop; > > ?* Written to only by each individual deferer. Read by both the deferer and > > ?* the reclamation tread. > > ?*/ > > -static struct defer_queue __thread defer_queue; > > +static DEFINE_URCU_TLS(struct defer_queue, defer_queue); > > ?static CDS_LIST_HEAD(registry_defer); > > ?static pthread_t tid_defer; > > > > @@ -245,12 +246,12 @@ static void _rcu_defer_barrier_thread(void) > > ?{ > > ? ? ? ?unsigned long head, num_items; > > > > - ? ? ? head = defer_queue.head; > > - ? ? ? num_items = head - defer_queue.tail; > > + ? ? ? head = URCU_TLS(defer_queue).head; > > + ? ? ? num_items = head - URCU_TLS(defer_queue).tail; > > ? ? ? ?if (caa_unlikely(!num_items)) > > ? ? ? ? ? ? ? ?return; > > ? ? ? ?synchronize_rcu(); > > - ? ? ? rcu_defer_barrier_queue(&defer_queue, head); > > + ? ? ? rcu_defer_barrier_queue(&URCU_TLS(defer_queue), head); > > ?} > > > > ?void rcu_defer_barrier_thread(void) > > @@ -311,8 +312,8 @@ void _defer_rcu(void (*fct)(void *p), void *p) > > ? ? ? ? * Head is only modified by ourself. Tail can be modified by reclamation > > ? ? ? ? * thread. > > ? ? ? ? */ > > - ? ? ? head = defer_queue.head; > > - ? ? ? tail = CMM_LOAD_SHARED(defer_queue.tail); > > + ? ? ? head = URCU_TLS(defer_queue).head; > > + ? ? ? tail = CMM_LOAD_SHARED(URCU_TLS(defer_queue).tail); > > > > ? ? ? ?/* > > ? ? ? ? * If queue is full, or reached threshold. Empty queue ourself. > > @@ -321,7 +322,7 @@ void _defer_rcu(void (*fct)(void *p), void *p) > > ? ? ? ?if (caa_unlikely(head - tail >= DEFER_QUEUE_SIZE - 2)) { > > ? ? ? ? ? ? ? ?assert(head - tail <= DEFER_QUEUE_SIZE); > > ? ? ? ? ? ? ? ?rcu_defer_barrier_thread(); > > - ? ? ? ? ? ? ? assert(head - CMM_LOAD_SHARED(defer_queue.tail) == 0); > > + ? ? ? ? ? ? ? assert(head - CMM_LOAD_SHARED(URCU_TLS(defer_queue).tail) == 0); > > ? ? ? ?} > > > > ? ? ? ?/* > > @@ -340,25 +341,25 @@ void _defer_rcu(void (*fct)(void *p), void *p) > > ? ? ? ? * Decode: see the comments before 'struct defer_queue' > > ? ? ? ? * ? ? ? ? or the code in rcu_defer_barrier_queue(). > > ? ? ? ? */ > > - ? ? ? if (caa_unlikely(defer_queue.last_fct_in != fct > > + ? ? ? if (caa_unlikely(URCU_TLS(defer_queue).last_fct_in != fct > > ? ? ? ? ? ? ? ? ? ? ? ?|| DQ_IS_FCT_BIT(p) > > ? ? ? ? ? ? ? ? ? ? ? ?|| p == DQ_FCT_MARK)) { > > - ? ? ? ? ? ? ? defer_queue.last_fct_in = fct; > > + ? ? ? ? ? ? ? URCU_TLS(defer_queue).last_fct_in = fct; > > ? ? ? ? ? ? ? ?if (caa_unlikely(DQ_IS_FCT_BIT(fct) || fct == DQ_FCT_MARK)) { > > - ? ? ? ? ? ? ? ? ? ? ? _CMM_STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK], > > + ? ? ? ? ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(defer_queue).q[head++ & DEFER_QUEUE_MASK], > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?DQ_FCT_MARK); > > - ? ? ? ? ? ? ? ? ? ? ? _CMM_STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK], > > + ? ? ? ? ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(defer_queue).q[head++ & DEFER_QUEUE_MASK], > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?fct); > > ? ? ? ? ? ? ? ?} else { > > ? ? ? ? ? ? ? ? ? ? ? ?DQ_SET_FCT_BIT(fct); > > - ? ? ? ? ? ? ? ? ? ? ? _CMM_STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK], > > + ? ? ? ? ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(defer_queue).q[head++ & DEFER_QUEUE_MASK], > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?fct); > > ? ? ? ? ? ? ? ?} > > ? ? ? ?} > > - ? ? ? _CMM_STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK], p); > > + ? ? ? _CMM_STORE_SHARED(URCU_TLS(defer_queue).q[head++ & DEFER_QUEUE_MASK], p); > > ? ? ? ?cmm_smp_wmb(); ?/* Publish new pointer before head */ > > ? ? ? ? ? ? ? ? ? ? ? ?/* Write q[] before head. */ > > - ? ? ? CMM_STORE_SHARED(defer_queue.head, head); > > + ? ? ? CMM_STORE_SHARED(URCU_TLS(defer_queue).head, head); > > ? ? ? ?cmm_smp_mb(); ? /* Write queue head before read futex */ > > ? ? ? ?/* > > ? ? ? ? * Wake-up any waiting defer thread. > > @@ -422,16 +423,16 @@ int rcu_defer_register_thread(void) > > ?{ > > ? ? ? ?int was_empty; > > > > - ? ? ? assert(defer_queue.last_head == 0); > > - ? ? ? assert(defer_queue.q == NULL); > > - ? ? ? defer_queue.q = malloc(sizeof(void *) * DEFER_QUEUE_SIZE); > > - ? ? ? if (!defer_queue.q) > > + ? ? ? assert(URCU_TLS(defer_queue).last_head == 0); > > + ? ? ? assert(URCU_TLS(defer_queue).q == NULL); > > + ? ? ? URCU_TLS(defer_queue).q = malloc(sizeof(void *) * DEFER_QUEUE_SIZE); > > + ? ? ? if (!URCU_TLS(defer_queue).q) > > ? ? ? ? ? ? ? ?return -ENOMEM; > > > > ? ? ? ?mutex_lock_defer(&defer_thread_mutex); > > ? ? ? ?mutex_lock_defer(&rcu_defer_mutex); > > ? ? ? ?was_empty = cds_list_empty(®istry_defer); > > - ? ? ? cds_list_add(&defer_queue.list, ®istry_defer); > > + ? ? ? cds_list_add(&URCU_TLS(defer_queue).list, ®istry_defer); > > ? ? ? ?mutex_unlock(&rcu_defer_mutex); > > > > ? ? ? ?if (was_empty) > > @@ -446,10 +447,10 @@ void rcu_defer_unregister_thread(void) > > > > ? ? ? ?mutex_lock_defer(&defer_thread_mutex); > > ? ? ? ?mutex_lock_defer(&rcu_defer_mutex); > > - ? ? ? cds_list_del(&defer_queue.list); > > + ? ? ? cds_list_del(&URCU_TLS(defer_queue).list); > > ? ? ? ?_rcu_defer_barrier_thread(); > > - ? ? ? free(defer_queue.q); > > - ? ? ? defer_queue.q = NULL; > > + ? ? ? free(URCU_TLS(defer_queue).q); > > + ? ? ? URCU_TLS(defer_queue).q = NULL; > > ? ? ? ?is_empty = cds_list_empty(®istry_defer); > > ? ? ? ?mutex_unlock(&rcu_defer_mutex); > > > > diff --git a/urcu-qsbr.c b/urcu-qsbr.c > > index 745676e..b20d564 100644 > > --- a/urcu-qsbr.c > > +++ b/urcu-qsbr.c > > @@ -40,6 +40,7 @@ > > ?#define BUILD_QSBR_LIB > > ?#include "urcu/static/urcu-qsbr.h" > > ?#include "urcu-pointer.h" > > +#include "urcu/tls-compat.h" > > > > ?/* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ > > ?#undef _LGPL_SOURCE > > @@ -66,11 +67,11 @@ unsigned long rcu_gp_ctr = RCU_GP_ONLINE; > > ?* Written to only by each individual reader. Read by both the reader and the > > ?* writers. > > ?*/ > > -struct rcu_reader __thread rcu_reader; > > +DEFINE_URCU_TLS(struct rcu_reader, rcu_reader); > > > > ?#ifdef DEBUG_YIELD > > ?unsigned int yield_active; > > -unsigned int __thread rand_yield; > > +DEFINE_URCU_TLS(unsigned int, rand_yield); > > ?#endif > > > > ?static CDS_LIST_HEAD(registry); > > @@ -139,7 +140,7 @@ static void update_counter_and_wait(void) > > ? ? ? ? * quiescent state. Failure to do so could result in the writer > > ? ? ? ? * waiting forever while new readers are always accessing data > > ? ? ? ? * (no progress). Enforce compiler-order of store to rcu_gp_ctr > > - ? ? ? ?* before load rcu_reader ctr. > > + ? ? ? ?* before load URCU_TLS(rcu_reader).ctr. > > ? ? ? ? */ > > ? ? ? ?cmm_barrier(); > > > > @@ -206,7 +207,7 @@ void synchronize_rcu(void) > > ?{ > > ? ? ? ?unsigned long was_online; > > > > - ? ? ? was_online = rcu_reader.ctr; > > + ? ? ? was_online = URCU_TLS(rcu_reader).ctr; > > > > ? ? ? ?/* All threads should read qparity before accessing data structure > > ? ? ? ? * where new ptr points to. ?In the "then" case, rcu_thread_offline > > @@ -236,7 +237,7 @@ void synchronize_rcu(void) > > ? ? ? ? * committing next rcu_gp_ctr update to memory. Failure to > > ? ? ? ? * do so could result in the writer waiting forever while new > > ? ? ? ? * readers are always accessing data (no progress). ?Enforce > > - ? ? ? ?* compiler-order of load rcu_reader ctr before store to > > + ? ? ? ?* compiler-order of load URCU_TLS(rcu_reader).ctr before store to > > ? ? ? ? * rcu_gp_ctr. > > ? ? ? ? */ > > ? ? ? ?cmm_barrier(); > > @@ -269,7 +270,7 @@ void synchronize_rcu(void) > > ?{ > > ? ? ? ?unsigned long was_online; > > > > - ? ? ? was_online = rcu_reader.ctr; > > + ? ? ? was_online = URCU_TLS(rcu_reader).ctr; > > > > ? ? ? ?/* > > ? ? ? ? * Mark the writer thread offline to make sure we don't wait for > > @@ -326,11 +327,11 @@ void rcu_thread_online(void) > > > > ?void rcu_register_thread(void) > > ?{ > > - ? ? ? rcu_reader.tid = pthread_self(); > > - ? ? ? assert(rcu_reader.ctr == 0); > > + ? ? ? URCU_TLS(rcu_reader).tid = pthread_self(); > > + ? ? ? assert(URCU_TLS(rcu_reader).ctr == 0); > > > > ? ? ? ?mutex_lock(&rcu_gp_lock); > > - ? ? ? cds_list_add(&rcu_reader.node, ®istry); > > + ? ? ? cds_list_add(&URCU_TLS(rcu_reader).node, ®istry); > > ? ? ? ?mutex_unlock(&rcu_gp_lock); > > ? ? ? ?_rcu_thread_online(); > > ?} > > @@ -343,7 +344,7 @@ void rcu_unregister_thread(void) > > ? ? ? ? */ > > ? ? ? ?_rcu_thread_offline(); > > ? ? ? ?mutex_lock(&rcu_gp_lock); > > - ? ? ? cds_list_del(&rcu_reader.node); > > + ? ? ? cds_list_del(&URCU_TLS(rcu_reader).node); > > ? ? ? ?mutex_unlock(&rcu_gp_lock); > > ?} > > > > diff --git a/urcu.c b/urcu.c > > index 3948629..5fb4db8 100644 > > --- a/urcu.c > > +++ b/urcu.c > > @@ -40,6 +40,7 @@ > > ?#include "urcu/map/urcu.h" > > ?#include "urcu/static/urcu.h" > > ?#include "urcu-pointer.h" > > +#include "urcu/tls-compat.h" > > > > ?/* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ > > ?#undef _LGPL_SOURCE > > @@ -94,11 +95,11 @@ unsigned long rcu_gp_ctr = RCU_GP_COUNT; > > ?* Written to only by each individual reader. Read by both the reader and the > > ?* writers. > > ?*/ > > -struct rcu_reader __thread rcu_reader; > > +DEFINE_URCU_TLS(struct rcu_reader, rcu_reader); > > > > ?#ifdef DEBUG_YIELD > > ?unsigned int yield_active; > > -unsigned int __thread rand_yield; > > +DEFINE_URCU_TLS(unsigned int, rand_yield); > > ?#endif > > > > ?static CDS_LIST_HEAD(registry); > > @@ -120,9 +121,9 @@ static void mutex_lock(pthread_mutex_t *mutex) > > ? ? ? ? ? ? ? ? ? ? ? ?perror("Error in pthread mutex lock"); > > ? ? ? ? ? ? ? ? ? ? ? ?exit(-1); > > ? ? ? ? ? ? ? ?} > > - ? ? ? ? ? ? ? if (CMM_LOAD_SHARED(rcu_reader.need_mb)) { > > + ? ? ? ? ? ? ? if (CMM_LOAD_SHARED(URCU_TLS(rcu_reader).need_mb)) { > > ? ? ? ? ? ? ? ? ? ? ? ?cmm_smp_mb(); > > - ? ? ? ? ? ? ? ? ? ? ? _CMM_STORE_SHARED(rcu_reader.need_mb, 0); > > + ? ? ? ? ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader).need_mb, 0); > > ? ? ? ? ? ? ? ? ? ? ? ?cmm_smp_mb(); > > ? ? ? ? ? ? ? ?} > > ? ? ? ? ? ? ? ?poll(NULL,0,10); > > @@ -245,7 +246,7 @@ void update_counter_and_wait(void) > > ? ? ? ?cmm_smp_mb(); > > > > ? ? ? ?/* > > - ? ? ? ?* Wait for each thread rcu_reader.ctr count to become 0. > > + ? ? ? ?* Wait for each thread URCU_TLS(rcu_reader).ctr count to become 0. > > ? ? ? ? */ > > ? ? ? ?for (;;) { > > ? ? ? ? ? ? ? ?wait_loops++; > > @@ -277,7 +278,8 @@ void update_counter_and_wait(void) > > ?#else /* #ifndef HAS_INCOHERENT_CACHES */ > > ? ? ? ? ? ? ? ?/* > > ? ? ? ? ? ? ? ? * BUSY-LOOP. Force the reader thread to commit its > > - ? ? ? ? ? ? ? ?* rcu_reader.ctr update to memory if we wait for too long. > > + ? ? ? ? ? ? ? ?* URCU_TLS(rcu_reader).ctr update to memory if we wait > > + ? ? ? ? ? ? ? ?* for too long. > > ? ? ? ? ? ? ? ? */ > > ? ? ? ? ? ? ? ?if (cds_list_empty(®istry)) { > > ? ? ? ? ? ? ? ? ? ? ? ?if (wait_loops == RCU_QS_ACTIVE_ATTEMPTS) { > > @@ -328,7 +330,7 @@ void synchronize_rcu(void) > > ? ? ? ? * committing next rcu_gp_ctr update to memory. Failure to do so could > > ? ? ? ? * result in the writer waiting forever while new readers are always > > ? ? ? ? * accessing data (no progress). ?Enforce compiler-order of load > > - ? ? ? ?* rcu_reader ctr before store to rcu_gp_ctr. > > + ? ? ? ?* URCU_TLS(rcu_reader).ctr before store to rcu_gp_ctr. > > ? ? ? ? */ > > ? ? ? ?cmm_barrier(); > > > > @@ -368,20 +370,20 @@ void rcu_read_unlock(void) > > > > ?void rcu_register_thread(void) > > ?{ > > - ? ? ? rcu_reader.tid = pthread_self(); > > - ? ? ? assert(rcu_reader.need_mb == 0); > > - ? ? ? assert(!(rcu_reader.ctr & RCU_GP_CTR_NEST_MASK)); > > + ? ? ? URCU_TLS(rcu_reader).tid = pthread_self(); > > + ? ? ? assert(URCU_TLS(rcu_reader).need_mb == 0); > > + ? ? ? assert(!(URCU_TLS(rcu_reader).ctr & RCU_GP_CTR_NEST_MASK)); > > > > ? ? ? ?mutex_lock(&rcu_gp_lock); > > ? ? ? ?rcu_init(); ? ? /* In case gcc does not support constructor attribute */ > > - ? ? ? cds_list_add(&rcu_reader.node, ®istry); > > + ? ? ? cds_list_add(&URCU_TLS(rcu_reader).node, ®istry); > > ? ? ? ?mutex_unlock(&rcu_gp_lock); > > ?} > > > > ?void rcu_unregister_thread(void) > > ?{ > > ? ? ? ?mutex_lock(&rcu_gp_lock); > > - ? ? ? cds_list_del(&rcu_reader.node); > > + ? ? ? cds_list_del(&URCU_TLS(rcu_reader).node); > > ? ? ? ?mutex_unlock(&rcu_gp_lock); > > ?} > > > > @@ -405,7 +407,7 @@ static void sigrcu_handler(int signo, siginfo_t *siginfo, void *context) > > ? ? ? ? * executed on. > > ? ? ? ? */ > > ? ? ? ?cmm_smp_mb(); > > - ? ? ? _CMM_STORE_SHARED(rcu_reader.need_mb, 0); > > + ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader).need_mb, 0); > > ? ? ? ?cmm_smp_mb(); > > ?} > > > > diff --git a/urcu/static/urcu-bp.h b/urcu/static/urcu-bp.h > > index 8d22163..e7b2eda 100644 > > --- a/urcu/static/urcu-bp.h > > +++ b/urcu/static/urcu-bp.h > > @@ -38,6 +38,7 @@ > > ?#include > > ?#include > > ?#include > > +#include > > > > ?/* > > ?* This code section can only be included in LGPL 2.1 compatible source code. > > @@ -74,25 +75,25 @@ extern "C" { > > ?#define MAX_SLEEP 50 > > > > ?extern unsigned int yield_active; > > -extern unsigned int __thread rand_yield; > > +extern DECLARE_URCU_TLS(unsigned int, rand_yield); > > > > ?static inline void debug_yield_read(void) > > ?{ > > ? ? ? ?if (yield_active & YIELD_READ) > > - ? ? ? ? ? ? ? if (rand_r(&rand_yield) & 0x1) > > - ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&rand_yield) % MAX_SLEEP); > > + ? ? ? ? ? ? ? if (rand_r(&URCU_TLS(rand_yield)) & 0x1) > > + ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&URCU_TLS(rand_yield)) % MAX_SLEEP); > > ?} > > > > ?static inline void debug_yield_write(void) > > ?{ > > ? ? ? ?if (yield_active & YIELD_WRITE) > > - ? ? ? ? ? ? ? if (rand_r(&rand_yield) & 0x1) > > - ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&rand_yield) % MAX_SLEEP); > > + ? ? ? ? ? ? ? if (rand_r(&URCU_TLS(rand_yield)) & 0x1) > > + ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&URCU_TLS(rand_yield)) % MAX_SLEEP); > > ?} > > > > ?static inline void debug_yield_init(void) > > ?{ > > - ? ? ? rand_yield = time(NULL) ^ pthread_self(); > > + ? ? ? URCU_TLS(rand_yield) = time(NULL) ^ pthread_self(); > > ?} > > ?#else > > ?static inline void debug_yield_read(void) > > @@ -144,7 +145,7 @@ struct rcu_reader { > > ?* Adds a pointer dereference on the read-side, but won't require to unregister > > ?* the reader thread. > > ?*/ > > -extern struct rcu_reader __thread *rcu_reader; > > +extern DECLARE_URCU_TLS(struct rcu_reader *, rcu_reader); > > > > ?static inline int rcu_old_gp_ongoing(long *value) > > ?{ > > @@ -166,24 +167,24 @@ static inline void _rcu_read_lock(void) > > ? ? ? ?long tmp; > > > > ? ? ? ?/* Check if registered */ > > - ? ? ? if (caa_unlikely(!rcu_reader)) > > + ? ? ? if (caa_unlikely(!URCU_TLS(rcu_reader))) > > ? ? ? ? ? ? ? ?rcu_bp_register(); > > > > ? ? ? ?cmm_barrier(); ?/* Ensure the compiler does not reorder us with mutex */ > > - ? ? ? tmp = rcu_reader->ctr; > > + ? ? ? tmp = URCU_TLS(rcu_reader)->ctr; > > ? ? ? ?/* > > ? ? ? ? * rcu_gp_ctr is > > ? ? ? ? * ? RCU_GP_COUNT | (~RCU_GP_CTR_PHASE or RCU_GP_CTR_PHASE) > > ? ? ? ? */ > > ? ? ? ?if (caa_likely(!(tmp & RCU_GP_CTR_NEST_MASK))) { > > - ? ? ? ? ? ? ? _CMM_STORE_SHARED(rcu_reader->ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); > > + ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader)->ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); > > ? ? ? ? ? ? ? ?/* > > ? ? ? ? ? ? ? ? * Set active readers count for outermost nesting level before > > ? ? ? ? ? ? ? ? * accessing the pointer. > > ? ? ? ? ? ? ? ? */ > > ? ? ? ? ? ? ? ?cmm_smp_mb(); > > ? ? ? ?} else { > > - ? ? ? ? ? ? ? _CMM_STORE_SHARED(rcu_reader->ctr, tmp + RCU_GP_COUNT); > > + ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader)->ctr, tmp + RCU_GP_COUNT); > > ? ? ? ?} > > ?} > > > > @@ -193,7 +194,7 @@ static inline void _rcu_read_unlock(void) > > ? ? ? ? * Finish using rcu before decrementing the pointer. > > ? ? ? ? */ > > ? ? ? ?cmm_smp_mb(); > > - ? ? ? _CMM_STORE_SHARED(rcu_reader->ctr, rcu_reader->ctr - RCU_GP_COUNT); > > + ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader)->ctr, URCU_TLS(rcu_reader)->ctr - RCU_GP_COUNT); > > ? ? ? ?cmm_barrier(); ?/* Ensure the compiler does not reorder us with mutex */ > > ?} > > > > diff --git a/urcu/static/urcu-qsbr.h b/urcu/static/urcu-qsbr.h > > index 68bfc31..22908a4 100644 > > --- a/urcu/static/urcu-qsbr.h > > +++ b/urcu/static/urcu-qsbr.h > > @@ -42,6 +42,7 @@ > > ?#include > > ?#include > > ?#include > > +#include > > > > ?#ifdef __cplusplus > > ?extern "C" { > > @@ -74,25 +75,25 @@ extern "C" { > > ?#define MAX_SLEEP 50 > > > > ?extern unsigned int yield_active; > > -extern unsigned int __thread rand_yield; > > +extern DECLARE_URCU_TLS(unsigned int, rand_yield); > > > > ?static inline void debug_yield_read(void) > > ?{ > > ? ? ? ?if (yield_active & YIELD_READ) > > - ? ? ? ? ? ? ? if (rand_r(&rand_yield) & 0x1) > > - ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&rand_yield) % MAX_SLEEP); > > + ? ? ? ? ? ? ? if (rand_r(&URCU_TLS(rand_yield)) & 0x1) > > + ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&URCU_TLS(rand_yield)) % MAX_SLEEP); > > ?} > > > > ?static inline void debug_yield_write(void) > > ?{ > > ? ? ? ?if (yield_active & YIELD_WRITE) > > - ? ? ? ? ? ? ? if (rand_r(&rand_yield) & 0x1) > > - ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&rand_yield) % MAX_SLEEP); > > + ? ? ? ? ? ? ? if (rand_r(&URCU_TLS(rand_yield)) & 0x1) > > + ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&URCU_TLS(rand_yield)) % MAX_SLEEP); > > ?} > > > > ?static inline void debug_yield_init(void) > > ?{ > > - ? ? ? rand_yield = time(NULL) ^ pthread_self(); > > + ? ? ? URCU_TLS(rand_yield) = time(NULL) ^ pthread_self(); > > ?} > > ?#else > > ?static inline void debug_yield_read(void) > > @@ -128,7 +129,7 @@ struct rcu_reader { > > ? ? ? ?pthread_t tid; > > ?}; > > > > -extern struct rcu_reader __thread rcu_reader; > > +extern DECLARE_URCU_TLS(struct rcu_reader, rcu_reader); > > > > ?extern int32_t gp_futex; > > > > @@ -137,8 +138,8 @@ extern int32_t gp_futex; > > ?*/ > > ?static inline void wake_up_gp(void) > > ?{ > > - ? ? ? if (caa_unlikely(_CMM_LOAD_SHARED(rcu_reader.waiting))) { > > - ? ? ? ? ? ? ? _CMM_STORE_SHARED(rcu_reader.waiting, 0); > > + ? ? ? if (caa_unlikely(_CMM_LOAD_SHARED(URCU_TLS(rcu_reader).waiting))) { > > + ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader).waiting, 0); > > ? ? ? ? ? ? ? ?cmm_smp_mb(); > > ? ? ? ? ? ? ? ?if (uatomic_read(&gp_futex) != -1) > > ? ? ? ? ? ? ? ? ? ? ? ?return; > > @@ -158,7 +159,7 @@ static inline int rcu_gp_ongoing(unsigned long *ctr) > > > > ?static inline void _rcu_read_lock(void) > > ?{ > > - ? ? ? rcu_assert(rcu_reader.ctr); > > + ? ? ? rcu_assert(URCU_TLS(rcu_reader).ctr); > > ?} > > > > ?static inline void _rcu_read_unlock(void) > > @@ -168,8 +169,8 @@ static inline void _rcu_read_unlock(void) > > ?static inline void _rcu_quiescent_state(void) > > ?{ > > ? ? ? ?cmm_smp_mb(); > > - ? ? ? _CMM_STORE_SHARED(rcu_reader.ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); > > - ? ? ? cmm_smp_mb(); ? /* write rcu_reader.ctr before read futex */ > > + ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); > > + ? ? ? cmm_smp_mb(); ? /* write URCU_TLS(rcu_reader).ctr before read futex */ > > ? ? ? ?wake_up_gp(); > > ? ? ? ?cmm_smp_mb(); > > ?} > > @@ -177,8 +178,8 @@ static inline void _rcu_quiescent_state(void) > > ?static inline void _rcu_thread_offline(void) > > ?{ > > ? ? ? ?cmm_smp_mb(); > > - ? ? ? CMM_STORE_SHARED(rcu_reader.ctr, 0); > > - ? ? ? cmm_smp_mb(); ? /* write rcu_reader.ctr before read futex */ > > + ? ? ? CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, 0); > > + ? ? ? cmm_smp_mb(); ? /* write URCU_TLS(rcu_reader).ctr before read futex */ > > ? ? ? ?wake_up_gp(); > > ? ? ? ?cmm_barrier(); ?/* Ensure the compiler does not reorder us with mutex */ > > ?} > > @@ -186,7 +187,7 @@ static inline void _rcu_thread_offline(void) > > ?static inline void _rcu_thread_online(void) > > ?{ > > ? ? ? ?cmm_barrier(); ?/* Ensure the compiler does not reorder us with mutex */ > > - ? ? ? _CMM_STORE_SHARED(rcu_reader.ctr, CMM_LOAD_SHARED(rcu_gp_ctr)); > > + ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, CMM_LOAD_SHARED(rcu_gp_ctr)); > > ? ? ? ?cmm_smp_mb(); > > ?} > > > > diff --git a/urcu/static/urcu.h b/urcu/static/urcu.h > > index 7ae0185..f27f8b6 100644 > > --- a/urcu/static/urcu.h > > +++ b/urcu/static/urcu.h > > @@ -40,6 +40,7 @@ > > ?#include > > ?#include > > ?#include > > +#include > > > > ?#ifdef __cplusplus > > ?extern "C" { > > @@ -121,25 +122,25 @@ extern "C" { > > ?#endif > > > > ?extern unsigned int yield_active; > > -extern unsigned int __thread rand_yield; > > +extern DECLARE_URCU_TLS(unsigned int, rand_yield); > > > > ?static inline void debug_yield_read(void) > > ?{ > > ? ? ? ?if (yield_active & YIELD_READ) > > - ? ? ? ? ? ? ? if (rand_r(&rand_yield) & 0x1) > > - ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&rand_yield) % MAX_SLEEP); > > + ? ? ? ? ? ? ? if (rand_r(&URCU_TLS(rand_yield)) & 0x1) > > + ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&URCU_TLS(rand_yield)) % MAX_SLEEP); > > ?} > > > > ?static inline void debug_yield_write(void) > > ?{ > > ? ? ? ?if (yield_active & YIELD_WRITE) > > - ? ? ? ? ? ? ? if (rand_r(&rand_yield) & 0x1) > > - ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&rand_yield) % MAX_SLEEP); > > + ? ? ? ? ? ? ? if (rand_r(&URCU_TLS(rand_yield)) & 0x1) > > + ? ? ? ? ? ? ? ? ? ? ? usleep(rand_r(&URCU_TLS(rand_yield)) % MAX_SLEEP); > > ?} > > > > ?static inline void debug_yield_init(void) > > ?{ > > - ? ? ? rand_yield = time(NULL) ^ (unsigned long) pthread_self(); > > + ? ? ? URCU_TLS(rand_yield) = time(NULL) ^ (unsigned long) pthread_self(); > > ?} > > ?#else > > ?static inline void debug_yield_read(void) > > @@ -222,7 +223,7 @@ struct rcu_reader { > > ? ? ? ?pthread_t tid; > > ?}; > > > > -extern struct rcu_reader __thread rcu_reader; > > +extern DECLARE_URCU_TLS(struct rcu_reader, rcu_reader); > > > > ?extern int32_t gp_futex; > > > > @@ -256,20 +257,20 @@ static inline void _rcu_read_lock(void) > > ? ? ? ?unsigned long tmp; > > > > ? ? ? ?cmm_barrier(); ?/* Ensure the compiler does not reorder us with mutex */ > > - ? ? ? tmp = rcu_reader.ctr; > > + ? ? ? tmp = URCU_TLS(rcu_reader).ctr; > > ? ? ? ?/* > > ? ? ? ? * rcu_gp_ctr is > > ? ? ? ? * ? RCU_GP_COUNT | (~RCU_GP_CTR_PHASE or RCU_GP_CTR_PHASE) > > ? ? ? ? */ > > ? ? ? ?if (caa_likely(!(tmp & RCU_GP_CTR_NEST_MASK))) { > > - ? ? ? ? ? ? ? _CMM_STORE_SHARED(rcu_reader.ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); > > + ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); > > ? ? ? ? ? ? ? ?/* > > ? ? ? ? ? ? ? ? * Set active readers count for outermost nesting level before > > ? ? ? ? ? ? ? ? * accessing the pointer. See smp_mb_master(). > > ? ? ? ? ? ? ? ? */ > > ? ? ? ? ? ? ? ?smp_mb_slave(RCU_MB_GROUP); > > ? ? ? ?} else { > > - ? ? ? ? ? ? ? _CMM_STORE_SHARED(rcu_reader.ctr, tmp + RCU_GP_COUNT); > > + ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, tmp + RCU_GP_COUNT); > > ? ? ? ?} > > ?} > > > > @@ -277,19 +278,19 @@ static inline void _rcu_read_unlock(void) > > ?{ > > ? ? ? ?unsigned long tmp; > > > > - ? ? ? tmp = rcu_reader.ctr; > > + ? ? ? tmp = URCU_TLS(rcu_reader).ctr; > > ? ? ? ?/* > > ? ? ? ? * Finish using rcu before decrementing the pointer. > > ? ? ? ? * See smp_mb_master(). > > ? ? ? ? */ > > ? ? ? ?if (caa_likely((tmp & RCU_GP_CTR_NEST_MASK) == RCU_GP_COUNT)) { > > ? ? ? ? ? ? ? ?smp_mb_slave(RCU_MB_GROUP); > > - ? ? ? ? ? ? ? _CMM_STORE_SHARED(rcu_reader.ctr, rcu_reader.ctr - RCU_GP_COUNT); > > - ? ? ? ? ? ? ? /* write rcu_reader.ctr before read futex */ > > + ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, URCU_TLS(rcu_reader).ctr - RCU_GP_COUNT); > > + ? ? ? ? ? ? ? /* write URCU_TLS(rcu_reader).ctr before read futex */ > > ? ? ? ? ? ? ? ?smp_mb_slave(RCU_MB_GROUP); > > ? ? ? ? ? ? ? ?wake_up_gp(); > > ? ? ? ?} else { > > - ? ? ? ? ? ? ? _CMM_STORE_SHARED(rcu_reader.ctr, rcu_reader.ctr - RCU_GP_COUNT); > > + ? ? ? ? ? ? ? _CMM_STORE_SHARED(URCU_TLS(rcu_reader).ctr, URCU_TLS(rcu_reader).ctr - RCU_GP_COUNT); > > ? ? ? ?} > > ? ? ? ?cmm_barrier(); ?/* Ensure the compiler does not reorder us with mutex */ > > ?} > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From paulmck at linux.vnet.ibm.com Wed May 16 14:32:38 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Wed, 16 May 2012 11:32:38 -0700 Subject: [lttng-dev] [rp] [RFC PATCH urcu] Document uatomic operations In-Reply-To: <20120516181742.GB16045@Krystal> References: <20120515023901.GA22786@Krystal> <20120515040936.GB2412@linux.vnet.ibm.com> <20120515121003.GA31468@Krystal> <20120516171803.GB2441@linux.vnet.ibm.com> <20120516181742.GB16045@Krystal> Message-ID: <20120516183238.GJ2441@linux.vnet.ibm.com> On Wed, May 16, 2012 at 02:17:42PM -0400, Mathieu Desnoyers wrote: > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > On Tue, May 15, 2012 at 08:10:03AM -0400, Mathieu Desnoyers wrote: > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > On Mon, May 14, 2012 at 10:39:01PM -0400, Mathieu Desnoyers wrote: > > > > > Document each atomic operation provided by urcu/uatomic.h, along with > > > > > their memory barrier guarantees. > > > > > > > > Great to see the documentation!!! Some comments below. > > > > > > > > Thanx, Paul > > > > > > > > > Signed-off-by: Mathieu Desnoyers > > > > > --- > > > > > diff --git a/doc/Makefile.am b/doc/Makefile.am > > > > > index bec1d7c..db9811c 100644 > > > > > --- a/doc/Makefile.am > > > > > +++ b/doc/Makefile.am > > > > > @@ -1 +1 @@ > > > > > -dist_doc_DATA = rcu-api.txt > > > > > +dist_doc_DATA = rcu-api.txt uatomic-api.txt > > > > > diff --git a/doc/uatomic-api.txt b/doc/uatomic-api.txt > > > > > new file mode 100644 > > > > > index 0000000..3605acf > > > > > --- /dev/null > > > > > +++ b/doc/uatomic-api.txt > > > > > @@ -0,0 +1,80 @@ > > > > > +Userspace RCU Atomic Operations API > > > > > +by Mathieu Desnoyers and Paul E. McKenney > > > > > + > > > > > + > > > > > +This document describes the API. Those are the atomic > > > > > +operations provided by the Userspace RCU library. The general rule > > > > > +regarding memory barriers is that only uatomic_xchg(), > > > > > +uatomic_cmpxchg(), uatomic_add_return(), and uatomic_sub_return() imply > > > > > +full memory barriers before and after the atomic operation. Other > > > > > +primitives don't guarantee any memory barrier. > > > > > + > > > > > +Only atomic operations performed on integers ("int" and "long", signed > > > > > +and unsigned) are supported on all architectures. Some architectures > > > > > +also support 1-byte and 2-byte atomic operations. Those respectively > > > > > +have UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT defined when > > > > > +uatomic.h is included. An architecture trying to perform an atomic write > > > > > +to a type size not supported by the architecture will trigger an illegal > > > > > +instruction. > > > > > + > > > > > +In the description below, "type" is a type that can be atomically > > > > > +written to by the architecture. It needs to be at most word-sized, and > > > > > +its alignment needs to greater or equal to its size. > > > > > + > > > > > +type uatomic_set(type *addr, type v) > > > > > + > > > > > + Atomically write @v into @addr. > > > > > > > > Wouldn't this instead be "void uatomic_set(type *addr, type v)"? > > > > > > Well, in that case, we'd need to change the macro. Currently, > > > _uatomic_set maps directly to: > > > > > > #define _uatomic_set(addr, v) CMM_STORE_SHARED(*(addr), (v)) > > > > > > and CMM_STORE_SHARED returns v. The question becomes: should we change > > > _uatomic_set or CMM_STORE_SHARED so they don't return anything, or > > > document that they return something ? > > > > > > One thing I noticed is that linters often complain that the return value > > > of CMM_STORE_SHARED is never used. One thing we could look into is to > > > try some gcc attributes and/or linter annotations to flag this return > > > value as possibly unused. Thoughts ? > > > > Hmmm... > > > > Does the following work? > > > > #define _uatomic_set(addr, v) ((void)CMM_STORE_SHARED(*(addr), (v))) > > Well, it would work, yes, but then we would not be consistent between > return values or no return values of: > > uatomic_set() > rcu_assign_pointer() > rcu_set_pointer() > > if you notice, in the Linux kernel, rcu_assign_pointer returns the > new pointer value. But you are right that atomic_set() does not return > anything. So which consistency would be best to keep ? Hmmm... I wonder how many people actually use rcu_assign_pointer()'s return value? If no one, I should make it a do-while(0). Although cscope does not show anything, I should probably put together a coccinelle script. Thanx, Paul > Thanks, > > Mathieu > > > > > > > > By "Atomically write @v into @addr", what is meant is that no concurrent > > > > operation that reads from addr will see partial effects of uatomic_set(), > > > > correct? In other words, the concurrent read will either see v or > > > > the old value, not a mush of the two. > > > > > > yep. I added that clarification. > > > > > > > > > > > > + > > > > > +type uatomic_read(type *addr) > > > > > + > > > > > + Atomically read @v from @addr. > > > > > > > > Similar comments on the meaning of "atomically". This may sound picky, > > > > but people coming from an x86 environment might otherwise assume that > > > > there is lock prefix involved... > > > > > > same. > > > > > > > > > > > > + > > > > > +type uatomic_cmpxchg(type *addr, type old, type new) > > > > > + > > > > > + Atomically check if @addr contains @old. If true, then replace > > > > > + the content of @addr by @new. Return the value previously > > > > > + contained by @addr. This function imply a full memory barrier > > > > > + before and after the atomic operation. > > > > > > > > Suggest "then atomically replace" or some such. It might not hurt > > > > to add that this is an atomic read-modify-write operation. > > > > > > Updated to: > > > > > > type uatomic_cmpxchg(type *addr, type old, type new) > > > > > > An atomic read-modify-write operation that performs this > > > sequence of operations atomically: check if @addr contains @old. > > > If true, then replace the content of @addr by @new. Return the > > > value previously contained by @addr. This function imply a full > > > memory barrier before and after the atomic operation. > > > > > > > > > > > Similar comments on the other value-returning atomics. > > > > > > Will do something similar. > > > > > > > > > > > > + > > > > > +type uatomic_xchg(type *addr, type new) > > > > > + > > > > > + Atomically replace the content of @addr by @new, and return the > > > > > + value previously contained by @addr. This function imply a full > > > > > + memory barrier before and after the atomic operation. > > > > > + > > > > > +type uatomic_add_return(type *addr, type v) > > > > > +type uatomic_sub_return(type *addr, type v) > > > > > + > > > > > + Atomically increment/decrement the content of @addr by @v, and > > > > > + return the resulting value. This function imply a full memory > > > > > + barrier before and after the atomic operation. > > > > > + > > > > > +void uatomic_and(type *addr, type mask) > > > > > +void uatomic_or(type *addr, type mask) > > > > > + > > > > > + Atomically write the result of bitwise "and"/"or" between the > > > > > + content of @addr and @mask into @addr. Memory barriers are > > > > > + provided by explicitly using cmm_smp_mb__before_uatomic_and(), > > > > > + cmm_smp_mb__after_uatomic_and(), > > > > > + cmm_smp_mb__before_uatomic_or(), and > > > > > + cmm_smp_mb__after_uatomic_or(). > > > > > > > > I suggest replacing "Memory barriers are provided ..." with something like > > > > "These operations do not necessarily imply memory barriers. If memory > > > > barriers are needed, they may be provided ...". Then perhaps add a > > > > sentence stating that the advantage of using the four __before_/__after_ > > > > primitives is that they are no-ops on architectures in which the underlying > > > > atomic instructions implicitly supply the needed memory barriers. > > > > > > > > Simlar comments on the other non-value-returning atomic operations below. > > > > > > OK, done. > > > > > > Here is the update: > > > > > > > > > diff --git a/doc/Makefile.am b/doc/Makefile.am > > > index 27d3793..3422653 100644 > > > --- a/doc/Makefile.am > > > +++ b/doc/Makefile.am > > > @@ -1 +1 @@ > > > -dist_doc_DATA = rcu-api.txt cds-api.txt > > > +dist_doc_DATA = rcu-api.txt cds-api.txt uatomic-api.txt > > > diff --git a/doc/uatomic-api.txt b/doc/uatomic-api.txt > > > new file mode 100644 > > > index 0000000..3ad8fbb > > > --- /dev/null > > > +++ b/doc/uatomic-api.txt > > > @@ -0,0 +1,102 @@ > > > +Userspace RCU Atomic Operations API > > > +by Mathieu Desnoyers and Paul E. McKenney > > > + > > > + > > > +This document describes the API. Those are the atomic > > > +operations provided by the Userspace RCU library. The general rule > > > +regarding memory barriers is that only uatomic_xchg(), > > > +uatomic_cmpxchg(), uatomic_add_return(), and uatomic_sub_return() imply > > > +full memory barriers before and after the atomic operation. Other > > > +primitives don't guarantee any memory barrier. > > > + > > > +Only atomic operations performed on integers ("int" and "long", signed > > > +and unsigned) are supported on all architectures. Some architectures > > > +also support 1-byte and 2-byte atomic operations. Those respectively > > > +have UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT defined when > > > +uatomic.h is included. An architecture trying to perform an atomic write > > > +to a type size not supported by the architecture will trigger an illegal > > > +instruction. > > > + > > > +In the description below, "type" is a type that can be atomically > > > +written to by the architecture. It needs to be at most word-sized, and > > > +its alignment needs to greater or equal to its size. > > > + > > > +type uatomic_set(type *addr, type v) > > > + > > > + Atomically write @v into @addr. By "atomically", we mean that no > > > + concurrent operation that reads from addr will see partial > > > + effects of uatomic_set(). > > > > Good clarification! > > > > If this is to return the value written, it should say so. (I would prefer > > no return, as this is the most common usage and the value written is easily > > available anyway.) > > > > > +type uatomic_read(type *addr) > > > + > > > + Atomically read @v from @addr. By "atomically", we mean that > > > + uatomic_read() cannot see a partial effect of any concurrent > > > + uatomic update. > > > + > > > +type uatomic_cmpxchg(type *addr, type old, type new) > > > + > > > + An atomic read-modify-write operation that performs this > > > + sequence of operations atomically: check if @addr contains @old. > > > + If true, then replace the content of @addr by @new. Return the > > > + value previously contained by @addr. This function imply a full > > > + memory barrier before and after the atomic operation. > > > > Good clarification! (And below as well.) > > > > > +type uatomic_xchg(type *addr, type new) > > > + > > > + An atomic read-modify-write operation that performs this sequence > > > + of operations atomically: replace the content of @addr by @new, > > > + and return the value previously contained by @addr. This > > > + function imply a full memory barrier before and after the atomic > > > + operation. > > > + > > > +type uatomic_add_return(type *addr, type v) > > > +type uatomic_sub_return(type *addr, type v) > > > + > > > + An atomic read-modify-write operation that performs this > > > + sequence of operations atomically: increment/decrement the > > > + content of @addr by @v, and return the resulting value. This > > > + function imply a full memory barrier before and after the atomic > > > + operation. > > > + > > > +void uatomic_and(type *addr, type mask) > > > +void uatomic_or(type *addr, type mask) > > > + > > > + Atomically write the result of bitwise "and"/"or" between the > > > + content of @addr and @mask into @addr. > > > + These operations do not necessarily imply memory barriers. > > > + If memory barriers are needed, they may be provided by > > > + explicitly using > > > + cmm_smp_mb__before_uatomic_and(), > > > + cmm_smp_mb__after_uatomic_and(), > > > + cmm_smp_mb__before_uatomic_or(), and > > > + cmm_smp_mb__after_uatomic_or(). These explicit barriers are > > > + np-ops on architectures in which the underlying atomic > > > + instructions implicitly supply the needed memory barriers. > > > > Good as well for these! > > > > Thanx, Paul > > > > > +void uatomic_add(type *addr, type v) > > > +void uatomic_sub(type *addr, type v) > > > + > > > + Atomically increment/decrement the content of @addr by @v. > > > + These operations do not necessarily imply memory barriers. > > > + If memory barriers are needed, they may be provided by > > > + explicitly using > > > + cmm_smp_mb__before_uatomic_add(), > > > + cmm_smp_mb__after_uatomic_add(), > > > + cmm_smp_mb__before_uatomic_sub(), and > > > + cmm_smp_mb__after_uatomic_sub(). These explicit barriers are > > > + np-ops on architectures in which the underlying atomic > > > + instructions implicitly supply the needed memory barriers. > > > + > > > +void uatomic_inc(type *addr) > > > +void uatomic_dec(type *addr) > > > + > > > + Atomically increment/decrement the content of @addr by 1. > > > + These operations do not necessarily imply memory barriers. > > > + If memory barriers are needed, they may be provided by > > > + explicitly using > > > + cmm_smp_mb__before_uatomic_inc(), > > > + cmm_smp_mb__after_uatomic_inc(), > > > + cmm_smp_mb__before_uatomic_dec(), and > > > + cmm_smp_mb__after_uatomic_dec(). These explicit barriers are > > > + np-ops on architectures in which the underlying atomic > > > + instructions implicitly supply the needed memory barriers. > > > > > > > > > -- > > > Mathieu Desnoyers > > > Operating System Efficiency R&D Consultant > > > EfficiOS Inc. > > > http://www.efficios.com > > > > > > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > rp mailing list > rp at svcs.cs.pdx.edu > http://svcs.cs.pdx.edu/mailman/listinfo/rp > From josh at joshtriplett.org Wed May 16 14:45:39 2012 From: josh at joshtriplett.org (Josh Triplett) Date: Wed, 16 May 2012 11:45:39 -0700 Subject: [lttng-dev] [rp] [RFC PATCH urcu] Document uatomic operations In-Reply-To: <20120516183238.GJ2441@linux.vnet.ibm.com> References: <20120515023901.GA22786@Krystal> <20120515040936.GB2412@linux.vnet.ibm.com> <20120515121003.GA31468@Krystal> <20120516171803.GB2441@linux.vnet.ibm.com> <20120516181742.GB16045@Krystal> <20120516183238.GJ2441@linux.vnet.ibm.com> Message-ID: <20120516184539.GB24507@leaf> On Wed, May 16, 2012 at 11:32:38AM -0700, Paul E. McKenney wrote: > On Wed, May 16, 2012 at 02:17:42PM -0400, Mathieu Desnoyers wrote: > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > On Tue, May 15, 2012 at 08:10:03AM -0400, Mathieu Desnoyers wrote: > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > On Mon, May 14, 2012 at 10:39:01PM -0400, Mathieu Desnoyers wrote: > > > > > > Document each atomic operation provided by urcu/uatomic.h, along with > > > > > > their memory barrier guarantees. > > > > > > > > > > Great to see the documentation!!! Some comments below. > > > > > > > > > > Thanx, Paul > > > > > > > > > > > Signed-off-by: Mathieu Desnoyers > > > > > > --- > > > > > > diff --git a/doc/Makefile.am b/doc/Makefile.am > > > > > > index bec1d7c..db9811c 100644 > > > > > > --- a/doc/Makefile.am > > > > > > +++ b/doc/Makefile.am > > > > > > @@ -1 +1 @@ > > > > > > -dist_doc_DATA = rcu-api.txt > > > > > > +dist_doc_DATA = rcu-api.txt uatomic-api.txt > > > > > > diff --git a/doc/uatomic-api.txt b/doc/uatomic-api.txt > > > > > > new file mode 100644 > > > > > > index 0000000..3605acf > > > > > > --- /dev/null > > > > > > +++ b/doc/uatomic-api.txt > > > > > > @@ -0,0 +1,80 @@ > > > > > > +Userspace RCU Atomic Operations API > > > > > > +by Mathieu Desnoyers and Paul E. McKenney > > > > > > + > > > > > > + > > > > > > +This document describes the API. Those are the atomic > > > > > > +operations provided by the Userspace RCU library. The general rule > > > > > > +regarding memory barriers is that only uatomic_xchg(), > > > > > > +uatomic_cmpxchg(), uatomic_add_return(), and uatomic_sub_return() imply > > > > > > +full memory barriers before and after the atomic operation. Other > > > > > > +primitives don't guarantee any memory barrier. > > > > > > + > > > > > > +Only atomic operations performed on integers ("int" and "long", signed > > > > > > +and unsigned) are supported on all architectures. Some architectures > > > > > > +also support 1-byte and 2-byte atomic operations. Those respectively > > > > > > +have UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT defined when > > > > > > +uatomic.h is included. An architecture trying to perform an atomic write > > > > > > +to a type size not supported by the architecture will trigger an illegal > > > > > > +instruction. > > > > > > + > > > > > > +In the description below, "type" is a type that can be atomically > > > > > > +written to by the architecture. It needs to be at most word-sized, and > > > > > > +its alignment needs to greater or equal to its size. > > > > > > + > > > > > > +type uatomic_set(type *addr, type v) > > > > > > + > > > > > > + Atomically write @v into @addr. > > > > > > > > > > Wouldn't this instead be "void uatomic_set(type *addr, type v)"? > > > > > > > > Well, in that case, we'd need to change the macro. Currently, > > > > _uatomic_set maps directly to: > > > > > > > > #define _uatomic_set(addr, v) CMM_STORE_SHARED(*(addr), (v)) > > > > > > > > and CMM_STORE_SHARED returns v. The question becomes: should we change > > > > _uatomic_set or CMM_STORE_SHARED so they don't return anything, or > > > > document that they return something ? > > > > > > > > One thing I noticed is that linters often complain that the return value > > > > of CMM_STORE_SHARED is never used. One thing we could look into is to > > > > try some gcc attributes and/or linter annotations to flag this return > > > > value as possibly unused. Thoughts ? > > > > > > Hmmm... > > > > > > Does the following work? > > > > > > #define _uatomic_set(addr, v) ((void)CMM_STORE_SHARED(*(addr), (v))) > > > > Well, it would work, yes, but then we would not be consistent between > > return values or no return values of: > > > > uatomic_set() > > rcu_assign_pointer() > > rcu_set_pointer() > > > > if you notice, in the Linux kernel, rcu_assign_pointer returns the > > new pointer value. But you are right that atomic_set() does not return > > anything. So which consistency would be best to keep ? > > Hmmm... I wonder how many people actually use rcu_assign_pointer()'s > return value? If no one, I should make it a do-while(0). Although > cscope does not show anything, I should probably put together a > coccinelle script. I just searched the entire Linux kernel with git grep '\S.*rcu_assign_pointer' (any non-whitespace preceding rcu_assign_pointer), and found no instances of anything assuming a return value from rcu_assign_pointer. I'd recommend making it void. - Josh Triplett From paulmck at linux.vnet.ibm.com Wed May 16 15:52:18 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Wed, 16 May 2012 12:52:18 -0700 Subject: [lttng-dev] [rp] [RFC PATCH urcu] Document uatomic operations In-Reply-To: <20120516184539.GB24507@leaf> References: <20120515023901.GA22786@Krystal> <20120515040936.GB2412@linux.vnet.ibm.com> <20120515121003.GA31468@Krystal> <20120516171803.GB2441@linux.vnet.ibm.com> <20120516181742.GB16045@Krystal> <20120516183238.GJ2441@linux.vnet.ibm.com> <20120516184539.GB24507@leaf> Message-ID: <20120516195217.GK2441@linux.vnet.ibm.com> On Wed, May 16, 2012 at 11:45:39AM -0700, Josh Triplett wrote: > On Wed, May 16, 2012 at 11:32:38AM -0700, Paul E. McKenney wrote: > > On Wed, May 16, 2012 at 02:17:42PM -0400, Mathieu Desnoyers wrote: > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > On Tue, May 15, 2012 at 08:10:03AM -0400, Mathieu Desnoyers wrote: > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > > On Mon, May 14, 2012 at 10:39:01PM -0400, Mathieu Desnoyers wrote: > > > > > > > Document each atomic operation provided by urcu/uatomic.h, along with > > > > > > > their memory barrier guarantees. > > > > > > > > > > > > Great to see the documentation!!! Some comments below. > > > > > > > > > > > > Thanx, Paul > > > > > > > > > > > > > Signed-off-by: Mathieu Desnoyers > > > > > > > --- > > > > > > > diff --git a/doc/Makefile.am b/doc/Makefile.am > > > > > > > index bec1d7c..db9811c 100644 > > > > > > > --- a/doc/Makefile.am > > > > > > > +++ b/doc/Makefile.am > > > > > > > @@ -1 +1 @@ > > > > > > > -dist_doc_DATA = rcu-api.txt > > > > > > > +dist_doc_DATA = rcu-api.txt uatomic-api.txt > > > > > > > diff --git a/doc/uatomic-api.txt b/doc/uatomic-api.txt > > > > > > > new file mode 100644 > > > > > > > index 0000000..3605acf > > > > > > > --- /dev/null > > > > > > > +++ b/doc/uatomic-api.txt > > > > > > > @@ -0,0 +1,80 @@ > > > > > > > +Userspace RCU Atomic Operations API > > > > > > > +by Mathieu Desnoyers and Paul E. McKenney > > > > > > > + > > > > > > > + > > > > > > > +This document describes the API. Those are the atomic > > > > > > > +operations provided by the Userspace RCU library. The general rule > > > > > > > +regarding memory barriers is that only uatomic_xchg(), > > > > > > > +uatomic_cmpxchg(), uatomic_add_return(), and uatomic_sub_return() imply > > > > > > > +full memory barriers before and after the atomic operation. Other > > > > > > > +primitives don't guarantee any memory barrier. > > > > > > > + > > > > > > > +Only atomic operations performed on integers ("int" and "long", signed > > > > > > > +and unsigned) are supported on all architectures. Some architectures > > > > > > > +also support 1-byte and 2-byte atomic operations. Those respectively > > > > > > > +have UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT defined when > > > > > > > +uatomic.h is included. An architecture trying to perform an atomic write > > > > > > > +to a type size not supported by the architecture will trigger an illegal > > > > > > > +instruction. > > > > > > > + > > > > > > > +In the description below, "type" is a type that can be atomically > > > > > > > +written to by the architecture. It needs to be at most word-sized, and > > > > > > > +its alignment needs to greater or equal to its size. > > > > > > > + > > > > > > > +type uatomic_set(type *addr, type v) > > > > > > > + > > > > > > > + Atomically write @v into @addr. > > > > > > > > > > > > Wouldn't this instead be "void uatomic_set(type *addr, type v)"? > > > > > > > > > > Well, in that case, we'd need to change the macro. Currently, > > > > > _uatomic_set maps directly to: > > > > > > > > > > #define _uatomic_set(addr, v) CMM_STORE_SHARED(*(addr), (v)) > > > > > > > > > > and CMM_STORE_SHARED returns v. The question becomes: should we change > > > > > _uatomic_set or CMM_STORE_SHARED so they don't return anything, or > > > > > document that they return something ? > > > > > > > > > > One thing I noticed is that linters often complain that the return value > > > > > of CMM_STORE_SHARED is never used. One thing we could look into is to > > > > > try some gcc attributes and/or linter annotations to flag this return > > > > > value as possibly unused. Thoughts ? > > > > > > > > Hmmm... > > > > > > > > Does the following work? > > > > > > > > #define _uatomic_set(addr, v) ((void)CMM_STORE_SHARED(*(addr), (v))) > > > > > > Well, it would work, yes, but then we would not be consistent between > > > return values or no return values of: > > > > > > uatomic_set() > > > rcu_assign_pointer() > > > rcu_set_pointer() > > > > > > if you notice, in the Linux kernel, rcu_assign_pointer returns the > > > new pointer value. But you are right that atomic_set() does not return > > > anything. So which consistency would be best to keep ? > > > > Hmmm... I wonder how many people actually use rcu_assign_pointer()'s > > return value? If no one, I should make it a do-while(0). Although > > cscope does not show anything, I should probably put together a > > coccinelle script. > > I just searched the entire Linux kernel with git grep > '\S.*rcu_assign_pointer' (any non-whitespace preceding > rcu_assign_pointer), and found no instances of anything assuming a > return value from rcu_assign_pointer. I'd recommend making it void. Woo-hoo!!! Thank you both!!! Thanx, Paul From alexandre.montplaisir at polymtl.ca Thu May 17 10:25:02 2012 From: alexandre.montplaisir at polymtl.ca (Alexandre Montplaisir) Date: Thu, 17 May 2012 10:25:02 -0400 Subject: [lttng-dev] HOW TO DOWNLOAD LTTng 2.0 stable? In-Reply-To: References: <4FB3EDC0.7080006@polymtl.ca> Message-ID: <4FB50A3E.7030508@polymtl.ca> This is an interesting problem, I'll forward it to the mailing list. On 12-05-17 10:02 AM, Vanni Genua wrote: > Also why I get this error? > see the attached log file. > Best regards. > V.G. > > localhost lttng-ust-2.0.1 # ./configure checking build system type... armv7l-unknown-linux-gnueabi checking host system type... armv7l-unknown-linux-gnueabi checking target system type... armv7l-unknown-linux-gnueabi checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for a thread-safe mkdir -p... /bin/mkdir -p checking for gawk... gawk checking whether make sets $(MAKE)... yes checking whether make supports nested variables... yes checking for a sed that does not truncate output... /bin/sed checking for gcc... gcc checking whether the C compiler works... yes checking for C compiler default output file name... a.out checking for suffix of executables... checking whether we are cross compiling... no checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether gcc accepts -g... yes checking for gcc option to accept ISO C89... none needed checking for style of include used by make... GNU checking dependency style of gcc... gcc3 checking for g++... g++ checking whether we are using the GNU C++ compiler... yes checking whether g++ accepts -g... yes checking dependency style of g++... gcc3 checking whether make sets $(MAKE)... (cached) yes checking how to print strings... printf checking for a sed that does not truncate output... (cached) /bin/sed checking for grep that handles long lines and -e... /bin/grep checking for egrep... /bin/grep -E checking for fgrep... /bin/grep -F checking for ld used by gcc... /usr/armv7a-unknown-linux-gnueabi/bin/ld checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is GNU ld... yes checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B checking the name lister (/usr/bin/nm -B) interface... BSD nm checking whether ln -s works... yes checking the maximum length of command line arguments... 1572864 checking whether the shell understands some XSI constructs... yes checking whether the shell understands "+="... yes checking how to convert armv7l-unknown-linux-gnueabi file names to armv7l-unknown-linux-gnueabi format... func_convert_file_noop checking how to convert armv7l-unknown-linux-gnueabi file names to toolchain format... func_convert_file_noop checking for /usr/armv7a-unknown-linux-gnueabi/bin/ld option to reload object files... -r checking for objdump... objdump checking how to recognize dependent libraries... pass_all checking for dlltool... no checking how to associate runtime and link libraries... printf %s\n checking for ar... ar checking for archiver @FILE support... @ checking for strip... strip checking for ranlib... ranlib checking command to parse /usr/bin/nm -B output from gcc object... ok checking for sysroot... no checking for mt... no checking if : is a manifest tool... no checking how to run the C preprocessor... gcc -E checking for ANSI C header files... yes checking for sys/types.h... yes checking for sys/stat.h... yes checking for stdlib.h... yes checking for string.h... yes checking for memory.h... yes checking for strings.h... yes checking for inttypes.h... yes checking for stdint.h... yes checking for unistd.h... yes checking for dlfcn.h... yes checking for objdir... .libs checking if gcc supports -fno-rtti -fno-exceptions... no checking for gcc option to produce PIC... -fPIC -DPIC checking if gcc PIC flag -fPIC -DPIC works... yes checking if gcc static flag -static works... yes checking if gcc supports -c -o file.o... yes checking if gcc supports -c -o file.o... (cached) yes checking whether the gcc linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... yes checking whether -lc should be explicitly linked in... no checking dynamic linker characteristics... GNU/Linux ld.so checking how to hardcode library paths into programs... immediate checking whether stripping libraries is possible... yes checking if libtool supports shared libraries... yes checking whether to build shared libraries... yes checking whether to build static libraries... yes checking how to run the C++ preprocessor... g++ -E checking for ld used by g++... /usr/armv7a-unknown-linux-gnueabi/bin/ld checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is GNU ld... yes checking whether the g++ linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... yes checking for g++ option to produce PIC... -fPIC -DPIC checking if g++ PIC flag -fPIC -DPIC works... yes checking if g++ static flag -static works... yes checking if g++ supports -c -o file.o... yes checking if g++ supports -c -o file.o... (cached) yes checking whether the g++ linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... yes checking dynamic linker characteristics... (cached) GNU/Linux ld.so checking how to hardcode library paths into programs... immediate checking for dlopen in -ldl... yes checking for pthread_create in -lpthread... yes checking for uuid_generate in -luuid... yes checking for inline... inline checking for stdlib.h... (cached) yes checking for GNU libc compatible malloc... yes checking for gettimeofday... yes checking for munmap... yes checking for socket... yes checking for strerror... yes checking for strtol... yes checking for sched_getcpu... yes checking for sysconf... yes checking for makeinfo... yes checking urcu-bp.h usability... yes checking urcu-bp.h presence... yes checking for urcu-bp.h... yes checking caa_likely()... yes checking for synchronize_rcu_bp in -lurcu-bp... yes checking for call_rcu_bp in -lurcu-bp... yes checking library format for the host system... configure: error: unable to detect library format (unsupported architecture (armv7l)?) From mathieu.desnoyers at efficios.com Thu May 17 10:30:31 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 17 May 2012 10:30:31 -0400 Subject: [lttng-dev] HOW TO DOWNLOAD LTTng 2.0 stable? In-Reply-To: <4FB50A3E.7030508@polymtl.ca> References: <4FB3EDC0.7080006@polymtl.ca> <4FB50A3E.7030508@polymtl.ca> Message-ID: <20120517143031.GA30839@Krystal> * Alexandre Montplaisir (alexandre.montplaisir at polymtl.ca) wrote: > This is an interesting problem, I'll forward it to the mailing list. > > > On 12-05-17 10:02 AM, Vanni Genua wrote: > > Also why I get this error? > > see the attached log file. > > Best regards. > > V.G. > > > > > > localhost lttng-ust-2.0.1 # ./configure > checking build system type... armv7l-unknown-linux-gnueabi > checking host system type... armv7l-unknown-linux-gnueabi > checking target system type... armv7l-unknown-linux-gnueabi > checking for a BSD-compatible install... /usr/bin/install -c > checking whether build environment is sane... yes > checking for a thread-safe mkdir -p... /bin/mkdir -p > checking for gawk... gawk > checking whether make sets $(MAKE)... yes > checking whether make supports nested variables... yes > checking for a sed that does not truncate output... /bin/sed > checking for gcc... gcc > checking whether the C compiler works... yes > checking for C compiler default output file name... a.out > checking for suffix of executables... > checking whether we are cross compiling... no > checking for suffix of object files... o > checking whether we are using the GNU C compiler... yes > checking whether gcc accepts -g... yes > checking for gcc option to accept ISO C89... none needed > checking for style of include used by make... GNU > checking dependency style of gcc... gcc3 > checking for g++... g++ > checking whether we are using the GNU C++ compiler... yes > checking whether g++ accepts -g... yes > checking dependency style of g++... gcc3 > checking whether make sets $(MAKE)... (cached) yes > checking how to print strings... printf > checking for a sed that does not truncate output... (cached) /bin/sed > checking for grep that handles long lines and -e... /bin/grep > checking for egrep... /bin/grep -E > checking for fgrep... /bin/grep -F > checking for ld used by gcc... /usr/armv7a-unknown-linux-gnueabi/bin/ld > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is GNU ld... yes > checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B > checking the name lister (/usr/bin/nm -B) interface... BSD nm > checking whether ln -s works... yes > checking the maximum length of command line arguments... 1572864 > checking whether the shell understands some XSI constructs... yes > checking whether the shell understands "+="... yes > checking how to convert armv7l-unknown-linux-gnueabi file names to armv7l-unknown-linux-gnueabi format... func_convert_file_noop > checking how to convert armv7l-unknown-linux-gnueabi file names to toolchain format... func_convert_file_noop > checking for /usr/armv7a-unknown-linux-gnueabi/bin/ld option to reload object files... -r > checking for objdump... objdump > checking how to recognize dependent libraries... pass_all > checking for dlltool... no > checking how to associate runtime and link libraries... printf %s\n > checking for ar... ar > checking for archiver @FILE support... @ > checking for strip... strip > checking for ranlib... ranlib > checking command to parse /usr/bin/nm -B output from gcc object... ok > checking for sysroot... no > checking for mt... no > checking if : is a manifest tool... no > checking how to run the C preprocessor... gcc -E > checking for ANSI C header files... yes > checking for sys/types.h... yes > checking for sys/stat.h... yes > checking for stdlib.h... yes > checking for string.h... yes > checking for memory.h... yes > checking for strings.h... yes > checking for inttypes.h... yes > checking for stdint.h... yes > checking for unistd.h... yes > checking for dlfcn.h... yes > checking for objdir... .libs > checking if gcc supports -fno-rtti -fno-exceptions... no > checking for gcc option to produce PIC... -fPIC -DPIC > checking if gcc PIC flag -fPIC -DPIC works... yes > checking if gcc static flag -static works... yes > checking if gcc supports -c -o file.o... yes > checking if gcc supports -c -o file.o... (cached) yes > checking whether the gcc linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... yes > checking whether -lc should be explicitly linked in... no > checking dynamic linker characteristics... GNU/Linux ld.so > checking how to hardcode library paths into programs... immediate > checking whether stripping libraries is possible... yes > checking if libtool supports shared libraries... yes > checking whether to build shared libraries... yes > checking whether to build static libraries... yes > checking how to run the C++ preprocessor... g++ -E > checking for ld used by g++... /usr/armv7a-unknown-linux-gnueabi/bin/ld > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is GNU ld... yes > checking whether the g++ linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... yes > checking for g++ option to produce PIC... -fPIC -DPIC > checking if g++ PIC flag -fPIC -DPIC works... yes > checking if g++ static flag -static works... yes > checking if g++ supports -c -o file.o... yes > checking if g++ supports -c -o file.o... (cached) yes > checking whether the g++ linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... yes > checking dynamic linker characteristics... (cached) GNU/Linux ld.so > checking how to hardcode library paths into programs... immediate > checking for dlopen in -ldl... yes > checking for pthread_create in -lpthread... yes > checking for uuid_generate in -luuid... yes > checking for inline... inline > checking for stdlib.h... (cached) yes > checking for GNU libc compatible malloc... yes > checking for gettimeofday... yes > checking for munmap... yes > checking for socket... yes > checking for strerror... yes > checking for strtol... yes > checking for sched_getcpu... yes > checking for sysconf... yes > checking for makeinfo... yes > checking urcu-bp.h usability... yes > checking urcu-bp.h presence... yes > checking for urcu-bp.h... yes > checking caa_likely()... yes > checking for synchronize_rcu_bp in -lurcu-bp... yes > checking for call_rcu_bp in -lurcu-bp... yes > checking library format for the host system... configure: error: unable to detect library format (unsupported architecture (armv7l)?) Does it help if you add a line: armv7l) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; near line 188 of configure.ac ? What we did in userspace RCU is to use "arm*". Thanks, Mathieu > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Thu May 17 12:43:36 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 17 May 2012 12:43:36 -0400 Subject: [lttng-dev] HOW TO DOWNLOAD LTTng 2.0 stable? In-Reply-To: References: <4FB3EDC0.7080006@polymtl.ca> <4FB50A3E.7030508@polymtl.ca> <20120517143031.GA30839@Krystal> Message-ID: <20120517164336.GA32730@Krystal> Please use "reply to all". Thank you, Mathieu * Vanni Genua (vannigenua at gmail.com) wrote: > I did it a minute ago, now the problems are the undefined references at the > end of this logs: > > localhost lttng-ust-2.0.1 # ./configure > --build=armv7a-unknown-linux-gnueabi > > checking build system type... > armv7a-unknown-linux-gnueabi > > checking host system type... > armv7a-unknown-linux-gnueabi > > checking target system type... > armv7a-unknown-linux-gnueabi > > checking for a BSD-compatible install... /usr/bin/install > -c > > checking whether build environment is sane... > yes > > checking for a thread-safe mkdir -p... /bin/mkdir > -p > > checking for gawk... > gawk > > checking whether make sets $(MAKE)... > yes > > checking whether make supports nested variables... > yes > > checking for a sed that does not truncate output... > /bin/sed > > checking for gcc... > gcc > > checking whether the C compiler works... > yes > > checking for C compiler default output file name... > a.out > > checking for suffix of > executables... > > checking whether we are cross compiling... > no > > checking for suffix of object files... > o > > checking whether we are using the GNU C compiler... > yes > > checking whether gcc accepts -g... > yes > > checking for gcc option to accept ISO C89... none > needed > > checking for style of include used by make... > GNU > > checking dependency style of gcc... > gcc3 > > checking for g++... > g++ > > checking whether we are using the GNU C++ compiler... > yes > > checking whether g++ accepts -g... > yes > > checking dependency style of g++... > gcc3 > > checking whether make sets $(MAKE)... (cached) > yes > > checking how to print strings... > printf > > checking for a sed that does not truncate output... (cached) > /bin/sed > > checking for grep that handles long lines and -e... > /bin/grep > > checking for egrep... /bin/grep > -E > > checking for fgrep... /bin/grep > -F > > checking for ld used by gcc... > /usr/armv7a-unknown-linux-gnueabi/bin/ld > > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is GNU > ld... > yes > checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm > -B > > checking the name lister (/usr/bin/nm -B) interface... BSD > nm > > checking whether ln -s works... > yes > > checking the maximum length of command line arguments... > 1572864 > > checking whether the shell understands some XSI constructs... > yes > > checking whether the shell understands "+="... > yes > > checking how to convert armv7a-unknown-linux-gnueabi file names to > armv7a-unknown-linux-gnueabi format... > func_convert_file_noop > checking how to convert armv7a-unknown-linux-gnueabi file names to > toolchain format... > func_convert_file_noop > checking for /usr/armv7a-unknown-linux-gnueabi/bin/ld option to reload > object files... > -r > checking for objdump... > objdump > > checking how to recognize dependent libraries... > pass_all > > checking for dlltool... > no > > checking how to associate runtime and link libraries... printf > %s\n > > checking for ar... > ar > > checking for archiver @FILE support... > @ > > checking for strip... > strip > > checking for ranlib... > ranlib > > checking command to parse /usr/bin/nm -B output from gcc object... > ok > > checking for sysroot... > no > > checking for mt... > no > > checking if : is a manifest tool... > no > > checking how to run the C preprocessor... gcc > -E > > checking for ANSI C header files... > yes > > checking for sys/types.h... > yes > > checking for sys/stat.h... > yes > > checking for stdlib.h... > yes > > checking for string.h... > yes > > checking for memory.h... > yes > > checking for strings.h... > yes > > checking for inttypes.h... > yes > > checking for stdint.h... > yes > > checking for unistd.h... > yes > > checking for dlfcn.h... > yes > > checking for objdir... > .libs > > checking if gcc supports -fno-rtti -fno-exceptions... > no > > checking for gcc option to produce PIC... -fPIC > -DPIC > > checking if gcc PIC flag -fPIC -DPIC works... > yes > > checking if gcc static flag -static works... > yes > > checking if gcc supports -c -o file.o... > yes > > checking if gcc supports -c -o file.o... (cached) > yes > > checking whether the gcc linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) > supports shared libraries... > yes > checking whether -lc should be explicitly linked in... > no > > checking dynamic linker characteristics... GNU/Linux > ld.so > > checking how to hardcode library paths into programs... > immediate > > checking whether stripping libraries is possible... > yes > > checking if libtool supports shared libraries... > yes > > checking whether to build shared libraries... > yes > > checking whether to build static libraries... > yes > > checking how to run the C++ preprocessor... g++ > -E > > checking for ld used by g++... > /usr/armv7a-unknown-linux-gnueabi/bin/ld > > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is GNU > ld... > yes > checking whether the g++ linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) > supports shared libraries... > yes > checking for g++ option to produce PIC... -fPIC > -DPIC > > checking if g++ PIC flag -fPIC -DPIC works... > yes > > checking if g++ static flag -static works... > yes > > checking if g++ supports -c -o file.o... > yes > > checking if g++ supports -c -o file.o... (cached) > yes > > checking whether the g++ linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) > supports shared libraries... > yes > checking dynamic linker characteristics... (cached) GNU/Linux > ld.so > > checking how to hardcode library paths into programs... > immediate > > checking for dlopen in -ldl... > yes > > checking for pthread_create in -lpthread... > yes > > checking for uuid_generate in -luuid... > yes > > checking for inline... > inline > > checking for stdlib.h... (cached) > yes > > checking for GNU libc compatible malloc... > yes > > checking for gettimeofday... > yes > > checking for munmap... > yes > > checking for socket... > yes > > checking for strerror... > yes > > checking for strtol... > yes > > checking for sched_getcpu... > yes > > checking for sysconf... > yes > > checking for makeinfo... > yes > > checking urcu-bp.h usability... > yes > > checking urcu-bp.h presence... > yes > > checking for urcu-bp.h... > yes > > checking caa_likely()... > yes > > checking for synchronize_rcu_bp in -lurcu-bp... > yes > > checking for call_rcu_bp in -lurcu-bp... > yes > > checking library format for the host system... > elf32-littlearm > > configure: creating > ./config.status > > config.status: creating > Makefile > > config.status: creating > doc/Makefile > > config.status: creating > doc/examples/Makefile > > config.status: creating > include/Makefile > > config.status: creating > include/lttng/ust-version.h > > config.status: creating > snprintf/Makefile > > config.status: creating > libringbuffer/Makefile > > config.status: creating > liblttng-ust-comm/Makefile > > config.status: creating > liblttng-ust/Makefile > > config.status: creating > liblttng-ust-ctl/Makefile > > config.status: creating > liblttng-ust-fork/Makefile > > config.status: creating > liblttng-ust-java/Makefile > > config.status: creating > liblttng-ust-libc-wrapper/Makefile > > config.status: creating > tools/Makefile > > config.status: creating > tests/Makefile > > config.status: creating > tests/hello/Makefile > > config.status: creating > tests/hello-static-lib/Makefile > > config.status: creating > tests/hello.cxx/Makefile > > config.status: creating > tests/demo/Makefile > > config.status: creating > tests/fork/Makefile > > config.status: creating > tests/ust-basic-tracing/Makefile > > config.status: creating > tests/ust-multi-test/Makefile > > config.status: creating > lttng-ust.pc > > config.status: creating > config.h > > config.status: config.h is > unchanged > > config.status: creating > include/lttng/ust-config.h > > config.status: include/lttng/ust-config.h is > unchanged > > config.status: executing depfiles > commands > > config.status: executing libtool > commands > > > > Version name: > Annedd'ale > > New type of beer, 100% from Quebec, flavored with sapin beaumier needles, > with a touch of > hops. > > > LTTng-UST will be built with the following > options: > > Library format: > elf32-littlearm > > > > Java support (JNI): > Disabled > > sdt.h integration: > Disabled > > > > Type 'make' to > compile. > > localhost lttng-ust-2.0.1 # > make > > make > all-recursive > > make[1]: Entering directory > `/usr/src/lttng-ust-2.0.1' > > Making all in > . > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1' > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1' > > Making all in > include > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/include' > > make[2]: Nothing to be done for > `all'. > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/include' > > Making all in > snprintf > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/snprintf' > > make[2]: Nothing to be done for > `all'. > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/snprintf' > > Making all in > libringbuffer > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/libringbuffer' > > CC > libringbuffer_la-ring_buffer_backend.lo > > CC > libringbuffer_la-ring_buffer_frontend.lo > > CCLD libringbuffer.la > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/libringbuffer' > > Making all in > liblttng-ust-comm > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' > > make[2]: Nothing to be done for > `all'. > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' > > Making all in > liblttng-ust > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust' > > CC > liblttng_ust_tracepoint_la-tracepoint.lo > > CCLD liblttng-ust-tracepoint.la > > CC > lttng-ust-comm.lo > > CC > lttng-ust-abi.lo > > CC > ltt-probes.lo > > CC > lttng-probe-ust.lo > > CC > lttng-context-vtid.lo > > CC > lttng-context-vpid.lo > > CC > lttng-context-pthread-id.lo > > CC > lttng-context-procname.lo > > CC > ltt-context.lo > > CC > ltt-events.lo > > CCLD liblttng-ust-runtime.la > > CC > ust-core.lo > > CC > ltt-ring-buffer-client-discard.lo > > CC > ltt-ring-buffer-client-overwrite.lo > > CC > ltt-ring-buffer-metadata-client.lo > > CCLD liblttng-ust-support.la > > CCLD liblttng-ust.la > > /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/../../../../armv7a-unknown-linux-gnueabi/bin/ld: > warning: creating a DT_TEXTREL in object. > copying selected object files to avoid basename > conflicts... > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust' > > Making all in > liblttng-ust-ctl > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' > > CC > ustctl.lo > > CCLD liblttng-ust-ctl.la > > /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/../../../../armv7a-unknown-linux-gnueabi/bin/ld: > warning: creating a DT_TEXTREL in object. > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' > > Making all in > liblttng-ust-fork > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' > > CCLD liblttng-ust-fork.la > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' > > Making all in > liblttng-ust-libc-wrapper > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' > > CC > lttng-ust-malloc.lo > > CCLD liblttng-ust-libc-wrapper.la > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' > > Making all in > tools > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/tools' > > make[2]: Nothing to be done for > `all'. > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/tools' > > Making all in > tests > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/tests' > > Making all in > . > > make[3]: Entering directory > `/usr/src/lttng-ust-2.0.1/tests' > > make[3]: Nothing to be done for > `all-am'. > > make[3]: Leaving directory > `/usr/src/lttng-ust-2.0.1/tests' > > Making all in > hello > > make[3]: Entering directory > `/usr/src/lttng-ust-2.0.1/tests/hello' > > CC > tp.o > > CCLD > hello > > ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > `__num_possible_cpus' > > ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > `shm_object_table_create' > > ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > `shm_object_table_append_shadow' > > ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > `shm_object_table_append' > > ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > `zalloc_shm' > > ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > `_get_num_possible_cpus' > > ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > `align_shm' > > ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > `shm_object_table_destroy' > > collect2: ld returned 1 exit > status > > make[3]: *** [hello] Error > 1 > > make[3]: Leaving directory > `/usr/src/lttng-ust-2.0.1/tests/hello' > > make[2]: *** [all-recursive] Error > 1 > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/tests' > > make[1]: *** [all-recursive] Error > 1 > > make[1]: Leaving directory > `/usr/src/lttng-ust-2.0.1' > > make: *** [all] Error > 2 > > localhost lttng-ust-2.0.1 # > > > On Thu, May 17, 2012 at 2:30 PM, Mathieu Desnoyers < > mathieu.desnoyers at efficios.com> wrote: > > > * Alexandre Montplaisir (alexandre.montplaisir at polymtl.ca) wrote: > > > This is an interesting problem, I'll forward it to the mailing list. > > > > > > > > > On 12-05-17 10:02 AM, Vanni Genua wrote: > > > > Also why I get this error? > > > > see the attached log file. > > > > Best regards. > > > > V.G. > > > > > > > > > > > > > > localhost lttng-ust-2.0.1 # ./configure > > > checking build system type... armv7l-unknown-linux-gnueabi > > > checking host system type... armv7l-unknown-linux-gnueabi > > > checking target system type... armv7l-unknown-linux-gnueabi > > > checking for a BSD-compatible install... /usr/bin/install -c > > > checking whether build environment is sane... yes > > > checking for a thread-safe mkdir -p... /bin/mkdir -p > > > checking for gawk... gawk > > > checking whether make sets $(MAKE)... yes > > > checking whether make supports nested variables... yes > > > checking for a sed that does not truncate output... /bin/sed > > > checking for gcc... gcc > > > checking whether the C compiler works... yes > > > checking for C compiler default output file name... a.out > > > checking for suffix of executables... > > > checking whether we are cross compiling... no > > > checking for suffix of object files... o > > > checking whether we are using the GNU C compiler... yes > > > checking whether gcc accepts -g... yes > > > checking for gcc option to accept ISO C89... none needed > > > checking for style of include used by make... GNU > > > checking dependency style of gcc... gcc3 > > > checking for g++... g++ > > > checking whether we are using the GNU C++ compiler... yes > > > checking whether g++ accepts -g... yes > > > checking dependency style of g++... gcc3 > > > checking whether make sets $(MAKE)... (cached) yes > > > checking how to print strings... printf > > > checking for a sed that does not truncate output... (cached) /bin/sed > > > checking for grep that handles long lines and -e... /bin/grep > > > checking for egrep... /bin/grep -E > > > checking for fgrep... /bin/grep -F > > > checking for ld used by gcc... /usr/armv7a-unknown-linux-gnueabi/bin/ld > > > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is GNU > > ld... yes > > > checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B > > > checking the name lister (/usr/bin/nm -B) interface... BSD nm > > > checking whether ln -s works... yes > > > checking the maximum length of command line arguments... 1572864 > > > checking whether the shell understands some XSI constructs... yes > > > checking whether the shell understands "+="... yes > > > checking how to convert armv7l-unknown-linux-gnueabi file names to > > armv7l-unknown-linux-gnueabi format... func_convert_file_noop > > > checking how to convert armv7l-unknown-linux-gnueabi file names to > > toolchain format... func_convert_file_noop > > > checking for /usr/armv7a-unknown-linux-gnueabi/bin/ld option to reload > > object files... -r > > > checking for objdump... objdump > > > checking how to recognize dependent libraries... pass_all > > > checking for dlltool... no > > > checking how to associate runtime and link libraries... printf %s\n > > > checking for ar... ar > > > checking for archiver @FILE support... @ > > > checking for strip... strip > > > checking for ranlib... ranlib > > > checking command to parse /usr/bin/nm -B output from gcc object... ok > > > checking for sysroot... no > > > checking for mt... no > > > checking if : is a manifest tool... no > > > checking how to run the C preprocessor... gcc -E > > > checking for ANSI C header files... yes > > > checking for sys/types.h... yes > > > checking for sys/stat.h... yes > > > checking for stdlib.h... yes > > > checking for string.h... yes > > > checking for memory.h... yes > > > checking for strings.h... yes > > > checking for inttypes.h... yes > > > checking for stdint.h... yes > > > checking for unistd.h... yes > > > checking for dlfcn.h... yes > > > checking for objdir... .libs > > > checking if gcc supports -fno-rtti -fno-exceptions... no > > > checking for gcc option to produce PIC... -fPIC -DPIC > > > checking if gcc PIC flag -fPIC -DPIC works... yes > > > checking if gcc static flag -static works... yes > > > checking if gcc supports -c -o file.o... yes > > > checking if gcc supports -c -o file.o... (cached) yes > > > checking whether the gcc linker > > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... yes > > > checking whether -lc should be explicitly linked in... no > > > checking dynamic linker characteristics... GNU/Linux ld.so > > > checking how to hardcode library paths into programs... immediate > > > checking whether stripping libraries is possible... yes > > > checking if libtool supports shared libraries... yes > > > checking whether to build shared libraries... yes > > > checking whether to build static libraries... yes > > > checking how to run the C++ preprocessor... g++ -E > > > checking for ld used by g++... /usr/armv7a-unknown-linux-gnueabi/bin/ld > > > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is GNU > > ld... yes > > > checking whether the g++ linker > > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... yes > > > checking for g++ option to produce PIC... -fPIC -DPIC > > > checking if g++ PIC flag -fPIC -DPIC works... yes > > > checking if g++ static flag -static works... yes > > > checking if g++ supports -c -o file.o... yes > > > checking if g++ supports -c -o file.o... (cached) yes > > > checking whether the g++ linker > > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... yes > > > checking dynamic linker characteristics... (cached) GNU/Linux ld.so > > > checking how to hardcode library paths into programs... immediate > > > checking for dlopen in -ldl... yes > > > checking for pthread_create in -lpthread... yes > > > checking for uuid_generate in -luuid... yes > > > checking for inline... inline > > > checking for stdlib.h... (cached) yes > > > checking for GNU libc compatible malloc... yes > > > checking for gettimeofday... yes > > > checking for munmap... yes > > > checking for socket... yes > > > checking for strerror... yes > > > checking for strtol... yes > > > checking for sched_getcpu... yes > > > checking for sysconf... yes > > > checking for makeinfo... yes > > > checking urcu-bp.h usability... yes > > > checking urcu-bp.h presence... yes > > > checking for urcu-bp.h... yes > > > checking caa_likely()... yes > > > checking for synchronize_rcu_bp in -lurcu-bp... yes > > > checking for call_rcu_bp in -lurcu-bp... yes > > > checking library format for the host system... configure: error: unable > > to detect library format (unsupported architecture (armv7l)?) > > > > Does it help if you add a line: > > > > armv7l) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; > > > > near line 188 of configure.ac ? > > > > What we did in userspace RCU is to use "arm*". > > > > Thanks, > > > > Mathieu > > > > > > > > > > > _______________________________________________ > > > lttng-dev mailing list > > > lttng-dev at lists.lttng.org > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Thu May 17 13:59:43 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 17 May 2012 13:59:43 -0400 Subject: [lttng-dev] [rp] [RFC PATCH urcu] Document uatomic operations In-Reply-To: <20120516195217.GK2441@linux.vnet.ibm.com> References: <20120515023901.GA22786@Krystal> <20120515040936.GB2412@linux.vnet.ibm.com> <20120515121003.GA31468@Krystal> <20120516171803.GB2441@linux.vnet.ibm.com> <20120516181742.GB16045@Krystal> <20120516183238.GJ2441@linux.vnet.ibm.com> <20120516184539.GB24507@leaf> <20120516195217.GK2441@linux.vnet.ibm.com> Message-ID: <20120517175943.GA824@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > On Wed, May 16, 2012 at 11:45:39AM -0700, Josh Triplett wrote: > > On Wed, May 16, 2012 at 11:32:38AM -0700, Paul E. McKenney wrote: > > > On Wed, May 16, 2012 at 02:17:42PM -0400, Mathieu Desnoyers wrote: > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > On Tue, May 15, 2012 at 08:10:03AM -0400, Mathieu Desnoyers wrote: > > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > > > On Mon, May 14, 2012 at 10:39:01PM -0400, Mathieu Desnoyers wrote: > > > > > > > > Document each atomic operation provided by urcu/uatomic.h, along with > > > > > > > > their memory barrier guarantees. > > > > > > > > > > > > > > Great to see the documentation!!! Some comments below. > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > > > > > > > Signed-off-by: Mathieu Desnoyers > > > > > > > > --- > > > > > > > > diff --git a/doc/Makefile.am b/doc/Makefile.am > > > > > > > > index bec1d7c..db9811c 100644 > > > > > > > > --- a/doc/Makefile.am > > > > > > > > +++ b/doc/Makefile.am > > > > > > > > @@ -1 +1 @@ > > > > > > > > -dist_doc_DATA = rcu-api.txt > > > > > > > > +dist_doc_DATA = rcu-api.txt uatomic-api.txt > > > > > > > > diff --git a/doc/uatomic-api.txt b/doc/uatomic-api.txt > > > > > > > > new file mode 100644 > > > > > > > > index 0000000..3605acf > > > > > > > > --- /dev/null > > > > > > > > +++ b/doc/uatomic-api.txt > > > > > > > > @@ -0,0 +1,80 @@ > > > > > > > > +Userspace RCU Atomic Operations API > > > > > > > > +by Mathieu Desnoyers and Paul E. McKenney > > > > > > > > + > > > > > > > > + > > > > > > > > +This document describes the API. Those are the atomic > > > > > > > > +operations provided by the Userspace RCU library. The general rule > > > > > > > > +regarding memory barriers is that only uatomic_xchg(), > > > > > > > > +uatomic_cmpxchg(), uatomic_add_return(), and uatomic_sub_return() imply > > > > > > > > +full memory barriers before and after the atomic operation. Other > > > > > > > > +primitives don't guarantee any memory barrier. > > > > > > > > + > > > > > > > > +Only atomic operations performed on integers ("int" and "long", signed > > > > > > > > +and unsigned) are supported on all architectures. Some architectures > > > > > > > > +also support 1-byte and 2-byte atomic operations. Those respectively > > > > > > > > +have UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT defined when > > > > > > > > +uatomic.h is included. An architecture trying to perform an atomic write > > > > > > > > +to a type size not supported by the architecture will trigger an illegal > > > > > > > > +instruction. > > > > > > > > + > > > > > > > > +In the description below, "type" is a type that can be atomically > > > > > > > > +written to by the architecture. It needs to be at most word-sized, and > > > > > > > > +its alignment needs to greater or equal to its size. > > > > > > > > + > > > > > > > > +type uatomic_set(type *addr, type v) > > > > > > > > + > > > > > > > > + Atomically write @v into @addr. > > > > > > > > > > > > > > Wouldn't this instead be "void uatomic_set(type *addr, type v)"? > > > > > > > > > > > > Well, in that case, we'd need to change the macro. Currently, > > > > > > _uatomic_set maps directly to: > > > > > > > > > > > > #define _uatomic_set(addr, v) CMM_STORE_SHARED(*(addr), (v)) > > > > > > > > > > > > and CMM_STORE_SHARED returns v. The question becomes: should we change > > > > > > _uatomic_set or CMM_STORE_SHARED so they don't return anything, or > > > > > > document that they return something ? > > > > > > > > > > > > One thing I noticed is that linters often complain that the return value > > > > > > of CMM_STORE_SHARED is never used. One thing we could look into is to > > > > > > try some gcc attributes and/or linter annotations to flag this return > > > > > > value as possibly unused. Thoughts ? > > > > > > > > > > Hmmm... > > > > > > > > > > Does the following work? > > > > > > > > > > #define _uatomic_set(addr, v) ((void)CMM_STORE_SHARED(*(addr), (v))) > > > > > > > > Well, it would work, yes, but then we would not be consistent between > > > > return values or no return values of: > > > > > > > > uatomic_set() > > > > rcu_assign_pointer() > > > > rcu_set_pointer() > > > > > > > > if you notice, in the Linux kernel, rcu_assign_pointer returns the > > > > new pointer value. But you are right that atomic_set() does not return > > > > anything. So which consistency would be best to keep ? > > > > > > Hmmm... I wonder how many people actually use rcu_assign_pointer()'s > > > return value? If no one, I should make it a do-while(0). Although > > > cscope does not show anything, I should probably put together a > > > coccinelle script. > > > > I just searched the entire Linux kernel with git grep > > '\S.*rcu_assign_pointer' (any non-whitespace preceding > > rcu_assign_pointer), and found no instances of anything assuming a > > return value from rcu_assign_pointer. I'd recommend making it void. > > Woo-hoo!!! Thank you both!!! I'm not sure.. making rcu_assign_pointer() void we would be changing the semantic, which previously was that of an assignment in C, to something else. In C, if we have the expression: var = value; This whole expression evaluates as "value". So we can have e.g. do { ... } while ((var = value) != other); If the semantic we give to "rcu_assign_pointer" is the same as assignment operator "=", then we could think that the following should be allowed: do { ... } while (rcu_assign_pointer(addr, value) != other); But making rcu_assign_pointer "void" would not allow that. So the question I'd ask here is: what do we gain by changing the semantic compared to C assignment operator ? Thanks, Mathieu -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From paulmck at linux.vnet.ibm.com Thu May 17 14:28:56 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Thu, 17 May 2012 11:28:56 -0700 Subject: [lttng-dev] [rp] [RFC PATCH urcu] Document uatomic operations In-Reply-To: <20120517175943.GA824@Krystal> References: <20120515023901.GA22786@Krystal> <20120515040936.GB2412@linux.vnet.ibm.com> <20120515121003.GA31468@Krystal> <20120516171803.GB2441@linux.vnet.ibm.com> <20120516181742.GB16045@Krystal> <20120516183238.GJ2441@linux.vnet.ibm.com> <20120516184539.GB24507@leaf> <20120516195217.GK2441@linux.vnet.ibm.com> <20120517175943.GA824@Krystal> Message-ID: <20120517182856.GK2567@linux.vnet.ibm.com> On Thu, May 17, 2012 at 01:59:43PM -0400, Mathieu Desnoyers wrote: > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > On Wed, May 16, 2012 at 11:45:39AM -0700, Josh Triplett wrote: > > > On Wed, May 16, 2012 at 11:32:38AM -0700, Paul E. McKenney wrote: > > > > On Wed, May 16, 2012 at 02:17:42PM -0400, Mathieu Desnoyers wrote: > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > > On Tue, May 15, 2012 at 08:10:03AM -0400, Mathieu Desnoyers wrote: > > > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > > > > On Mon, May 14, 2012 at 10:39:01PM -0400, Mathieu Desnoyers wrote: > > > > > > > > > Document each atomic operation provided by urcu/uatomic.h, along with > > > > > > > > > their memory barrier guarantees. > > > > > > > > > > > > > > > > Great to see the documentation!!! Some comments below. > > > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > > > > > > > > > Signed-off-by: Mathieu Desnoyers > > > > > > > > > --- > > > > > > > > > diff --git a/doc/Makefile.am b/doc/Makefile.am > > > > > > > > > index bec1d7c..db9811c 100644 > > > > > > > > > --- a/doc/Makefile.am > > > > > > > > > +++ b/doc/Makefile.am > > > > > > > > > @@ -1 +1 @@ > > > > > > > > > -dist_doc_DATA = rcu-api.txt > > > > > > > > > +dist_doc_DATA = rcu-api.txt uatomic-api.txt > > > > > > > > > diff --git a/doc/uatomic-api.txt b/doc/uatomic-api.txt > > > > > > > > > new file mode 100644 > > > > > > > > > index 0000000..3605acf > > > > > > > > > --- /dev/null > > > > > > > > > +++ b/doc/uatomic-api.txt > > > > > > > > > @@ -0,0 +1,80 @@ > > > > > > > > > +Userspace RCU Atomic Operations API > > > > > > > > > +by Mathieu Desnoyers and Paul E. McKenney > > > > > > > > > + > > > > > > > > > + > > > > > > > > > +This document describes the API. Those are the atomic > > > > > > > > > +operations provided by the Userspace RCU library. The general rule > > > > > > > > > +regarding memory barriers is that only uatomic_xchg(), > > > > > > > > > +uatomic_cmpxchg(), uatomic_add_return(), and uatomic_sub_return() imply > > > > > > > > > +full memory barriers before and after the atomic operation. Other > > > > > > > > > +primitives don't guarantee any memory barrier. > > > > > > > > > + > > > > > > > > > +Only atomic operations performed on integers ("int" and "long", signed > > > > > > > > > +and unsigned) are supported on all architectures. Some architectures > > > > > > > > > +also support 1-byte and 2-byte atomic operations. Those respectively > > > > > > > > > +have UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT defined when > > > > > > > > > +uatomic.h is included. An architecture trying to perform an atomic write > > > > > > > > > +to a type size not supported by the architecture will trigger an illegal > > > > > > > > > +instruction. > > > > > > > > > + > > > > > > > > > +In the description below, "type" is a type that can be atomically > > > > > > > > > +written to by the architecture. It needs to be at most word-sized, and > > > > > > > > > +its alignment needs to greater or equal to its size. > > > > > > > > > + > > > > > > > > > +type uatomic_set(type *addr, type v) > > > > > > > > > + > > > > > > > > > + Atomically write @v into @addr. > > > > > > > > > > > > > > > > Wouldn't this instead be "void uatomic_set(type *addr, type v)"? > > > > > > > > > > > > > > Well, in that case, we'd need to change the macro. Currently, > > > > > > > _uatomic_set maps directly to: > > > > > > > > > > > > > > #define _uatomic_set(addr, v) CMM_STORE_SHARED(*(addr), (v)) > > > > > > > > > > > > > > and CMM_STORE_SHARED returns v. The question becomes: should we change > > > > > > > _uatomic_set or CMM_STORE_SHARED so they don't return anything, or > > > > > > > document that they return something ? > > > > > > > > > > > > > > One thing I noticed is that linters often complain that the return value > > > > > > > of CMM_STORE_SHARED is never used. One thing we could look into is to > > > > > > > try some gcc attributes and/or linter annotations to flag this return > > > > > > > value as possibly unused. Thoughts ? > > > > > > > > > > > > Hmmm... > > > > > > > > > > > > Does the following work? > > > > > > > > > > > > #define _uatomic_set(addr, v) ((void)CMM_STORE_SHARED(*(addr), (v))) > > > > > > > > > > Well, it would work, yes, but then we would not be consistent between > > > > > return values or no return values of: > > > > > > > > > > uatomic_set() > > > > > rcu_assign_pointer() > > > > > rcu_set_pointer() > > > > > > > > > > if you notice, in the Linux kernel, rcu_assign_pointer returns the > > > > > new pointer value. But you are right that atomic_set() does not return > > > > > anything. So which consistency would be best to keep ? > > > > > > > > Hmmm... I wonder how many people actually use rcu_assign_pointer()'s > > > > return value? If no one, I should make it a do-while(0). Although > > > > cscope does not show anything, I should probably put together a > > > > coccinelle script. > > > > > > I just searched the entire Linux kernel with git grep > > > '\S.*rcu_assign_pointer' (any non-whitespace preceding > > > rcu_assign_pointer), and found no instances of anything assuming a > > > return value from rcu_assign_pointer. I'd recommend making it void. > > > > Woo-hoo!!! Thank you both!!! > > I'm not sure.. making rcu_assign_pointer() void we would be changing the > semantic, which previously was that of an assignment in C, to something > else. > > In C, if we have the expression: > > var = value; > > This whole expression evaluates as "value". So we can have e.g. > > do { > ... > } while ((var = value) != other); > > If the semantic we give to "rcu_assign_pointer" is the same as > assignment operator "=", then we could think that the following should > be allowed: > > do { > ... > } while (rcu_assign_pointer(addr, value) != other); > > But making rcu_assign_pointer "void" would not allow that. So the > question I'd ask here is: what do we gain by changing the semantic > compared to C assignment operator ? It is pretty easy to handle this with a void rcu_assign_pointer(): do { ... rcu_assign_pointer(addr, value); } while (value != other); If "value" is an expression involving side-effects, then yes, you would need a temporary. But there are several hundred uses of rcu_assign_pointer() in the Linux kernel, and none of them are in a while-loop expression. So I am in favor of making rcu_assign_pointer() void. Thanx, Paul > Thanks, > > Mathieu > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > From mathieu.desnoyers at efficios.com Thu May 17 18:04:13 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 17 May 2012 18:04:13 -0400 Subject: [lttng-dev] [rp] [RFC PATCH urcu] Document uatomic operations In-Reply-To: <20120517182856.GK2567@linux.vnet.ibm.com> References: <20120515023901.GA22786@Krystal> <20120515040936.GB2412@linux.vnet.ibm.com> <20120515121003.GA31468@Krystal> <20120516171803.GB2441@linux.vnet.ibm.com> <20120516181742.GB16045@Krystal> <20120516183238.GJ2441@linux.vnet.ibm.com> <20120516184539.GB24507@leaf> <20120516195217.GK2441@linux.vnet.ibm.com> <20120517175943.GA824@Krystal> <20120517182856.GK2567@linux.vnet.ibm.com> Message-ID: <20120517220413.GB3822@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > On Thu, May 17, 2012 at 01:59:43PM -0400, Mathieu Desnoyers wrote: > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > On Wed, May 16, 2012 at 11:45:39AM -0700, Josh Triplett wrote: > > > > On Wed, May 16, 2012 at 11:32:38AM -0700, Paul E. McKenney wrote: > > > > > On Wed, May 16, 2012 at 02:17:42PM -0400, Mathieu Desnoyers wrote: > > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > > > On Tue, May 15, 2012 at 08:10:03AM -0400, Mathieu Desnoyers wrote: > > > > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > > > > > On Mon, May 14, 2012 at 10:39:01PM -0400, Mathieu Desnoyers wrote: > > > > > > > > > > Document each atomic operation provided by urcu/uatomic.h, along with > > > > > > > > > > their memory barrier guarantees. > > > > > > > > > > > > > > > > > > Great to see the documentation!!! Some comments below. > > > > > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > > > > > > > > > > > Signed-off-by: Mathieu Desnoyers > > > > > > > > > > --- > > > > > > > > > > diff --git a/doc/Makefile.am b/doc/Makefile.am > > > > > > > > > > index bec1d7c..db9811c 100644 > > > > > > > > > > --- a/doc/Makefile.am > > > > > > > > > > +++ b/doc/Makefile.am > > > > > > > > > > @@ -1 +1 @@ > > > > > > > > > > -dist_doc_DATA = rcu-api.txt > > > > > > > > > > +dist_doc_DATA = rcu-api.txt uatomic-api.txt > > > > > > > > > > diff --git a/doc/uatomic-api.txt b/doc/uatomic-api.txt > > > > > > > > > > new file mode 100644 > > > > > > > > > > index 0000000..3605acf > > > > > > > > > > --- /dev/null > > > > > > > > > > +++ b/doc/uatomic-api.txt > > > > > > > > > > @@ -0,0 +1,80 @@ > > > > > > > > > > +Userspace RCU Atomic Operations API > > > > > > > > > > +by Mathieu Desnoyers and Paul E. McKenney > > > > > > > > > > + > > > > > > > > > > + > > > > > > > > > > +This document describes the API. Those are the atomic > > > > > > > > > > +operations provided by the Userspace RCU library. The general rule > > > > > > > > > > +regarding memory barriers is that only uatomic_xchg(), > > > > > > > > > > +uatomic_cmpxchg(), uatomic_add_return(), and uatomic_sub_return() imply > > > > > > > > > > +full memory barriers before and after the atomic operation. Other > > > > > > > > > > +primitives don't guarantee any memory barrier. > > > > > > > > > > + > > > > > > > > > > +Only atomic operations performed on integers ("int" and "long", signed > > > > > > > > > > +and unsigned) are supported on all architectures. Some architectures > > > > > > > > > > +also support 1-byte and 2-byte atomic operations. Those respectively > > > > > > > > > > +have UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT defined when > > > > > > > > > > +uatomic.h is included. An architecture trying to perform an atomic write > > > > > > > > > > +to a type size not supported by the architecture will trigger an illegal > > > > > > > > > > +instruction. > > > > > > > > > > + > > > > > > > > > > +In the description below, "type" is a type that can be atomically > > > > > > > > > > +written to by the architecture. It needs to be at most word-sized, and > > > > > > > > > > +its alignment needs to greater or equal to its size. > > > > > > > > > > + > > > > > > > > > > +type uatomic_set(type *addr, type v) > > > > > > > > > > + > > > > > > > > > > + Atomically write @v into @addr. > > > > > > > > > > > > > > > > > > Wouldn't this instead be "void uatomic_set(type *addr, type v)"? > > > > > > > > > > > > > > > > Well, in that case, we'd need to change the macro. Currently, > > > > > > > > _uatomic_set maps directly to: > > > > > > > > > > > > > > > > #define _uatomic_set(addr, v) CMM_STORE_SHARED(*(addr), (v)) > > > > > > > > > > > > > > > > and CMM_STORE_SHARED returns v. The question becomes: should we change > > > > > > > > _uatomic_set or CMM_STORE_SHARED so they don't return anything, or > > > > > > > > document that they return something ? > > > > > > > > > > > > > > > > One thing I noticed is that linters often complain that the return value > > > > > > > > of CMM_STORE_SHARED is never used. One thing we could look into is to > > > > > > > > try some gcc attributes and/or linter annotations to flag this return > > > > > > > > value as possibly unused. Thoughts ? > > > > > > > > > > > > > > Hmmm... > > > > > > > > > > > > > > Does the following work? > > > > > > > > > > > > > > #define _uatomic_set(addr, v) ((void)CMM_STORE_SHARED(*(addr), (v))) > > > > > > > > > > > > Well, it would work, yes, but then we would not be consistent between > > > > > > return values or no return values of: > > > > > > > > > > > > uatomic_set() > > > > > > rcu_assign_pointer() > > > > > > rcu_set_pointer() > > > > > > > > > > > > if you notice, in the Linux kernel, rcu_assign_pointer returns the > > > > > > new pointer value. But you are right that atomic_set() does not return > > > > > > anything. So which consistency would be best to keep ? > > > > > > > > > > Hmmm... I wonder how many people actually use rcu_assign_pointer()'s > > > > > return value? If no one, I should make it a do-while(0). Although > > > > > cscope does not show anything, I should probably put together a > > > > > coccinelle script. > > > > > > > > I just searched the entire Linux kernel with git grep > > > > '\S.*rcu_assign_pointer' (any non-whitespace preceding > > > > rcu_assign_pointer), and found no instances of anything assuming a > > > > return value from rcu_assign_pointer. I'd recommend making it void. > > > > > > Woo-hoo!!! Thank you both!!! > > > > I'm not sure.. making rcu_assign_pointer() void we would be changing the > > semantic, which previously was that of an assignment in C, to something > > else. > > > > In C, if we have the expression: > > > > var = value; > > > > This whole expression evaluates as "value". So we can have e.g. > > > > do { > > ... > > } while ((var = value) != other); > > > > If the semantic we give to "rcu_assign_pointer" is the same as > > assignment operator "=", then we could think that the following should > > be allowed: > > > > do { > > ... > > } while (rcu_assign_pointer(addr, value) != other); > > > > But making rcu_assign_pointer "void" would not allow that. So the > > question I'd ask here is: what do we gain by changing the semantic > > compared to C assignment operator ? > > It is pretty easy to handle this with a void rcu_assign_pointer(): > > do { > ... > rcu_assign_pointer(addr, value); > } while (value != other); > > If "value" is an expression involving side-effects, then yes, > you would need a temporary. But there are several hundred uses of > rcu_assign_pointer() in the Linux kernel, and none of them are > in a while-loop expression. > > So I am in favor of making rcu_assign_pointer() void. OK. How about the following patch then ? diff --git a/urcu-pointer.h b/urcu-pointer.h index dd64ec4..1e1e6bf 100644 --- a/urcu-pointer.h +++ b/urcu-pointer.h @@ -47,9 +47,9 @@ extern "C" { #define rcu_dereference _rcu_dereference /* - * rcu_cmpxchg_pointer(type **ptr, type *new, type *old) + * type *rcu_cmpxchg_pointer(type **ptr, type *new, type *old) * type *rcu_xchg_pointer(type **ptr, type *new) - * type *rcu_set_pointer(type **ptr, type *new) + * void rcu_set_pointer(type **ptr, type *new) * * RCU pointer updates. * @ptr: address of the pointer to modify @@ -94,20 +94,24 @@ extern void *rcu_xchg_pointer_sym(void **p, void *v); (_________p1); \ }) +/* + * Note: rcu_set_pointer_sym returns @v because we don't want to break + * the ABI. At the API level, rcu_set_pointer() now returns void. Use of + * the return value is therefore deprecated, and will cause a build + * error. + */ extern void *rcu_set_pointer_sym(void **p, void *v); #define rcu_set_pointer(p, v) \ - ({ \ + do { \ typeof(*(p)) _________pv = (v); \ - typeof(*(p)) _________p1 = URCU_FORCE_CAST(typeof(*(p)), \ - rcu_set_pointer_sym(URCU_FORCE_CAST(void **, p), \ - _________pv)); \ - (_________p1); \ - }) + (void) rcu_set_pointer_sym(URCU_FORCE_CAST(void **, p), \ + _________pv); \ + } while (0) #endif /* !_LGPL_SOURCE */ /* - * rcu_assign_pointer(type *ptr, type *new) + * void rcu_assign_pointer(type *ptr, type *new) * * Same as rcu_set_pointer, but takes the pointer to assign to rather than its * address as first parameter. Provided for compatibility with the Linux kernel diff --git a/urcu/static/urcu-pointer.h b/urcu/static/urcu-pointer.h index acd7cee..906caa0 100644 --- a/urcu/static/urcu-pointer.h +++ b/urcu/static/urcu-pointer.h @@ -102,13 +102,13 @@ extern "C" { #define _rcu_set_pointer(p, v) \ - ({ \ + do { \ typeof(*p) _________pv = (v); \ if (!__builtin_constant_p(v) || \ ((v) != NULL)) \ cmm_wmb(); \ uatomic_set(p, _________pv); \ - }) + } while (0) /** * _rcu_assign_pointer - assign (publicize) a pointer to a new data structure diff --git a/urcu/uatomic/generic.h b/urcu/uatomic/generic.h index bfd9b68..9e2e780 100644 --- a/urcu/uatomic/generic.h +++ b/urcu/uatomic/generic.h @@ -29,7 +29,7 @@ extern "C" { #endif #ifndef uatomic_set -#define uatomic_set(addr, v) CMM_STORE_SHARED(*(addr), (v)) +#define uatomic_set(addr, v) ((void) CMM_STORE_SHARED(*(addr), (v))) #endif #ifndef uatomic_read Thanks, Mathieu -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From paulmck at linux.vnet.ibm.com Thu May 17 18:37:27 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Thu, 17 May 2012 15:37:27 -0700 Subject: [lttng-dev] [rp] [RFC PATCH urcu] Document uatomic operations In-Reply-To: <20120517220413.GB3822@Krystal> References: <20120515040936.GB2412@linux.vnet.ibm.com> <20120515121003.GA31468@Krystal> <20120516171803.GB2441@linux.vnet.ibm.com> <20120516181742.GB16045@Krystal> <20120516183238.GJ2441@linux.vnet.ibm.com> <20120516184539.GB24507@leaf> <20120516195217.GK2441@linux.vnet.ibm.com> <20120517175943.GA824@Krystal> <20120517182856.GK2567@linux.vnet.ibm.com> <20120517220413.GB3822@Krystal> Message-ID: <20120517223726.GO2567@linux.vnet.ibm.com> On Thu, May 17, 2012 at 06:04:13PM -0400, Mathieu Desnoyers wrote: > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > On Thu, May 17, 2012 at 01:59:43PM -0400, Mathieu Desnoyers wrote: > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > On Wed, May 16, 2012 at 11:45:39AM -0700, Josh Triplett wrote: > > > > > On Wed, May 16, 2012 at 11:32:38AM -0700, Paul E. McKenney wrote: > > > > > > On Wed, May 16, 2012 at 02:17:42PM -0400, Mathieu Desnoyers wrote: > > > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > > > > On Tue, May 15, 2012 at 08:10:03AM -0400, Mathieu Desnoyers wrote: > > > > > > > > > * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > > > > > > > > > > On Mon, May 14, 2012 at 10:39:01PM -0400, Mathieu Desnoyers wrote: > > > > > > > > > > > Document each atomic operation provided by urcu/uatomic.h, along with > > > > > > > > > > > their memory barrier guarantees. > > > > > > > > > > > > > > > > > > > > Great to see the documentation!!! Some comments below. > > > > > > > > > > > > > > > > > > > > Thanx, Paul > > > > > > > > > > > > > > > > > > > > > Signed-off-by: Mathieu Desnoyers > > > > > > > > > > > --- > > > > > > > > > > > diff --git a/doc/Makefile.am b/doc/Makefile.am > > > > > > > > > > > index bec1d7c..db9811c 100644 > > > > > > > > > > > --- a/doc/Makefile.am > > > > > > > > > > > +++ b/doc/Makefile.am > > > > > > > > > > > @@ -1 +1 @@ > > > > > > > > > > > -dist_doc_DATA = rcu-api.txt > > > > > > > > > > > +dist_doc_DATA = rcu-api.txt uatomic-api.txt > > > > > > > > > > > diff --git a/doc/uatomic-api.txt b/doc/uatomic-api.txt > > > > > > > > > > > new file mode 100644 > > > > > > > > > > > index 0000000..3605acf > > > > > > > > > > > --- /dev/null > > > > > > > > > > > +++ b/doc/uatomic-api.txt > > > > > > > > > > > @@ -0,0 +1,80 @@ > > > > > > > > > > > +Userspace RCU Atomic Operations API > > > > > > > > > > > +by Mathieu Desnoyers and Paul E. McKenney > > > > > > > > > > > + > > > > > > > > > > > + > > > > > > > > > > > +This document describes the API. Those are the atomic > > > > > > > > > > > +operations provided by the Userspace RCU library. The general rule > > > > > > > > > > > +regarding memory barriers is that only uatomic_xchg(), > > > > > > > > > > > +uatomic_cmpxchg(), uatomic_add_return(), and uatomic_sub_return() imply > > > > > > > > > > > +full memory barriers before and after the atomic operation. Other > > > > > > > > > > > +primitives don't guarantee any memory barrier. > > > > > > > > > > > + > > > > > > > > > > > +Only atomic operations performed on integers ("int" and "long", signed > > > > > > > > > > > +and unsigned) are supported on all architectures. Some architectures > > > > > > > > > > > +also support 1-byte and 2-byte atomic operations. Those respectively > > > > > > > > > > > +have UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT defined when > > > > > > > > > > > +uatomic.h is included. An architecture trying to perform an atomic write > > > > > > > > > > > +to a type size not supported by the architecture will trigger an illegal > > > > > > > > > > > +instruction. > > > > > > > > > > > + > > > > > > > > > > > +In the description below, "type" is a type that can be atomically > > > > > > > > > > > +written to by the architecture. It needs to be at most word-sized, and > > > > > > > > > > > +its alignment needs to greater or equal to its size. > > > > > > > > > > > + > > > > > > > > > > > +type uatomic_set(type *addr, type v) > > > > > > > > > > > + > > > > > > > > > > > + Atomically write @v into @addr. > > > > > > > > > > > > > > > > > > > > Wouldn't this instead be "void uatomic_set(type *addr, type v)"? > > > > > > > > > > > > > > > > > > Well, in that case, we'd need to change the macro. Currently, > > > > > > > > > _uatomic_set maps directly to: > > > > > > > > > > > > > > > > > > #define _uatomic_set(addr, v) CMM_STORE_SHARED(*(addr), (v)) > > > > > > > > > > > > > > > > > > and CMM_STORE_SHARED returns v. The question becomes: should we change > > > > > > > > > _uatomic_set or CMM_STORE_SHARED so they don't return anything, or > > > > > > > > > document that they return something ? > > > > > > > > > > > > > > > > > > One thing I noticed is that linters often complain that the return value > > > > > > > > > of CMM_STORE_SHARED is never used. One thing we could look into is to > > > > > > > > > try some gcc attributes and/or linter annotations to flag this return > > > > > > > > > value as possibly unused. Thoughts ? > > > > > > > > > > > > > > > > Hmmm... > > > > > > > > > > > > > > > > Does the following work? > > > > > > > > > > > > > > > > #define _uatomic_set(addr, v) ((void)CMM_STORE_SHARED(*(addr), (v))) > > > > > > > > > > > > > > Well, it would work, yes, but then we would not be consistent between > > > > > > > return values or no return values of: > > > > > > > > > > > > > > uatomic_set() > > > > > > > rcu_assign_pointer() > > > > > > > rcu_set_pointer() > > > > > > > > > > > > > > if you notice, in the Linux kernel, rcu_assign_pointer returns the > > > > > > > new pointer value. But you are right that atomic_set() does not return > > > > > > > anything. So which consistency would be best to keep ? > > > > > > > > > > > > Hmmm... I wonder how many people actually use rcu_assign_pointer()'s > > > > > > return value? If no one, I should make it a do-while(0). Although > > > > > > cscope does not show anything, I should probably put together a > > > > > > coccinelle script. > > > > > > > > > > I just searched the entire Linux kernel with git grep > > > > > '\S.*rcu_assign_pointer' (any non-whitespace preceding > > > > > rcu_assign_pointer), and found no instances of anything assuming a > > > > > return value from rcu_assign_pointer. I'd recommend making it void. > > > > > > > > Woo-hoo!!! Thank you both!!! > > > > > > I'm not sure.. making rcu_assign_pointer() void we would be changing the > > > semantic, which previously was that of an assignment in C, to something > > > else. > > > > > > In C, if we have the expression: > > > > > > var = value; > > > > > > This whole expression evaluates as "value". So we can have e.g. > > > > > > do { > > > ... > > > } while ((var = value) != other); > > > > > > If the semantic we give to "rcu_assign_pointer" is the same as > > > assignment operator "=", then we could think that the following should > > > be allowed: > > > > > > do { > > > ... > > > } while (rcu_assign_pointer(addr, value) != other); > > > > > > But making rcu_assign_pointer "void" would not allow that. So the > > > question I'd ask here is: what do we gain by changing the semantic > > > compared to C assignment operator ? > > > > It is pretty easy to handle this with a void rcu_assign_pointer(): > > > > do { > > ... > > rcu_assign_pointer(addr, value); > > } while (value != other); > > > > If "value" is an expression involving side-effects, then yes, > > you would need a temporary. But there are several hundred uses of > > rcu_assign_pointer() in the Linux kernel, and none of them are > > in a while-loop expression. > > > > So I am in favor of making rcu_assign_pointer() void. > > OK. How about the following patch then ? Looks good to me! Reviewed-by: Paul E. McKenney > diff --git a/urcu-pointer.h b/urcu-pointer.h > index dd64ec4..1e1e6bf 100644 > --- a/urcu-pointer.h > +++ b/urcu-pointer.h > @@ -47,9 +47,9 @@ extern "C" { > #define rcu_dereference _rcu_dereference > > /* > - * rcu_cmpxchg_pointer(type **ptr, type *new, type *old) > + * type *rcu_cmpxchg_pointer(type **ptr, type *new, type *old) > * type *rcu_xchg_pointer(type **ptr, type *new) > - * type *rcu_set_pointer(type **ptr, type *new) > + * void rcu_set_pointer(type **ptr, type *new) > * > * RCU pointer updates. > * @ptr: address of the pointer to modify > @@ -94,20 +94,24 @@ extern void *rcu_xchg_pointer_sym(void **p, void *v); > (_________p1); \ > }) > > +/* > + * Note: rcu_set_pointer_sym returns @v because we don't want to break > + * the ABI. At the API level, rcu_set_pointer() now returns void. Use of > + * the return value is therefore deprecated, and will cause a build > + * error. > + */ > extern void *rcu_set_pointer_sym(void **p, void *v); > #define rcu_set_pointer(p, v) \ > - ({ \ > + do { \ > typeof(*(p)) _________pv = (v); \ > - typeof(*(p)) _________p1 = URCU_FORCE_CAST(typeof(*(p)), \ > - rcu_set_pointer_sym(URCU_FORCE_CAST(void **, p), \ > - _________pv)); \ > - (_________p1); \ > - }) > + (void) rcu_set_pointer_sym(URCU_FORCE_CAST(void **, p), \ > + _________pv); \ > + } while (0) > > #endif /* !_LGPL_SOURCE */ > > /* > - * rcu_assign_pointer(type *ptr, type *new) > + * void rcu_assign_pointer(type *ptr, type *new) > * > * Same as rcu_set_pointer, but takes the pointer to assign to rather than its > * address as first parameter. Provided for compatibility with the Linux kernel > diff --git a/urcu/static/urcu-pointer.h b/urcu/static/urcu-pointer.h > index acd7cee..906caa0 100644 > --- a/urcu/static/urcu-pointer.h > +++ b/urcu/static/urcu-pointer.h > @@ -102,13 +102,13 @@ extern "C" { > > > #define _rcu_set_pointer(p, v) \ > - ({ \ > + do { \ > typeof(*p) _________pv = (v); \ > if (!__builtin_constant_p(v) || \ > ((v) != NULL)) \ > cmm_wmb(); \ > uatomic_set(p, _________pv); \ > - }) > + } while (0) > > /** > * _rcu_assign_pointer - assign (publicize) a pointer to a new data structure > diff --git a/urcu/uatomic/generic.h b/urcu/uatomic/generic.h > index bfd9b68..9e2e780 100644 > --- a/urcu/uatomic/generic.h > +++ b/urcu/uatomic/generic.h > @@ -29,7 +29,7 @@ extern "C" { > #endif > > #ifndef uatomic_set > -#define uatomic_set(addr, v) CMM_STORE_SHARED(*(addr), (v)) > +#define uatomic_set(addr, v) ((void) CMM_STORE_SHARED(*(addr), (v))) > #endif > > #ifndef uatomic_read > > > Thanks, > > Mathieu > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > rp mailing list > rp at svcs.cs.pdx.edu > http://svcs.cs.pdx.edu/mailman/listinfo/rp > From montarcyber at gmail.com Fri May 18 00:12:36 2012 From: montarcyber at gmail.com (tchak adim) Date: Fri, 18 May 2012 06:12:36 +0200 Subject: [lttng-dev] problem when installing lttng-modules-2.0.2 Message-ID: Hi all, I'm a new user of lttng , i'm trying to install it on my ubuntu 10.04 OS . I already compile linux kernel-2.6.35.13 on my PC . but when i compile lttng-modules-2.0.2 source code these errors occur : /PC/lttng-modules-2.0.2/instrumentation/syscalls/headers/../../../probes/../instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers.h:1438: warning: ?struct rlimit64? declared inside parameter list /PC/lttng-modules-2.0.2/instrumentation/syscalls/headers/../../../probes/../instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers.h:1444: error: conflicting types for ?trace_sys_prlimit64? /PC/lttng-modules-2.0.2/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers.h:1444: note: previous definition of ?trace_sys_prlimit64? was here Can anyone helps me to fix it ? Regards. -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexandre.montplaisir at polymtl.ca Fri May 18 10:14:26 2012 From: alexandre.montplaisir at polymtl.ca (Alexandre Montplaisir) Date: Fri, 18 May 2012 10:14:26 -0400 Subject: [lttng-dev] problem when installing lttng-modules-2.0.2 In-Reply-To: References: Message-ID: <4FB65942.2080803@polymtl.ca> On 12-05-18 12:12 AM, tchak adim wrote: > Hi all, > > > I'm a new user of lttng , i'm trying to install it on my ubuntu 10.04 OS . > I already compile linux kernel-2.6.35.13 on my PC . > but when i compile lttng-modules-2.0.2 source code these errors occur : > > /PC/lttng-modules-2.0.2/instrumentation/syscalls/headers/../../../probes/../instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers.h:1438: > warning: ?struct rlimit64? declared inside parameter list > /PC/lttng-modules-2.0.2/instrumentation/syscalls/headers/../../../probes/../instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers.h:1444: > error: conflicting types for ?trace_sys_prlimit64? > /PC/lttng-modules-2.0.2/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers.h:1444: > note: previous definition of ?trace_sys_prlimit64? was here > > Can anyone helps me to fix it ? > > Regards. > > Hi, lttng-modules officially supports kernel 2.6.38 and up only. However, there were some experimental patches to make it run on CentOS 6 (kernel 2.6.32), see http://lists.lttng.org/pipermail/lttng-dev/2012-May/017908.html . Ubuntu 10.04 comes with 2.6.32 if I'm not mistaken, so it might be possible to make it work using those. Cheers, -- Alexandre Montplaisir DORSAL lab, ?cole Polytechnique de Montr?al From paulbarrette at gmail.com Fri May 18 10:59:59 2012 From: paulbarrette at gmail.com (Paul Barrette) Date: Fri, 18 May 2012 10:59:59 -0400 Subject: [lttng-dev] compiling lttng 2.0.1 statically into kernel tree 3.4.0-rc7 fails Message-ID: Hi all, I added the lttng-module to my kernel tree with the goal of making it a tristate option. I added a Kconfig and a few Makefile changes (removed the rules at end). I am able to compile lttng-module as a module (M), but compiling statically fails at link time with some redefinition errors (log below). Details: target: powerpc kernel config: mpc85xx_defconfig lttng-modules 2.0.1 plus patch commit 6bd5e64e29cf1c251632501e45d61be6f16257ba Author: Mathieu Desnoyers Date: Thu Apr 26 17:40:31 2012 -0400 Fix: update signal instrumentation for 3.4 kernel Fix #226 Any ideas? LD drivers/staging/lttng2/probes/built-in.o LD drivers/staging/lttng2/built-in.o drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x35c): multiple definition of `__tracepoint_lttng_statedump_network_interface' drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x64): first defined here drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x320): multiple definition of `__tracepoint_lttng_statedump_process_state' drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x14): first defined here drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x2f8): multiple definition of `__tracepoint_lttng_statedump_start' drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x0): first defined here drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x334): multiple definition of `__tracepoint_lttng_statedump_file_descriptor' drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x28): first defined here drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x370): multiple definition of `__tracepoint_lttng_statedump_interrupt' drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x50): first defined here drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x348): multiple definition of `__tracepoint_lttng_statedump_vm_map' drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x3c): first defined here drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x30c): multiple definition of `__tracepoint_lttng_statedump_end' drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x78): first defined here make[3]: *** [drivers/staging/lttng2/built-in.o] Error 1 make[2]: *** [drivers/staging/lttng2] Error 2 make[1]: *** [drivers/staging] Error 2 make: *** [drivers] Error 2 Thanks Pb -- -- Paul Barrette Linked In Profile http://sitarplayer.net ? \\=^% (*)---(*) ^^~~^~~~^^^~~^ -------------- next part -------------- An HTML attachment was scrubbed... URL: From mathieu.desnoyers at efficios.com Fri May 18 11:18:51 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 18 May 2012 11:18:51 -0400 Subject: [lttng-dev] HOW TO DOWNLOAD LTTng 2.0 stable? In-Reply-To: References: <4FB3EDC0.7080006@polymtl.ca> <4FB50A3E.7030508@polymtl.ca> <20120517143031.GA30839@Krystal> Message-ID: <20120518151850.GA17152@Krystal> * Vanni Genua (vannigenua at gmail.com) wrote: > I did it a minute ago, now the problems are the undefined references at the > end of this logs: > > localhost lttng-ust-2.0.1 # ./configure --build=armv7a-unknown-linux- > gnueabi This looks like a problem with your toolchain (gcc/ld/...), since AFAIK Alexandre is able to cross-build for ARMv7 on Ubuntu. You should ask your distribution vendor. Also, you seem to be still using lttng-ust 2.0.1 instead of "HEAD". Which commit ID are you using ? Thanks, Mathieu > > checking build system type... > armv7a-unknown-linux-gnueabi > > checking host system type... > armv7a-unknown-linux-gnueabi > > checking target system type... > armv7a-unknown-linux-gnueabi > > checking how to convert armv7a-unknown-linux-gnueabi file names to > armv7a-unknown-linux-gnueabi format... > func_convert_file_noop > checking how to convert armv7a-unknown-linux-gnueabi file names to > toolchain format... > func_convert_file_noop > checking library format for the host system... > elf32-littlearm > > configure: creating > ./config.status > > config.status: creating > Makefile > > config.status: creating > doc/Makefile > > config.status: creating > doc/examples/Makefile > > config.status: creating > include/Makefile > > config.status: creating > include/lttng/ust-version.h > > config.status: creating > snprintf/Makefile > > config.status: creating > libringbuffer/Makefile > > config.status: creating > liblttng-ust-comm/Makefile > > config.status: creating > liblttng-ust/Makefile > > config.status: creating > liblttng-ust-ctl/Makefile > > config.status: creating > liblttng-ust-fork/Makefile > > config.status: creating > liblttng-ust-java/Makefile > > config.status: creating > liblttng-ust-libc-wrapper/Makefile > > config.status: creating > tools/Makefile > > config.status: creating > tests/Makefile > > config.status: creating > tests/hello/Makefile > > config.status: creating > tests/hello-static-lib/Makefile > > config.status: creating > tests/hello.cxx/Makefile > > config.status: creating > tests/demo/Makefile > > config.status: creating > tests/fork/Makefile > > config.status: creating > tests/ust-basic-tracing/Makefile > > config.status: creating > tests/ust-multi-test/Makefile > > config.status: creating > lttng-ust.pc > > config.status: creating > config.h > > config.status: config.h is > unchanged > > config.status: creating > include/lttng/ust-config.h > > config.status: include/lttng/ust-config.h is > unchanged > > config.status: executing depfiles > commands > > config.status: executing libtool > commands > > > > Version name: > Annedd'ale > > New type of beer, 100% from Quebec, flavored with sapin beaumier needles, > with a touch of > hops. > > > LTTng-UST will be built with the following > options: > > Library format: > elf32-littlearm > > > > Java support (JNI): > Disabled > > sdt.h integration: > Disabled > > > > Type 'make' to > compile. > > localhost lttng-ust-2.0.1 # > make > > make > all-recursive > > make[1]: Entering directory > `/usr/src/lttng-ust-2.0.1' > > Making all in > . > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1' > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1' > > Making all in > include > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/include' > > make[2]: Nothing to be done for > `all'. > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/include' > > Making all in > snprintf > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/snprintf' > > make[2]: Nothing to be done for > `all'. > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/snprintf' > > Making all in > libringbuffer > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/libringbuffer' > > CC > libringbuffer_la-ring_buffer_backend.lo > > CC > libringbuffer_la-ring_buffer_frontend.lo > > CCLD libringbuffer.la > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/libringbuffer' > > Making all in > liblttng-ust-comm > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' > > make[2]: Nothing to be done for > `all'. > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' > > Making all in > liblttng-ust > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust' > > CC > liblttng_ust_tracepoint_la-tracepoint.lo > > CCLD liblttng-ust-tracepoint.la > > CC > lttng-ust-comm.lo > > CC > lttng-ust-abi.lo > > CC > ltt-probes.lo > > CC > lttng-probe-ust.lo > > CC > lttng-context-vtid.lo > > CC > lttng-context-vpid.lo > > CC > lttng-context-pthread-id.lo > > CC > lttng-context-procname.lo > > CC > ltt-context.lo > > CC > ltt-events.lo > > CCLD liblttng-ust-runtime.la > > CC > ust-core.lo > > CC > ltt-ring-buffer-client-discard.lo > > CC > ltt-ring-buffer-client-overwrite.lo > > CC > ltt-ring-buffer-metadata-client.lo > > CCLD liblttng-ust-support.la > > CCLD liblttng-ust.la > > /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/../../../../armv7a-unknown-linux-gnueabi/bin/ld: > warning: creating a DT_TEXTREL in object. > copying selected object files to avoid basename > conflicts... > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust' > > Making all in > liblttng-ust-ctl > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' > > CC > ustctl.lo > > CCLD liblttng-ust-ctl.la > > /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/../../../../armv7a-unknown-linux-gnueabi/bin/ld: > warning: creating a DT_TEXTREL in object. > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' > > Making all in > liblttng-ust-fork > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' > > CCLD liblttng-ust-fork.la > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' > > Making all in > liblttng-ust-libc-wrapper > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' > > CC > lttng-ust-malloc.lo > > CCLD liblttng-ust-libc-wrapper.la > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' > > Making all in > tools > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/tools' > > make[2]: Nothing to be done for > `all'. > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/tools' > > Making all in > tests > > make[2]: Entering directory > `/usr/src/lttng-ust-2.0.1/tests' > > Making all in > . > > make[3]: Entering directory > `/usr/src/lttng-ust-2.0.1/tests' > > make[3]: Nothing to be done for > `all-am'. > > make[3]: Leaving directory > `/usr/src/lttng-ust-2.0.1/tests' > > Making all in > hello > > make[3]: Entering directory > `/usr/src/lttng-ust-2.0.1/tests/hello' > > CC > tp.o > > CCLD > hello > > ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > `__num_possible_cpus' > > ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > `shm_object_table_create' > > ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > `shm_object_table_append_shadow' > > ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > `shm_object_table_append' > > ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > `zalloc_shm' > > ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > `_get_num_possible_cpus' > > ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > `align_shm' > > ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > `shm_object_table_destroy' > > collect2: ld returned 1 exit > status > > make[3]: *** [hello] Error > 1 > > make[3]: Leaving directory > `/usr/src/lttng-ust-2.0.1/tests/hello' > > make[2]: *** [all-recursive] Error > 1 > > make[2]: Leaving directory > `/usr/src/lttng-ust-2.0.1/tests' > > make[1]: *** [all-recursive] Error > 1 > > make[1]: Leaving directory > `/usr/src/lttng-ust-2.0.1' > > make: *** [all] Error > 2 > > localhost lttng-ust-2.0.1 # > > > On Thu, May 17, 2012 at 2:30 PM, Mathieu Desnoyers < > mathieu.desnoyers at efficios.com> wrote: > > > * Alexandre Montplaisir (alexandre.montplaisir at polymtl.ca) wrote: > > > This is an interesting problem, I'll forward it to the mailing list. > > > > > > > > > On 12-05-17 10:02 AM, Vanni Genua wrote: > > > > Also why I get this error? > > > > see the attached log file. > > > > Best regards. > > > > V.G. > > > > > > > > > > > > > > localhost lttng-ust-2.0.1 # ./configure > > > checking build system type... armv7l-unknown-linux-gnueabi > > > checking host system type... armv7l-unknown-linux-gnueabi > > > checking target system type... armv7l-unknown-linux-gnueabi > > > checking for a BSD-compatible install... /usr/bin/install -c > > > checking whether build environment is sane... yes > > > checking for a thread-safe mkdir -p... /bin/mkdir -p > > > checking for gawk... gawk > > > checking whether make sets $(MAKE)... yes > > > checking whether make supports nested variables... yes > > > checking for a sed that does not truncate output... /bin/sed > > > checking for gcc... gcc > > > checking whether the C compiler works... yes > > > checking for C compiler default output file name... a.out > > > checking for suffix of executables... > > > checking whether we are cross compiling... no > > > checking for suffix of object files... o > > > checking whether we are using the GNU C compiler... yes > > > checking whether gcc accepts -g... yes > > > checking for gcc option to accept ISO C89... none needed > > > checking for style of include used by make... GNU > > > checking dependency style of gcc... gcc3 > > > checking for g++... g++ > > > checking whether we are using the GNU C++ compiler... yes > > > checking whether g++ accepts -g... yes > > > checking dependency style of g++... gcc3 > > > checking whether make sets $(MAKE)... (cached) yes > > > checking how to print strings... printf > > > checking for a sed that does not truncate output... (cached) /bin/sed > > > checking for grep that handles long lines and -e... /bin/grep > > > checking for egrep... /bin/grep -E > > > checking for fgrep... /bin/grep -F > > > checking for ld used by gcc... /usr/armv7a-unknown-linux-gnueabi/bin/ld > > > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is GNU > > ld... yes > > > checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B > > > checking the name lister (/usr/bin/nm -B) interface... BSD nm > > > checking whether ln -s works... yes > > > checking the maximum length of command line arguments... 1572864 > > > checking whether the shell understands some XSI constructs... yes > > > checking whether the shell understands "+="... yes > > > checking how to convert armv7l-unknown-linux-gnueabi file names to > > armv7l-unknown-linux-gnueabi format... func_convert_file_noop > > > checking how to convert armv7l-unknown-linux-gnueabi file names to > > toolchain format... func_convert_file_noop > > > checking for /usr/armv7a-unknown-linux-gnueabi/bin/ld option to reload > > object files... -r > > > checking for objdump... objdump > > > checking how to recognize dependent libraries... pass_all > > > checking for dlltool... no > > > checking how to associate runtime and link libraries... printf %s\n > > > checking for ar... ar > > > checking for archiver @FILE support... @ > > > checking for strip... strip > > > checking for ranlib... ranlib > > > checking command to parse /usr/bin/nm -B output from gcc object... ok > > > checking for sysroot... no > > > checking for mt... no > > > checking if : is a manifest tool... no > > > checking how to run the C preprocessor... gcc -E > > > checking for ANSI C header files... yes > > > checking for sys/types.h... yes > > > checking for sys/stat.h... yes > > > checking for stdlib.h... yes > > > checking for string.h... yes > > > checking for memory.h... yes > > > checking for strings.h... yes > > > checking for inttypes.h... yes > > > checking for stdint.h... yes > > > checking for unistd.h... yes > > > checking for dlfcn.h... yes > > > checking for objdir... .libs > > > checking if gcc supports -fno-rtti -fno-exceptions... no > > > checking for gcc option to produce PIC... -fPIC -DPIC > > > checking if gcc PIC flag -fPIC -DPIC works... yes > > > checking if gcc static flag -static works... yes > > > checking if gcc supports -c -o file.o... yes > > > checking if gcc supports -c -o file.o... (cached) yes > > > checking whether the gcc linker > > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... yes > > > checking whether -lc should be explicitly linked in... no > > > checking dynamic linker characteristics... GNU/Linux ld.so > > > checking how to hardcode library paths into programs... immediate > > > checking whether stripping libraries is possible... yes > > > checking if libtool supports shared libraries... yes > > > checking whether to build shared libraries... yes > > > checking whether to build static libraries... yes > > > checking how to run the C++ preprocessor... g++ -E > > > checking for ld used by g++... /usr/armv7a-unknown-linux-gnueabi/bin/ld > > > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is GNU > > ld... yes > > > checking whether the g++ linker > > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... yes > > > checking for g++ option to produce PIC... -fPIC -DPIC > > > checking if g++ PIC flag -fPIC -DPIC works... yes > > > checking if g++ static flag -static works... yes > > > checking if g++ supports -c -o file.o... yes > > > checking if g++ supports -c -o file.o... (cached) yes > > > checking whether the g++ linker > > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... yes > > > checking dynamic linker characteristics... (cached) GNU/Linux ld.so > > > checking how to hardcode library paths into programs... immediate > > > checking for dlopen in -ldl... yes > > > checking for pthread_create in -lpthread... yes > > > checking for uuid_generate in -luuid... yes > > > checking for inline... inline > > > checking for stdlib.h... (cached) yes > > > checking for GNU libc compatible malloc... yes > > > checking for gettimeofday... yes > > > checking for munmap... yes > > > checking for socket... yes > > > checking for strerror... yes > > > checking for strtol... yes > > > checking for sched_getcpu... yes > > > checking for sysconf... yes > > > checking for makeinfo... yes > > > checking urcu-bp.h usability... yes > > > checking urcu-bp.h presence... yes > > > checking for urcu-bp.h... yes > > > checking caa_likely()... yes > > > checking for synchronize_rcu_bp in -lurcu-bp... yes > > > checking for call_rcu_bp in -lurcu-bp... yes > > > checking library format for the host system... configure: error: unable > > to detect library format (unsupported architecture (armv7l)?) > > > > Does it help if you add a line: > > > > armv7l) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; > > > > near line 188 of configure.ac ? > > > > What we did in userspace RCU is to use "arm*". > > > > Thanks, > > > > Mathieu > > > > > > > > > > > _______________________________________________ > > > lttng-dev mailing list > > > lttng-dev at lists.lttng.org > > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Fri May 18 11:49:26 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 18 May 2012 11:49:26 -0400 Subject: [lttng-dev] compiling lttng 2.0.1 statically into kernel tree 3.4.0-rc7 fails In-Reply-To: References: Message-ID: <20120518154926.GA18114@Krystal> * Paul Barrette (paulbarrette at gmail.com) wrote: > Hi all, > I added the lttng-module to my kernel tree with the goal of making it a > tristate option. I added a Kconfig and a few Makefile changes (removed the > rules at end). I am able to compile lttng-module as a module (M), but > compiling statically fails at link time with some redefinition errors (log > below). You might want to compare with the LTTng in drivers/staging/lttng of the LTSI kernel. See http://git.linuxfoundation.org/?p=ltsi-kernel.git;a=summary Thanks, Mathieu > > Details: > target: powerpc > kernel config: mpc85xx_defconfig > lttng-modules 2.0.1 plus patch > > commit 6bd5e64e29cf1c251632501e45d61be6f16257ba > Author: Mathieu Desnoyers > Date: Thu Apr 26 17:40:31 2012 -0400 > > Fix: update signal instrumentation for 3.4 kernel > > Fix #226 > > Any ideas? > > LD drivers/staging/lttng2/probes/built-in.o > LD drivers/staging/lttng2/built-in.o > drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x35c): multiple > definition of `__tracepoint_lttng_statedump_network_interface' > drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x64): first > defined here > drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x320): multiple > definition of `__tracepoint_lttng_statedump_process_state' > drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x14): first > defined here > drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x2f8): multiple > definition of `__tracepoint_lttng_statedump_start' > drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x0): first defined > here > drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x334): multiple > definition of `__tracepoint_lttng_statedump_file_descriptor' > drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x28): first > defined here > drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x370): multiple > definition of `__tracepoint_lttng_statedump_interrupt' > drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x50): first > defined here > drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x348): multiple > definition of `__tracepoint_lttng_statedump_vm_map' > drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x3c): first > defined here > drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x30c): multiple > definition of `__tracepoint_lttng_statedump_end' > drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x78): first > defined here > make[3]: *** [drivers/staging/lttng2/built-in.o] Error 1 > make[2]: *** [drivers/staging/lttng2] Error 2 > make[1]: *** [drivers/staging] Error 2 > make: *** [drivers] Error 2 > > > > Thanks > Pb > > -- > -- > Paul Barrette > Linked In Profile > http://sitarplayer.net > ? > \\=^% > (*)---(*) > ^^~~^~~~^^^~~^ > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Fri May 18 12:44:40 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 18 May 2012 12:44:40 -0400 Subject: [lttng-dev] HOW TO DOWNLOAD LTTng 2.0 stable? In-Reply-To: References: <4FB3EDC0.7080006@polymtl.ca> <4FB50A3E.7030508@polymtl.ca> <20120517143031.GA30839@Krystal> <20120518151850.GA17152@Krystal> Message-ID: <20120518164440.GB18739@Krystal> Hi Vanni, * Vanni Genua (vannigenua at gmail.com) wrote: > I asked you about the HEAD download (mater and stable2.0), > I found its size was about 180kB, whereas the 2.0.1 was over 500KB. > I also wrote you that the HEAD (master?) missed the configure file, so > it was not possible to run ./configure ) The lttng-ust README file states to run ./bootstrap before configure. > May you post me the exact link where the full HEAD is? git clone git://git.lttng.org/lttng-ust.git cd lttng-ust #then either: git checkout master (for master branch) # or git checkout stable-2.0 Side-note: the linking problem you are seeing might be caused by an issue in lttng-ust Makefile.am regarding support for cross-compiling. Unfortunately, I don't have a setup readily available, but if other people could test cross-build and report issues, it might help us. Thanks! Mathieu > I'm using gcc 4.4.2 (I guess, because now I'm not at the office). > Thanks. > Vanni > > On 5/18/12, Mathieu Desnoyers wrote: > > * Vanni Genua (vannigenua at gmail.com) wrote: > >> I did it a minute ago, now the problems are the undefined references at > >> the > >> end of this logs: > >> > >> localhost lttng-ust-2.0.1 # ./configure --build=armv7a-unknown-linux- > >> gnueabi > > > > This looks like a problem with your toolchain (gcc/ld/...), since AFAIK > > Alexandre is able to cross-build for ARMv7 on Ubuntu. You should ask > > your distribution vendor. > > > > Also, you seem to be still using lttng-ust 2.0.1 instead of "HEAD". > > Which commit ID are you using ? > > > > Thanks, > > > > Mathieu > > > > > > > >> > >> checking build system type... > >> armv7a-unknown-linux-gnueabi > >> > >> checking host system type... > >> armv7a-unknown-linux-gnueabi > >> > >> checking target system type... > >> armv7a-unknown-linux-gnueabi > >> > >> checking how to convert armv7a-unknown-linux-gnueabi file names to > >> armv7a-unknown-linux-gnueabi format... > >> func_convert_file_noop > >> checking how to convert armv7a-unknown-linux-gnueabi file names to > >> toolchain format... > >> func_convert_file_noop > >> checking library format for the host system... > >> elf32-littlearm > >> > >> configure: creating > >> ./config.status > >> > >> config.status: creating > >> Makefile > >> > >> config.status: creating > >> doc/Makefile > >> > >> config.status: creating > >> doc/examples/Makefile > >> > >> config.status: creating > >> include/Makefile > >> > >> config.status: creating > >> include/lttng/ust-version.h > >> > >> config.status: creating > >> snprintf/Makefile > >> > >> config.status: creating > >> libringbuffer/Makefile > >> > >> config.status: creating > >> liblttng-ust-comm/Makefile > >> > >> config.status: creating > >> liblttng-ust/Makefile > >> > >> config.status: creating > >> liblttng-ust-ctl/Makefile > >> > >> config.status: creating > >> liblttng-ust-fork/Makefile > >> > >> config.status: creating > >> liblttng-ust-java/Makefile > >> > >> config.status: creating > >> liblttng-ust-libc-wrapper/Makefile > >> > >> config.status: creating > >> tools/Makefile > >> > >> config.status: creating > >> tests/Makefile > >> > >> config.status: creating > >> tests/hello/Makefile > >> > >> config.status: creating > >> tests/hello-static-lib/Makefile > >> > >> config.status: creating > >> tests/hello.cxx/Makefile > >> > >> config.status: creating > >> tests/demo/Makefile > >> > >> config.status: creating > >> tests/fork/Makefile > >> > >> config.status: creating > >> tests/ust-basic-tracing/Makefile > >> > >> config.status: creating > >> tests/ust-multi-test/Makefile > >> > >> config.status: creating > >> lttng-ust.pc > >> > >> config.status: creating > >> config.h > >> > >> config.status: config.h is > >> unchanged > >> > >> config.status: creating > >> include/lttng/ust-config.h > >> > >> config.status: include/lttng/ust-config.h is > >> unchanged > >> > >> config.status: executing depfiles > >> commands > >> > >> config.status: executing libtool > >> commands > >> > >> > >> > >> Version name: > >> Annedd'ale > >> > >> New type of beer, 100% from Quebec, flavored with sapin beaumier needles, > >> with a touch of > >> hops. > >> > >> > >> LTTng-UST will be built with the following > >> options: > >> > >> Library format: > >> elf32-littlearm > >> > >> > >> > >> Java support (JNI): > >> Disabled > >> > >> sdt.h integration: > >> Disabled > >> > >> > >> > >> Type 'make' to > >> compile. > >> > >> localhost lttng-ust-2.0.1 # > >> make > >> > >> make > >> all-recursive > >> > >> make[1]: Entering directory > >> `/usr/src/lttng-ust-2.0.1' > >> > >> Making all in > >> . > >> > >> make[2]: Entering directory > >> `/usr/src/lttng-ust-2.0.1' > >> > >> make[2]: Leaving directory > >> `/usr/src/lttng-ust-2.0.1' > >> > >> Making all in > >> include > >> > >> make[2]: Entering directory > >> `/usr/src/lttng-ust-2.0.1/include' > >> > >> make[2]: Nothing to be done for > >> `all'. > >> > >> make[2]: Leaving directory > >> `/usr/src/lttng-ust-2.0.1/include' > >> > >> Making all in > >> snprintf > >> > >> make[2]: Entering directory > >> `/usr/src/lttng-ust-2.0.1/snprintf' > >> > >> make[2]: Nothing to be done for > >> `all'. > >> > >> make[2]: Leaving directory > >> `/usr/src/lttng-ust-2.0.1/snprintf' > >> > >> Making all in > >> libringbuffer > >> > >> make[2]: Entering directory > >> `/usr/src/lttng-ust-2.0.1/libringbuffer' > >> > >> CC > >> libringbuffer_la-ring_buffer_backend.lo > >> > >> CC > >> libringbuffer_la-ring_buffer_frontend.lo > >> > >> CCLD libringbuffer.la > >> > >> make[2]: Leaving directory > >> `/usr/src/lttng-ust-2.0.1/libringbuffer' > >> > >> Making all in > >> liblttng-ust-comm > >> > >> make[2]: Entering directory > >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' > >> > >> make[2]: Nothing to be done for > >> `all'. > >> > >> make[2]: Leaving directory > >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' > >> > >> Making all in > >> liblttng-ust > >> > >> make[2]: Entering directory > >> `/usr/src/lttng-ust-2.0.1/liblttng-ust' > >> > >> CC > >> liblttng_ust_tracepoint_la-tracepoint.lo > >> > >> CCLD liblttng-ust-tracepoint.la > >> > >> CC > >> lttng-ust-comm.lo > >> > >> CC > >> lttng-ust-abi.lo > >> > >> CC > >> ltt-probes.lo > >> > >> CC > >> lttng-probe-ust.lo > >> > >> CC > >> lttng-context-vtid.lo > >> > >> CC > >> lttng-context-vpid.lo > >> > >> CC > >> lttng-context-pthread-id.lo > >> > >> CC > >> lttng-context-procname.lo > >> > >> CC > >> ltt-context.lo > >> > >> CC > >> ltt-events.lo > >> > >> CCLD liblttng-ust-runtime.la > >> > >> CC > >> ust-core.lo > >> > >> CC > >> ltt-ring-buffer-client-discard.lo > >> > >> CC > >> ltt-ring-buffer-client-overwrite.lo > >> > >> CC > >> ltt-ring-buffer-metadata-client.lo > >> > >> CCLD liblttng-ust-support.la > >> > >> CCLD liblttng-ust.la > >> > >> /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/../../../../armv7a-unknown-linux-gnueabi/bin/ld: > >> warning: creating a DT_TEXTREL in object. > >> copying selected object files to avoid basename > >> conflicts... > >> > >> make[2]: Leaving directory > >> `/usr/src/lttng-ust-2.0.1/liblttng-ust' > >> > >> Making all in > >> liblttng-ust-ctl > >> > >> make[2]: Entering directory > >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' > >> > >> CC > >> ustctl.lo > >> > >> CCLD liblttng-ust-ctl.la > >> > >> /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/../../../../armv7a-unknown-linux-gnueabi/bin/ld: > >> warning: creating a DT_TEXTREL in object. > >> make[2]: Leaving directory > >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' > >> > >> Making all in > >> liblttng-ust-fork > >> > >> make[2]: Entering directory > >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' > >> > >> CCLD liblttng-ust-fork.la > >> > >> make[2]: Leaving directory > >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' > >> > >> Making all in > >> liblttng-ust-libc-wrapper > >> > >> make[2]: Entering directory > >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' > >> > >> CC > >> lttng-ust-malloc.lo > >> > >> CCLD liblttng-ust-libc-wrapper.la > >> > >> make[2]: Leaving directory > >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' > >> > >> Making all in > >> tools > >> > >> make[2]: Entering directory > >> `/usr/src/lttng-ust-2.0.1/tools' > >> > >> make[2]: Nothing to be done for > >> `all'. > >> > >> make[2]: Leaving directory > >> `/usr/src/lttng-ust-2.0.1/tools' > >> > >> Making all in > >> tests > >> > >> make[2]: Entering directory > >> `/usr/src/lttng-ust-2.0.1/tests' > >> > >> Making all in > >> . > >> > >> make[3]: Entering directory > >> `/usr/src/lttng-ust-2.0.1/tests' > >> > >> make[3]: Nothing to be done for > >> `all-am'. > >> > >> make[3]: Leaving directory > >> `/usr/src/lttng-ust-2.0.1/tests' > >> > >> Making all in > >> hello > >> > >> make[3]: Entering directory > >> `/usr/src/lttng-ust-2.0.1/tests/hello' > >> > >> CC > >> tp.o > >> > >> CCLD > >> hello > >> > >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > >> `__num_possible_cpus' > >> > >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > >> `shm_object_table_create' > >> > >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > >> `shm_object_table_append_shadow' > >> > >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > >> `shm_object_table_append' > >> > >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > >> `zalloc_shm' > >> > >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > >> `_get_num_possible_cpus' > >> > >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > >> `align_shm' > >> > >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > >> `shm_object_table_destroy' > >> > >> collect2: ld returned 1 exit > >> status > >> > >> make[3]: *** [hello] Error > >> 1 > >> > >> make[3]: Leaving directory > >> `/usr/src/lttng-ust-2.0.1/tests/hello' > >> > >> make[2]: *** [all-recursive] Error > >> 1 > >> > >> make[2]: Leaving directory > >> `/usr/src/lttng-ust-2.0.1/tests' > >> > >> make[1]: *** [all-recursive] Error > >> 1 > >> > >> make[1]: Leaving directory > >> `/usr/src/lttng-ust-2.0.1' > >> > >> make: *** [all] Error > >> 2 > >> > >> localhost lttng-ust-2.0.1 # > >> > >> > >> On Thu, May 17, 2012 at 2:30 PM, Mathieu Desnoyers < > >> mathieu.desnoyers at efficios.com> wrote: > >> > >> > * Alexandre Montplaisir (alexandre.montplaisir at polymtl.ca) wrote: > >> > > This is an interesting problem, I'll forward it to the mailing list. > >> > > > >> > > > >> > > On 12-05-17 10:02 AM, Vanni Genua wrote: > >> > > > Also why I get this error? > >> > > > see the attached log file. > >> > > > Best regards. > >> > > > V.G. > >> > > > > >> > > > > >> > > > >> > > localhost lttng-ust-2.0.1 # ./configure > >> > > checking build system type... armv7l-unknown-linux-gnueabi > >> > > checking host system type... armv7l-unknown-linux-gnueabi > >> > > checking target system type... armv7l-unknown-linux-gnueabi > >> > > checking for a BSD-compatible install... /usr/bin/install -c > >> > > checking whether build environment is sane... yes > >> > > checking for a thread-safe mkdir -p... /bin/mkdir -p > >> > > checking for gawk... gawk > >> > > checking whether make sets $(MAKE)... yes > >> > > checking whether make supports nested variables... yes > >> > > checking for a sed that does not truncate output... /bin/sed > >> > > checking for gcc... gcc > >> > > checking whether the C compiler works... yes > >> > > checking for C compiler default output file name... a.out > >> > > checking for suffix of executables... > >> > > checking whether we are cross compiling... no > >> > > checking for suffix of object files... o > >> > > checking whether we are using the GNU C compiler... yes > >> > > checking whether gcc accepts -g... yes > >> > > checking for gcc option to accept ISO C89... none needed > >> > > checking for style of include used by make... GNU > >> > > checking dependency style of gcc... gcc3 > >> > > checking for g++... g++ > >> > > checking whether we are using the GNU C++ compiler... yes > >> > > checking whether g++ accepts -g... yes > >> > > checking dependency style of g++... gcc3 > >> > > checking whether make sets $(MAKE)... (cached) yes > >> > > checking how to print strings... printf > >> > > checking for a sed that does not truncate output... (cached) /bin/sed > >> > > checking for grep that handles long lines and -e... /bin/grep > >> > > checking for egrep... /bin/grep -E > >> > > checking for fgrep... /bin/grep -F > >> > > checking for ld used by gcc... > >> > > /usr/armv7a-unknown-linux-gnueabi/bin/ld > >> > > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is > >> > > GNU > >> > ld... yes > >> > > checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B > >> > > checking the name lister (/usr/bin/nm -B) interface... BSD nm > >> > > checking whether ln -s works... yes > >> > > checking the maximum length of command line arguments... 1572864 > >> > > checking whether the shell understands some XSI constructs... yes > >> > > checking whether the shell understands "+="... yes > >> > > checking how to convert armv7l-unknown-linux-gnueabi file names to > >> > armv7l-unknown-linux-gnueabi format... func_convert_file_noop > >> > > checking how to convert armv7l-unknown-linux-gnueabi file names to > >> > toolchain format... func_convert_file_noop > >> > > checking for /usr/armv7a-unknown-linux-gnueabi/bin/ld option to > >> > > reload > >> > object files... -r > >> > > checking for objdump... objdump > >> > > checking how to recognize dependent libraries... pass_all > >> > > checking for dlltool... no > >> > > checking how to associate runtime and link libraries... printf %s\n > >> > > checking for ar... ar > >> > > checking for archiver @FILE support... @ > >> > > checking for strip... strip > >> > > checking for ranlib... ranlib > >> > > checking command to parse /usr/bin/nm -B output from gcc object... ok > >> > > checking for sysroot... no > >> > > checking for mt... no > >> > > checking if : is a manifest tool... no > >> > > checking how to run the C preprocessor... gcc -E > >> > > checking for ANSI C header files... yes > >> > > checking for sys/types.h... yes > >> > > checking for sys/stat.h... yes > >> > > checking for stdlib.h... yes > >> > > checking for string.h... yes > >> > > checking for memory.h... yes > >> > > checking for strings.h... yes > >> > > checking for inttypes.h... yes > >> > > checking for stdint.h... yes > >> > > checking for unistd.h... yes > >> > > checking for dlfcn.h... yes > >> > > checking for objdir... .libs > >> > > checking if gcc supports -fno-rtti -fno-exceptions... no > >> > > checking for gcc option to produce PIC... -fPIC -DPIC > >> > > checking if gcc PIC flag -fPIC -DPIC works... yes > >> > > checking if gcc static flag -static works... yes > >> > > checking if gcc supports -c -o file.o... yes > >> > > checking if gcc supports -c -o file.o... (cached) yes > >> > > checking whether the gcc linker > >> > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... > >> > yes > >> > > checking whether -lc should be explicitly linked in... no > >> > > checking dynamic linker characteristics... GNU/Linux ld.so > >> > > checking how to hardcode library paths into programs... immediate > >> > > checking whether stripping libraries is possible... yes > >> > > checking if libtool supports shared libraries... yes > >> > > checking whether to build shared libraries... yes > >> > > checking whether to build static libraries... yes > >> > > checking how to run the C++ preprocessor... g++ -E > >> > > checking for ld used by g++... > >> > > /usr/armv7a-unknown-linux-gnueabi/bin/ld > >> > > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is > >> > > GNU > >> > ld... yes > >> > > checking whether the g++ linker > >> > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... > >> > yes > >> > > checking for g++ option to produce PIC... -fPIC -DPIC > >> > > checking if g++ PIC flag -fPIC -DPIC works... yes > >> > > checking if g++ static flag -static works... yes > >> > > checking if g++ supports -c -o file.o... yes > >> > > checking if g++ supports -c -o file.o... (cached) yes > >> > > checking whether the g++ linker > >> > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... > >> > yes > >> > > checking dynamic linker characteristics... (cached) GNU/Linux ld.so > >> > > checking how to hardcode library paths into programs... immediate > >> > > checking for dlopen in -ldl... yes > >> > > checking for pthread_create in -lpthread... yes > >> > > checking for uuid_generate in -luuid... yes > >> > > checking for inline... inline > >> > > checking for stdlib.h... (cached) yes > >> > > checking for GNU libc compatible malloc... yes > >> > > checking for gettimeofday... yes > >> > > checking for munmap... yes > >> > > checking for socket... yes > >> > > checking for strerror... yes > >> > > checking for strtol... yes > >> > > checking for sched_getcpu... yes > >> > > checking for sysconf... yes > >> > > checking for makeinfo... yes > >> > > checking urcu-bp.h usability... yes > >> > > checking urcu-bp.h presence... yes > >> > > checking for urcu-bp.h... yes > >> > > checking caa_likely()... yes > >> > > checking for synchronize_rcu_bp in -lurcu-bp... yes > >> > > checking for call_rcu_bp in -lurcu-bp... yes > >> > > checking library format for the host system... configure: error: > >> > > unable > >> > to detect library format (unsupported architecture (armv7l)?) > >> > > >> > Does it help if you add a line: > >> > > >> > armv7l) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; > >> > > >> > near line 188 of configure.ac ? > >> > > >> > What we did in userspace RCU is to use "arm*". > >> > > >> > Thanks, > >> > > >> > Mathieu > >> > > >> > > > >> > > > >> > > _______________________________________________ > >> > > lttng-dev mailing list > >> > > lttng-dev at lists.lttng.org > >> > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > >> > > >> > -- > >> > Mathieu Desnoyers > >> > Operating System Efficiency R&D Consultant > >> > EfficiOS Inc. > >> > http://www.efficios.com > >> > > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Fri May 18 12:47:37 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 18 May 2012 12:47:37 -0400 Subject: [lttng-dev] compiling lttng 2.0.1 statically into kernel tree 3.4.0-rc7 fails In-Reply-To: <20120518154926.GA18114@Krystal> References: <20120518154926.GA18114@Krystal> Message-ID: <20120518164737.GD18739@Krystal> * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > * Paul Barrette (paulbarrette at gmail.com) wrote: > > Hi all, > > I added the lttng-module to my kernel tree with the goal of making it a > > tristate option. I added a Kconfig and a few Makefile changes (removed the > > rules at end). I am able to compile lttng-module as a module (M), but > > compiling statically fails at link time with some redefinition errors (log > > below). > > You might want to compare with the LTTng in drivers/staging/lttng of the > LTSI kernel. See > > http://git.linuxfoundation.org/?p=ltsi-kernel.git;a=summary Following up a private exchange: This issue was fixed by: "commit c87fb51b023540388493442049d127fa9a388af8 Author: Mathieu Desnoyers Date: Thu Apr 26 17:40:31 2012 -0400 Fix: update signal instrumentation for 3.4 kernel Fix #226 Signed-off-by: Mathieu Desnoyers " in stable-2.0, which is also in the master branch. Thanks, Mathieu > > Thanks, > > Mathieu > > > > > Details: > > target: powerpc > > kernel config: mpc85xx_defconfig > > lttng-modules 2.0.1 plus patch > > > > commit 6bd5e64e29cf1c251632501e45d61be6f16257ba > > Author: Mathieu Desnoyers > > Date: Thu Apr 26 17:40:31 2012 -0400 > > > > Fix: update signal instrumentation for 3.4 kernel > > > > Fix #226 > > > > Any ideas? > > > > LD drivers/staging/lttng2/probes/built-in.o > > LD drivers/staging/lttng2/built-in.o > > drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x35c): multiple > > definition of `__tracepoint_lttng_statedump_network_interface' > > drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x64): first > > defined here > > drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x320): multiple > > definition of `__tracepoint_lttng_statedump_process_state' > > drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x14): first > > defined here > > drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x2f8): multiple > > definition of `__tracepoint_lttng_statedump_start' > > drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x0): first defined > > here > > drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x334): multiple > > definition of `__tracepoint_lttng_statedump_file_descriptor' > > drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x28): first > > defined here > > drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x370): multiple > > definition of `__tracepoint_lttng_statedump_interrupt' > > drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x50): first > > defined here > > drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x348): multiple > > definition of `__tracepoint_lttng_statedump_vm_map' > > drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x3c): first > > defined here > > drivers/staging/lttng2/probes/built-in.o:(__tracepoints+0x30c): multiple > > definition of `__tracepoint_lttng_statedump_end' > > drivers/staging/lttng2/lttng-statedump.o:(__tracepoints+0x78): first > > defined here > > make[3]: *** [drivers/staging/lttng2/built-in.o] Error 1 > > make[2]: *** [drivers/staging/lttng2] Error 2 > > make[1]: *** [drivers/staging] Error 2 > > make: *** [drivers] Error 2 > > > > > > > > Thanks > > Pb > > > > -- > > -- > > Paul Barrette > > Linked In Profile > > http://sitarplayer.net > > ? > > \\=^% > > (*)---(*) > > ^^~~^~~~^^^~~^ > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From cespedes at ieee.org Fri May 18 15:41:42 2012 From: cespedes at ieee.org (=?ISO-8859-1?Q?Carlos_C=E9spedes?=) Date: Fri, 18 May 2012 13:41:42 -0600 Subject: [lttng-dev] cannot compile babeltrace in cygwin because of undefined symbols Message-ID: Hello there, Sadly I have not been able to compile babeltrace uder cygwin because it has undefined symbols. This is the error I get from make: .libs/ctf-text.o: In function `ctf_text_write_event': /cygdrive/c/Users/cespedec/Downloads/babeltrace/babeltrace-1.0.0-rc2/formats/ctf-text/ctf-text.c:249: undefined reference to `_ctf_print_timestamp' /cygdrive/c/Users/cespedec/Downloads/babeltrace/babeltrace-1.0.0-rc2/formats/ctf-text/ctf-text.c:251: undefined reference to `_ctf_print_timestamp' /cygdrive/c/Users/cespedec/Downloads/babeltrace/babeltrace-1.0.0-rc2/formats/ctf-text/ctf-text.c:263: undefined reference to `_ctf_print_timestamp' collect2: ld returned 1 exit status Makefile:374: recipe for target `libbabeltrace-ctf-text.la' failed I am using $LDFLAGS=-no-undefined which is a linker flag passed to libtool in order not to allow undefined symbols. If I don't use the flag then I get other warnings about: libtool: link: warning: undefined symbols not allowed in i686-pc-cygwin shared libraries *** Warning: This system can not link to static lib archive ../mailbox/libmailutils.la. *** I have the capability to make that library automatically link in when *** you link to this library. But I can only do this if you have a *** shared version of the library, which you do not appear to have. libtool: link: warning: undefined symbols not allowed in i686-pc-cygwin shared libraries The libtool issue is well explained on this thread: http://cygwin.com/ml/cygwin/2005-08/msg00052.html Simply put cygwin's libtool does not cope well with undefined symbols. Thanks for your help. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mathieu.desnoyers at efficios.com Fri May 18 15:41:49 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 18 May 2012 15:41:49 -0400 Subject: [lttng-dev] HOW TO DOWNLOAD LTTng 2.0 stable? In-Reply-To: References: <4FB50A3E.7030508@polymtl.ca> <20120517143031.GA30839@Krystal> <20120518151850.GA17152@Krystal> <20120518164440.GB18739@Krystal> Message-ID: <20120518194149.GA20850@Krystal> Make sure all the dependencies listed in the README are installed (also those for using bootstrap). Thanks, Mathieu * Vanni Genua (vannigenua at gmail.com) wrote: > I tried to ./bootstrap but it didn't work. > tomorrow I'll try to checkout master as you have written. > then I'm going to tell you if it will work. > Thanks. > Vanni > > On 5/18/12, Mathieu Desnoyers wrote: > > Hi Vanni, > > > > * Vanni Genua (vannigenua at gmail.com) wrote: > >> I asked you about the HEAD download (mater and stable2.0), > >> I found its size was about 180kB, whereas the 2.0.1 was over 500KB. > >> I also wrote you that the HEAD (master?) missed the configure file, so > >> it was not possible to run ./configure ) > > > > The lttng-ust README file states to run ./bootstrap before configure. > > > >> May you post me the exact link where the full HEAD is? > > > > git clone git://git.lttng.org/lttng-ust.git > > cd lttng-ust > > #then either: > > git checkout master (for master branch) > > > > # or > > git checkout stable-2.0 > > > > Side-note: the linking problem you are seeing might be caused by an > > issue in lttng-ust Makefile.am regarding support for cross-compiling. > > Unfortunately, I don't have a setup readily available, but if other > > people could test cross-build and report issues, it might help us. > > > > Thanks! > > > > Mathieu > > > >> I'm using gcc 4.4.2 (I guess, because now I'm not at the office). > >> Thanks. > >> Vanni > >> > >> On 5/18/12, Mathieu Desnoyers wrote: > >> > * Vanni Genua (vannigenua at gmail.com) wrote: > >> >> I did it a minute ago, now the problems are the undefined references > >> >> at > >> >> the > >> >> end of this logs: > >> >> > >> >> localhost lttng-ust-2.0.1 # ./configure --build=armv7a-unknown-linux- > >> >> gnueabi > >> > > >> > This looks like a problem with your toolchain (gcc/ld/...), since AFAIK > >> > Alexandre is able to cross-build for ARMv7 on Ubuntu. You should ask > >> > your distribution vendor. > >> > > >> > Also, you seem to be still using lttng-ust 2.0.1 instead of "HEAD". > >> > Which commit ID are you using ? > >> > > >> > Thanks, > >> > > >> > Mathieu > >> > > >> > > >> > > >> >> > >> >> checking build system type... > >> >> armv7a-unknown-linux-gnueabi > >> >> > >> >> checking host system type... > >> >> armv7a-unknown-linux-gnueabi > >> >> > >> >> checking target system type... > >> >> armv7a-unknown-linux-gnueabi > >> >> > >> >> checking how to convert armv7a-unknown-linux-gnueabi file names to > >> >> armv7a-unknown-linux-gnueabi format... > >> >> func_convert_file_noop > >> >> checking how to convert armv7a-unknown-linux-gnueabi file names to > >> >> toolchain format... > >> >> func_convert_file_noop > >> >> checking library format for the host system... > >> >> elf32-littlearm > >> >> > >> >> configure: creating > >> >> ./config.status > >> >> > >> >> config.status: creating > >> >> Makefile > >> >> > >> >> config.status: creating > >> >> doc/Makefile > >> >> > >> >> config.status: creating > >> >> doc/examples/Makefile > >> >> > >> >> config.status: creating > >> >> include/Makefile > >> >> > >> >> config.status: creating > >> >> include/lttng/ust-version.h > >> >> > >> >> config.status: creating > >> >> snprintf/Makefile > >> >> > >> >> config.status: creating > >> >> libringbuffer/Makefile > >> >> > >> >> config.status: creating > >> >> liblttng-ust-comm/Makefile > >> >> > >> >> config.status: creating > >> >> liblttng-ust/Makefile > >> >> > >> >> config.status: creating > >> >> liblttng-ust-ctl/Makefile > >> >> > >> >> config.status: creating > >> >> liblttng-ust-fork/Makefile > >> >> > >> >> config.status: creating > >> >> liblttng-ust-java/Makefile > >> >> > >> >> config.status: creating > >> >> liblttng-ust-libc-wrapper/Makefile > >> >> > >> >> config.status: creating > >> >> tools/Makefile > >> >> > >> >> config.status: creating > >> >> tests/Makefile > >> >> > >> >> config.status: creating > >> >> tests/hello/Makefile > >> >> > >> >> config.status: creating > >> >> tests/hello-static-lib/Makefile > >> >> > >> >> config.status: creating > >> >> tests/hello.cxx/Makefile > >> >> > >> >> config.status: creating > >> >> tests/demo/Makefile > >> >> > >> >> config.status: creating > >> >> tests/fork/Makefile > >> >> > >> >> config.status: creating > >> >> tests/ust-basic-tracing/Makefile > >> >> > >> >> config.status: creating > >> >> tests/ust-multi-test/Makefile > >> >> > >> >> config.status: creating > >> >> lttng-ust.pc > >> >> > >> >> config.status: creating > >> >> config.h > >> >> > >> >> config.status: config.h is > >> >> unchanged > >> >> > >> >> config.status: creating > >> >> include/lttng/ust-config.h > >> >> > >> >> config.status: include/lttng/ust-config.h is > >> >> unchanged > >> >> > >> >> config.status: executing depfiles > >> >> commands > >> >> > >> >> config.status: executing libtool > >> >> commands > >> >> > >> >> > >> >> > >> >> Version name: > >> >> Annedd'ale > >> >> > >> >> New type of beer, 100% from Quebec, flavored with sapin beaumier > >> >> needles, > >> >> with a touch of > >> >> hops. > >> >> > >> >> > >> >> LTTng-UST will be built with the following > >> >> options: > >> >> > >> >> Library format: > >> >> elf32-littlearm > >> >> > >> >> > >> >> > >> >> Java support (JNI): > >> >> Disabled > >> >> > >> >> sdt.h integration: > >> >> Disabled > >> >> > >> >> > >> >> > >> >> Type 'make' to > >> >> compile. > >> >> > >> >> localhost lttng-ust-2.0.1 # > >> >> make > >> >> > >> >> make > >> >> all-recursive > >> >> > >> >> make[1]: Entering directory > >> >> `/usr/src/lttng-ust-2.0.1' > >> >> > >> >> Making all in > >> >> . > >> >> > >> >> make[2]: Entering directory > >> >> `/usr/src/lttng-ust-2.0.1' > >> >> > >> >> make[2]: Leaving directory > >> >> `/usr/src/lttng-ust-2.0.1' > >> >> > >> >> Making all in > >> >> include > >> >> > >> >> make[2]: Entering directory > >> >> `/usr/src/lttng-ust-2.0.1/include' > >> >> > >> >> make[2]: Nothing to be done for > >> >> `all'. > >> >> > >> >> make[2]: Leaving directory > >> >> `/usr/src/lttng-ust-2.0.1/include' > >> >> > >> >> Making all in > >> >> snprintf > >> >> > >> >> make[2]: Entering directory > >> >> `/usr/src/lttng-ust-2.0.1/snprintf' > >> >> > >> >> make[2]: Nothing to be done for > >> >> `all'. > >> >> > >> >> make[2]: Leaving directory > >> >> `/usr/src/lttng-ust-2.0.1/snprintf' > >> >> > >> >> Making all in > >> >> libringbuffer > >> >> > >> >> make[2]: Entering directory > >> >> `/usr/src/lttng-ust-2.0.1/libringbuffer' > >> >> > >> >> CC > >> >> libringbuffer_la-ring_buffer_backend.lo > >> >> > >> >> CC > >> >> libringbuffer_la-ring_buffer_frontend.lo > >> >> > >> >> CCLD libringbuffer.la > >> >> > >> >> make[2]: Leaving directory > >> >> `/usr/src/lttng-ust-2.0.1/libringbuffer' > >> >> > >> >> Making all in > >> >> liblttng-ust-comm > >> >> > >> >> make[2]: Entering directory > >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' > >> >> > >> >> make[2]: Nothing to be done for > >> >> `all'. > >> >> > >> >> make[2]: Leaving directory > >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' > >> >> > >> >> Making all in > >> >> liblttng-ust > >> >> > >> >> make[2]: Entering directory > >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust' > >> >> > >> >> CC > >> >> liblttng_ust_tracepoint_la-tracepoint.lo > >> >> > >> >> CCLD liblttng-ust-tracepoint.la > >> >> > >> >> CC > >> >> lttng-ust-comm.lo > >> >> > >> >> CC > >> >> lttng-ust-abi.lo > >> >> > >> >> CC > >> >> ltt-probes.lo > >> >> > >> >> CC > >> >> lttng-probe-ust.lo > >> >> > >> >> CC > >> >> lttng-context-vtid.lo > >> >> > >> >> CC > >> >> lttng-context-vpid.lo > >> >> > >> >> CC > >> >> lttng-context-pthread-id.lo > >> >> > >> >> CC > >> >> lttng-context-procname.lo > >> >> > >> >> CC > >> >> ltt-context.lo > >> >> > >> >> CC > >> >> ltt-events.lo > >> >> > >> >> CCLD liblttng-ust-runtime.la > >> >> > >> >> CC > >> >> ust-core.lo > >> >> > >> >> CC > >> >> ltt-ring-buffer-client-discard.lo > >> >> > >> >> CC > >> >> ltt-ring-buffer-client-overwrite.lo > >> >> > >> >> CC > >> >> ltt-ring-buffer-metadata-client.lo > >> >> > >> >> CCLD liblttng-ust-support.la > >> >> > >> >> CCLD liblttng-ust.la > >> >> > >> >> /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/../../../../armv7a-unknown-linux-gnueabi/bin/ld: > >> >> warning: creating a DT_TEXTREL in object. > >> >> copying selected object files to avoid basename > >> >> conflicts... > >> >> > >> >> make[2]: Leaving directory > >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust' > >> >> > >> >> Making all in > >> >> liblttng-ust-ctl > >> >> > >> >> make[2]: Entering directory > >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' > >> >> > >> >> CC > >> >> ustctl.lo > >> >> > >> >> CCLD liblttng-ust-ctl.la > >> >> > >> >> /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/../../../../armv7a-unknown-linux-gnueabi/bin/ld: > >> >> warning: creating a DT_TEXTREL in object. > >> >> make[2]: Leaving directory > >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' > >> >> > >> >> Making all in > >> >> liblttng-ust-fork > >> >> > >> >> make[2]: Entering directory > >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' > >> >> > >> >> CCLD liblttng-ust-fork.la > >> >> > >> >> make[2]: Leaving directory > >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' > >> >> > >> >> Making all in > >> >> liblttng-ust-libc-wrapper > >> >> > >> >> make[2]: Entering directory > >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' > >> >> > >> >> CC > >> >> lttng-ust-malloc.lo > >> >> > >> >> CCLD liblttng-ust-libc-wrapper.la > >> >> > >> >> make[2]: Leaving directory > >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' > >> >> > >> >> Making all in > >> >> tools > >> >> > >> >> make[2]: Entering directory > >> >> `/usr/src/lttng-ust-2.0.1/tools' > >> >> > >> >> make[2]: Nothing to be done for > >> >> `all'. > >> >> > >> >> make[2]: Leaving directory > >> >> `/usr/src/lttng-ust-2.0.1/tools' > >> >> > >> >> Making all in > >> >> tests > >> >> > >> >> make[2]: Entering directory > >> >> `/usr/src/lttng-ust-2.0.1/tests' > >> >> > >> >> Making all in > >> >> . > >> >> > >> >> make[3]: Entering directory > >> >> `/usr/src/lttng-ust-2.0.1/tests' > >> >> > >> >> make[3]: Nothing to be done for > >> >> `all-am'. > >> >> > >> >> make[3]: Leaving directory > >> >> `/usr/src/lttng-ust-2.0.1/tests' > >> >> > >> >> Making all in > >> >> hello > >> >> > >> >> make[3]: Entering directory > >> >> `/usr/src/lttng-ust-2.0.1/tests/hello' > >> >> > >> >> CC > >> >> tp.o > >> >> > >> >> CCLD > >> >> hello > >> >> > >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > >> >> `__num_possible_cpus' > >> >> > >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > >> >> `shm_object_table_create' > >> >> > >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > >> >> `shm_object_table_append_shadow' > >> >> > >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > >> >> `shm_object_table_append' > >> >> > >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > >> >> `zalloc_shm' > >> >> > >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > >> >> `_get_num_possible_cpus' > >> >> > >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > >> >> `align_shm' > >> >> > >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to > >> >> `shm_object_table_destroy' > >> >> > >> >> collect2: ld returned 1 exit > >> >> status > >> >> > >> >> make[3]: *** [hello] Error > >> >> 1 > >> >> > >> >> make[3]: Leaving directory > >> >> `/usr/src/lttng-ust-2.0.1/tests/hello' > >> >> > >> >> make[2]: *** [all-recursive] Error > >> >> 1 > >> >> > >> >> make[2]: Leaving directory > >> >> `/usr/src/lttng-ust-2.0.1/tests' > >> >> > >> >> make[1]: *** [all-recursive] Error > >> >> 1 > >> >> > >> >> make[1]: Leaving directory > >> >> `/usr/src/lttng-ust-2.0.1' > >> >> > >> >> make: *** [all] Error > >> >> 2 > >> >> > >> >> localhost lttng-ust-2.0.1 # > >> >> > >> >> > >> >> On Thu, May 17, 2012 at 2:30 PM, Mathieu Desnoyers < > >> >> mathieu.desnoyers at efficios.com> wrote: > >> >> > >> >> > * Alexandre Montplaisir (alexandre.montplaisir at polymtl.ca) wrote: > >> >> > > This is an interesting problem, I'll forward it to the mailing > >> >> > > list. > >> >> > > > >> >> > > > >> >> > > On 12-05-17 10:02 AM, Vanni Genua wrote: > >> >> > > > Also why I get this error? > >> >> > > > see the attached log file. > >> >> > > > Best regards. > >> >> > > > V.G. > >> >> > > > > >> >> > > > > >> >> > > > >> >> > > localhost lttng-ust-2.0.1 # ./configure > >> >> > > checking build system type... armv7l-unknown-linux-gnueabi > >> >> > > checking host system type... armv7l-unknown-linux-gnueabi > >> >> > > checking target system type... armv7l-unknown-linux-gnueabi > >> >> > > checking for a BSD-compatible install... /usr/bin/install -c > >> >> > > checking whether build environment is sane... yes > >> >> > > checking for a thread-safe mkdir -p... /bin/mkdir -p > >> >> > > checking for gawk... gawk > >> >> > > checking whether make sets $(MAKE)... yes > >> >> > > checking whether make supports nested variables... yes > >> >> > > checking for a sed that does not truncate output... /bin/sed > >> >> > > checking for gcc... gcc > >> >> > > checking whether the C compiler works... yes > >> >> > > checking for C compiler default output file name... a.out > >> >> > > checking for suffix of executables... > >> >> > > checking whether we are cross compiling... no > >> >> > > checking for suffix of object files... o > >> >> > > checking whether we are using the GNU C compiler... yes > >> >> > > checking whether gcc accepts -g... yes > >> >> > > checking for gcc option to accept ISO C89... none needed > >> >> > > checking for style of include used by make... GNU > >> >> > > checking dependency style of gcc... gcc3 > >> >> > > checking for g++... g++ > >> >> > > checking whether we are using the GNU C++ compiler... yes > >> >> > > checking whether g++ accepts -g... yes > >> >> > > checking dependency style of g++... gcc3 > >> >> > > checking whether make sets $(MAKE)... (cached) yes > >> >> > > checking how to print strings... printf > >> >> > > checking for a sed that does not truncate output... (cached) > >> >> > > /bin/sed > >> >> > > checking for grep that handles long lines and -e... /bin/grep > >> >> > > checking for egrep... /bin/grep -E > >> >> > > checking for fgrep... /bin/grep -F > >> >> > > checking for ld used by gcc... > >> >> > > /usr/armv7a-unknown-linux-gnueabi/bin/ld > >> >> > > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) > >> >> > > is > >> >> > > GNU > >> >> > ld... yes > >> >> > > checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm > >> >> > > -B > >> >> > > checking the name lister (/usr/bin/nm -B) interface... BSD nm > >> >> > > checking whether ln -s works... yes > >> >> > > checking the maximum length of command line arguments... 1572864 > >> >> > > checking whether the shell understands some XSI constructs... yes > >> >> > > checking whether the shell understands "+="... yes > >> >> > > checking how to convert armv7l-unknown-linux-gnueabi file names to > >> >> > armv7l-unknown-linux-gnueabi format... func_convert_file_noop > >> >> > > checking how to convert armv7l-unknown-linux-gnueabi file names to > >> >> > toolchain format... func_convert_file_noop > >> >> > > checking for /usr/armv7a-unknown-linux-gnueabi/bin/ld option to > >> >> > > reload > >> >> > object files... -r > >> >> > > checking for objdump... objdump > >> >> > > checking how to recognize dependent libraries... pass_all > >> >> > > checking for dlltool... no > >> >> > > checking how to associate runtime and link libraries... printf > >> >> > > %s\n > >> >> > > checking for ar... ar > >> >> > > checking for archiver @FILE support... @ > >> >> > > checking for strip... strip > >> >> > > checking for ranlib... ranlib > >> >> > > checking command to parse /usr/bin/nm -B output from gcc object... > >> >> > > ok > >> >> > > checking for sysroot... no > >> >> > > checking for mt... no > >> >> > > checking if : is a manifest tool... no > >> >> > > checking how to run the C preprocessor... gcc -E > >> >> > > checking for ANSI C header files... yes > >> >> > > checking for sys/types.h... yes > >> >> > > checking for sys/stat.h... yes > >> >> > > checking for stdlib.h... yes > >> >> > > checking for string.h... yes > >> >> > > checking for memory.h... yes > >> >> > > checking for strings.h... yes > >> >> > > checking for inttypes.h... yes > >> >> > > checking for stdint.h... yes > >> >> > > checking for unistd.h... yes > >> >> > > checking for dlfcn.h... yes > >> >> > > checking for objdir... .libs > >> >> > > checking if gcc supports -fno-rtti -fno-exceptions... no > >> >> > > checking for gcc option to produce PIC... -fPIC -DPIC > >> >> > > checking if gcc PIC flag -fPIC -DPIC works... yes > >> >> > > checking if gcc static flag -static works... yes > >> >> > > checking if gcc supports -c -o file.o... yes > >> >> > > checking if gcc supports -c -o file.o... (cached) yes > >> >> > > checking whether the gcc linker > >> >> > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared > >> >> > libraries... > >> >> > yes > >> >> > > checking whether -lc should be explicitly linked in... no > >> >> > > checking dynamic linker characteristics... GNU/Linux ld.so > >> >> > > checking how to hardcode library paths into programs... immediate > >> >> > > checking whether stripping libraries is possible... yes > >> >> > > checking if libtool supports shared libraries... yes > >> >> > > checking whether to build shared libraries... yes > >> >> > > checking whether to build static libraries... yes > >> >> > > checking how to run the C++ preprocessor... g++ -E > >> >> > > checking for ld used by g++... > >> >> > > /usr/armv7a-unknown-linux-gnueabi/bin/ld > >> >> > > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) > >> >> > > is > >> >> > > GNU > >> >> > ld... yes > >> >> > > checking whether the g++ linker > >> >> > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared > >> >> > libraries... > >> >> > yes > >> >> > > checking for g++ option to produce PIC... -fPIC -DPIC > >> >> > > checking if g++ PIC flag -fPIC -DPIC works... yes > >> >> > > checking if g++ static flag -static works... yes > >> >> > > checking if g++ supports -c -o file.o... yes > >> >> > > checking if g++ supports -c -o file.o... (cached) yes > >> >> > > checking whether the g++ linker > >> >> > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared > >> >> > libraries... > >> >> > yes > >> >> > > checking dynamic linker characteristics... (cached) GNU/Linux > >> >> > > ld.so > >> >> > > checking how to hardcode library paths into programs... immediate > >> >> > > checking for dlopen in -ldl... yes > >> >> > > checking for pthread_create in -lpthread... yes > >> >> > > checking for uuid_generate in -luuid... yes > >> >> > > checking for inline... inline > >> >> > > checking for stdlib.h... (cached) yes > >> >> > > checking for GNU libc compatible malloc... yes > >> >> > > checking for gettimeofday... yes > >> >> > > checking for munmap... yes > >> >> > > checking for socket... yes > >> >> > > checking for strerror... yes > >> >> > > checking for strtol... yes > >> >> > > checking for sched_getcpu... yes > >> >> > > checking for sysconf... yes > >> >> > > checking for makeinfo... yes > >> >> > > checking urcu-bp.h usability... yes > >> >> > > checking urcu-bp.h presence... yes > >> >> > > checking for urcu-bp.h... yes > >> >> > > checking caa_likely()... yes > >> >> > > checking for synchronize_rcu_bp in -lurcu-bp... yes > >> >> > > checking for call_rcu_bp in -lurcu-bp... yes > >> >> > > checking library format for the host system... configure: error: > >> >> > > unable > >> >> > to detect library format (unsupported architecture (armv7l)?) > >> >> > > >> >> > Does it help if you add a line: > >> >> > > >> >> > armv7l) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; > >> >> > > >> >> > near line 188 of configure.ac ? > >> >> > > >> >> > What we did in userspace RCU is to use "arm*". > >> >> > > >> >> > Thanks, > >> >> > > >> >> > Mathieu > >> >> > > >> >> > > > >> >> > > > >> >> > > _______________________________________________ > >> >> > > lttng-dev mailing list > >> >> > > lttng-dev at lists.lttng.org > >> >> > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > >> >> > > >> >> > -- > >> >> > Mathieu Desnoyers > >> >> > Operating System Efficiency R&D Consultant > >> >> > EfficiOS Inc. > >> >> > http://www.efficios.com > >> >> > > >> > > >> > -- > >> > Mathieu Desnoyers > >> > Operating System Efficiency R&D Consultant > >> > EfficiOS Inc. > >> > http://www.efficios.com > >> > > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From hch at infradead.org Sun May 20 10:44:28 2012 From: hch at infradead.org (Christoph Hellwig) Date: Sun, 20 May 2012 10:44:28 -0400 Subject: [lttng-dev] [sheepdog] [PATCH] configure: exit if urcu/uatomic.h is not found In-Reply-To: <4FB8EEF3.5000204@gmail.com> References: <1337482745-21658-1-git-send-email-morita.kazutaka@lab.ntt.co.jp> <4FB8EEF3.5000204@gmail.com> Message-ID: <20120520144428.GA32368@infradead.org> We could have a local include/uatomic.h that includes either based on which one is available, still erroring out if none is present. I've cced the LTTng list to se if using the old uatomic_arch.h header from outside librcu is something we should do at all. On Sun, May 20, 2012 at 09:17:39PM +0800, Liu Yuan wrote: > On 05/20/2012 10:59 AM, MORITA Kazutaka wrote: > > > > > On my environment (debian squeeze), the package version of liburcu is > > too old (0.4.1) and I cannot compile the latest sheepdog because > > urcu/uatomic.h is missing. > > > > Is there any way to build Sheepdog with the older version of liburcu? > > If no, we'd better check the existence of urcu/uatomic.h. > > > urcu/uatomic_arch.h might be the compatible header to include, but it > will issue a annoying warning for a recent version like following: > > /usr/include/urcu/uatomic_arch.h:1: warning: #warning > "urcu/uatomic_arch.h is deprecated. Please include urcu/uatomic.h instead." > > Maybe we can use complex macros to check urcu version to get rid of this > warning, but I think would be better use your patch directly to simplify > the thing. > > Thanks, > Yuan > -- > sheepdog mailing list > sheepdog at lists.wpkg.org > http://lists.wpkg.org/mailman/listinfo/sheepdog ---end quoted text--- From mathieu.desnoyers at efficios.com Sun May 20 11:28:29 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 20 May 2012 11:28:29 -0400 Subject: [lttng-dev] [sheepdog] [PATCH] configure: exit if urcu/uatomic.h is not found In-Reply-To: <20120520144428.GA32368@infradead.org> References: <1337482745-21658-1-git-send-email-morita.kazutaka@lab.ntt.co.jp> <4FB8EEF3.5000204@gmail.com> <20120520144428.GA32368@infradead.org> Message-ID: <20120520152829.GB25641@Krystal> * Christoph Hellwig (hch at infradead.org) wrote: > We could have a local include/uatomic.h that includes either based on > which one is available, still erroring out if none is present. > > I've cced the LTTng list to se if using the old uatomic_arch.h header > from outside librcu is something we should do at all. Hi Christoph, Hrm, 0.4.1 is really old (2010-02-12). We did migrate some header names and clean up some API namespacing back then between 0.4 and 0.5, so we would not have to do it when the project would get more exposure. In terms of way forward, we were planning to remove urcu/uatomic_arch.h after a rather long deprecation period, being replaced by urcu/uatomic.h. As you noticed, there has been a deprecation #warning in place since the move has been done. If you want to keep compatibility with the old 0.4.x version of liburcu for a longer time, my recommendation would be to add a configure.ac check for urcu/uatomic.h. It it is missing, then check for urcu/uatomic_arch.h. This would specify a preprocessor macro that will select either in a wrapper header within the sheepdog project. If you only rely on uatomic, doing so should handle deprecation of the older liburcu 0.4.x support within sheepdog at some point in the future if need be. It's good to be aware that between 0.4.x and 0.5, a namespace cleanup for all the smp_*mb() went in: those are now all prefixed with "cmm_", e.g. cmm_smp_mb(). Same for a few other API members that were clashing with private project namespaces (all documented in the ChangeLog). uatomic_*() already had its namespace, so it did not need to be changed. If in the future sheepdog starts using features for which the namespace changed at 0.5, you might want to consider dropping support for liburcu 0.4.x. Whether you decide on just bailing out is urcu/uatomic.h is not found or use a detection macro is up to you, and depends on how far back you want to support old distros. Thanks! Mathieu > > On Sun, May 20, 2012 at 09:17:39PM +0800, Liu Yuan wrote: > > On 05/20/2012 10:59 AM, MORITA Kazutaka wrote: > > > > > > > > On my environment (debian squeeze), the package version of liburcu is > > > too old (0.4.1) and I cannot compile the latest sheepdog because > > > urcu/uatomic.h is missing. > > > > > > Is there any way to build Sheepdog with the older version of liburcu? > > > If no, we'd better check the existence of urcu/uatomic.h. > > > > > > urcu/uatomic_arch.h might be the compatible header to include, but it > > will issue a annoying warning for a recent version like following: > > > > /usr/include/urcu/uatomic_arch.h:1: warning: #warning > > "urcu/uatomic_arch.h is deprecated. Please include urcu/uatomic.h instead." > > > > Maybe we can use complex macros to check urcu version to get rid of this > > warning, but I think would be better use your patch directly to simplify > > the thing. > > > > Thanks, > > Yuan > > -- > > sheepdog mailing list > > sheepdog at lists.wpkg.org > > http://lists.wpkg.org/mailman/listinfo/sheepdog > ---end quoted text--- > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From paulmck at linux.vnet.ibm.com Sun May 20 11:56:11 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Sun, 20 May 2012 08:56:11 -0700 Subject: [lttng-dev] [sheepdog] [PATCH] configure: exit if urcu/uatomic.h is not found In-Reply-To: <20120520152829.GB25641@Krystal> References: <1337482745-21658-1-git-send-email-morita.kazutaka@lab.ntt.co.jp> <4FB8EEF3.5000204@gmail.com> <20120520144428.GA32368@infradead.org> <20120520152829.GB25641@Krystal> Message-ID: <20120520155611.GA20237@linux.vnet.ibm.com> On Sun, May 20, 2012 at 11:28:29AM -0400, Mathieu Desnoyers wrote: > * Christoph Hellwig (hch at infradead.org) wrote: > > We could have a local include/uatomic.h that includes either based on > > which one is available, still erroring out if none is present. > > > > I've cced the LTTng list to se if using the old uatomic_arch.h header > > from outside librcu is something we should do at all. > > Hi Christoph, > > Hrm, 0.4.1 is really old (2010-02-12). We did migrate some header names > and clean up some API namespacing back then between 0.4 and 0.5, so we > would not have to do it when the project would get more exposure. In > terms of way forward, we were planning to remove urcu/uatomic_arch.h > after a rather long deprecation period, being replaced by > urcu/uatomic.h. As you noticed, there has been a deprecation #warning in > place since the move has been done. > > If you want to keep compatibility with the old 0.4.x version of liburcu > for a longer time, my recommendation would be to add a configure.ac > check for urcu/uatomic.h. It it is missing, then check for > urcu/uatomic_arch.h. This would specify a preprocessor macro that will > select either in a wrapper header within the sheepdog project. > If you only rely on uatomic, doing so should handle deprecation of the > older liburcu 0.4.x support within sheepdog at some point in the future > if need be. Another approach is to have sheepdog simply download the desired version of liburcu if it doesn't like the one it finds. ;-) Thanx, Paul > It's good to be aware that between 0.4.x and 0.5, a namespace cleanup > for all the smp_*mb() went in: those are now all prefixed with "cmm_", > e.g. cmm_smp_mb(). Same for a few other API members that were clashing > with private project namespaces (all documented in the ChangeLog). > uatomic_*() already had its namespace, so it did not need to be changed. > > If in the future sheepdog starts using features for which the namespace > changed at 0.5, you might want to consider dropping support for liburcu > 0.4.x. > > Whether you decide on just bailing out is urcu/uatomic.h is not found or > use a detection macro is up to you, and depends on how far back you want > to support old distros. > > Thanks! > > Mathieu > > > > > > On Sun, May 20, 2012 at 09:17:39PM +0800, Liu Yuan wrote: > > > On 05/20/2012 10:59 AM, MORITA Kazutaka wrote: > > > > > > > > > > > On my environment (debian squeeze), the package version of liburcu is > > > > too old (0.4.1) and I cannot compile the latest sheepdog because > > > > urcu/uatomic.h is missing. > > > > > > > > Is there any way to build Sheepdog with the older version of liburcu? > > > > If no, we'd better check the existence of urcu/uatomic.h. > > > > > > > > > urcu/uatomic_arch.h might be the compatible header to include, but it > > > will issue a annoying warning for a recent version like following: > > > > > > /usr/include/urcu/uatomic_arch.h:1: warning: #warning > > > "urcu/uatomic_arch.h is deprecated. Please include urcu/uatomic.h instead." > > > > > > Maybe we can use complex macros to check urcu version to get rid of this > > > warning, but I think would be better use your patch directly to simplify > > > the thing. > > > > > > Thanks, > > > Yuan > > > -- > > > sheepdog mailing list > > > sheepdog at lists.wpkg.org > > > http://lists.wpkg.org/mailman/listinfo/sheepdog > > ---end quoted text--- > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > From stanislav.vovk at ericsson.com Mon May 21 04:38:49 2012 From: stanislav.vovk at ericsson.com (Stanislav Vovk) Date: Mon, 21 May 2012 10:38:49 +0200 Subject: [lttng-dev] Lttng-modules Message-ID: <6CAFD5C0F804784B80F24F3571EB7A3C67DF0307C8@ESESSCMS0363.eemea.ericsson.se> Hi I am using Linux kernel 3.2 on PowerPC and have a question about LTTng2 kernel modules. As stated in the README CONFIG_TRACEPOINTS is required, in my kernel config it does not exist. Do I need to patch my kernel to build LTTng modules and make it work? Or how to proceed ... It seems like I cant get modules to build at the moment. Thanks BR /Stanislav -------------- next part -------------- An HTML attachment was scrubbed... URL: From francis.giraldeau at gmail.com Mon May 21 05:24:44 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Mon, 21 May 2012 11:24:44 +0200 Subject: [lttng-dev] Lttng-modules In-Reply-To: <6CAFD5C0F804784B80F24F3571EB7A3C67DF0307C8@ESESSCMS0363.eemea.ericsson.se> References: <6CAFD5C0F804784B80F24F3571EB7A3C67DF0307C8@ESESSCMS0363.eemea.ericsson.se> Message-ID: 2012/5/21 Stanislav Vovk > ** > Hi > > I am using Linux kernel 3.2 on PowerPC and have a question about LTTng2 > kernel modules. > As stated in the README CONFIG_TRACEPOINTS is required, in my kernel > config it does not exist. Do I need to patch my kernel to build LTTng > modules and make it work? Or how to proceed ... It seems like I cant get > modules to build at the moment. > The CONFIG_TRACEPOINTS option can be set when compiling the kernel. If your kernel is not compiled with this option, then it must be recompiled. With make menuconfig, enable the option by selecting this item: Kernel hacking ---> Tracers Then, after compilation and installation of the new kernel and a reboot, lttng-modules should build. If you want to specify the source directory of the kernel for lttng-modules, use the env var like this: KERNELDIR=../dir-to-linux make modules Francis -------------- next part -------------- An HTML attachment was scrubbed... URL: From mathieu.desnoyers at efficios.com Mon May 21 12:49:22 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 21 May 2012 12:49:22 -0400 Subject: [lttng-dev] BABELTRACE In-Reply-To: References: Message-ID: <20120521164921.GA6550@Krystal> I would suspect that you need to install an updated version of flex and bison. If you don't need the babeltrace master branch, you could instead use the babeltrace tarball packages, which don't require flex nor bison (see babeltrace README file for dependencies). Thanks, Mathieu * Vanni Genua (vannigenua at gmail.com) wrote: > I did > #./bootstrap > and it was ok > Then I did > #./configure > and I got this error: > checking for bison... bison -y > checking for flex... flex > checking lex output file root... lex.yy > checking lex library... -lfl > checking whether yytext is a pointer... yes > ./configure: line 11626: syntax error near unexpected token `0.16' > ./configure: line 11626: ` PKG_PROG_PKG_CONFIG(0.16)' > > How to solve this bug? > Thanks > V.G. > > On Mon, May 21, 2012 at 2:18 PM, Vanni Genua wrote: > > > Soved with Babeltrace Master. > > V.G. > > > > > > On Mon, May 21, 2012 at 1:55 PM, Vanni Genua wrote: > > > >> Hi there, > >> so once I have correctly installed LTTng-modules, LTTng-ust and > >> LTTng-tools, I can use LTTng but not LTTng view. In order to use #lttng > >> view command I have to install Babeltrace, but it seems still to be a rc > >> version. As a matter of fact I downloaded it from > >> http://lttng.org/download and, according to README file, I launched > >> #./bootsrap but this file is not in the directory: it doesn't exist! > >> I'm stuck here now, any idea? > >> Vanni > >> > > > > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon May 21 19:06:40 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 21 May 2012 19:06:40 -0400 Subject: [lttng-dev] [RELEASE] Userspace RCU 0.7.0 Message-ID: <20120521230640.GA18601@Krystal> liburcu is a LGPLv2.1 userspace RCU (read-copy-update) library. This data synchronization library provides read-side access which scales linearly with the number of cores. It does so by allowing multiples copies of a given data structure to live at the same time, and by monitoring the data structure accesses to detect grace periods after which memory reclamation is possible. liburcu-cds (cds: concurrent data structures) provides efficient data containers based on RCU and lock-free algorithms. Those structures include hash tables, queues, stacks, and doubly-linked lists. * New in this release: The major feature added in this release is the RCU Lock-Free Resizable Hash Table (API: urcu/rculfhash.h). This hash table scales very well to many cores for updates on different keys, is cache-efficient, uses RCU for lookups and traversals, provides ordering guarantees for updates vs reads, and uniqueness guarantees for uniquify and replace operations vs RCU traversals. It automatically resizes when the hash chains become too dense. For more information, please refer to the slides of the following presentation: http://www.efficios.com/lpc2011-urcu . The source code also contains extensive explanation of the hash table architecture. Also new in this release: a fallback for compilers that do not support __thread TLS has been implemented, which should enable support for Android, NetBSD, Darwin, and OpenBSD. (Feedback about your experience with userspace RCU on those platforms is welcome. Following sufficient positive feedback, I will consider adding those to the list of supported OS in the README.) Changelog: 2012-05-21 Userspace RCU 0.7.0 * Cleanup: header comments coding style * Document uatomic operations * Update return value of "set" operations * Fix mremap wrapper for NetBSD 5 * Use urcu/tls-compat.h * Implement urcu/tls-compat.h * Add TLS detection m4 macro * document concurrent data structures * documentation: refer to rcu-api.txt * Move API.txt to doc/rcu-api.txt, install in system doc/ * rculfhash: document implied memory barriers * rculfhash: Ensure future-proof memory barrier semantic consistency * API cleanup: use "uatomic_*" in cmm_smp_mb__ API * uatomic: add memory barrier API for and/or/add/sub/inc/sub * rculfhash: add runhash.sh test script * rculfhash tests: add missing check * rculfhash: fix: race between replace and del operations * rculfhash: replace unneeded rcu_dereference by CMM_LOAD_SHARED * rculfhash: use do {} while (0) for dbg_printf() * rculfhash: cleanup typo * rculfhash: update API comments * rculfhash: update comments in implementation * rculfhash tests: add long hash chains tests * rculfhash tests: add uniqueness test * rculfhash test: print test name * rculfhash: stress requirement in documentation * rculfhash: fix typo * rculfhash tests: use array of callbacks to modularize * rculfhash tests: modularize tests * rculfhash: document ordering guarantees * rculfhash: document linearizability guarantees * rculfhash: update removal comment * Add missing files to .gitignore * Fix out-of-tree build * rculfhash: check malloc NULL pointer * Fix uatomic sign cast * Remove unused jhash.h file * Fix: use known license text, fix incorrect FSF address * Fix: add missing sched.h include in rculfhash.c * Allow tests to run on architectures without per-cpu call_rcu support * Hash table test: FreeBSD compatibility fix * tests: define _GNU_SOURCE instead of __USE_GNU * RCU lock-free hash table: implement cds_lfht_is_node_deleted() * Define _GNU_SOURCE to access CPU_ZERO() macro in uClibc * Install ChangeLog and README into system's doc * Fix AC_LANG_SOURCE usage: only takes one parameter * Fix autoconf futex check * configure.ac: Use AC_LANG_SOURCE for if else macros * Refresh autoconf files * Update gitignore * rculfhash: add comment about hash seed randomness within test program * readme: state correct GCC dependency for ARM * rculfhash: remove an invocation of bit_reverse_ulong() when adding * rculfhash: remove unneeded conversion * rculfhash: remove unneeded clear_flag() * cds_lfht_replace: add checks for old/new node hash/value match * rculfhash: use node instead of iter argument for deletion * rculfhash: number of logically removed nodes should not appear in API * Document that flags could be represented on 2 bits * Add missing REMOVAL_OWNER_FLAG comment to cds_lfht_node comment * _cds_lfht_del is not used for buckets anymore, remove parameter * rculfhash: Relax atomicity guarantees required by removal operation * remove unneeded "return;" * simplify the deletion for bucket node * Remove unneeded code * Cleanup DEFINE_RCU_FLAVOR() * Add cds_lfht_ prefix to fls_ulong, get_count_order_ulong, get_count_order_u32 * Merge RCU Lock-Free Resizable Hash Table Project website: http://lttng.org/urcu Download link: http://lttng.org/files/urcu/ -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Tue May 22 12:35:35 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 22 May 2012 12:35:35 -0400 Subject: [lttng-dev] [lttng-ust PATCH 1/2] Add Integer and Long tracepoint types to the Java interface In-Reply-To: <1336104210-3160-1-git-send-email-alexandre.montplaisir@polymtl.ca> References: <1336104210-3160-1-git-send-email-alexandre.montplaisir@polymtl.ca> Message-ID: <20120522163535.GA5462@Krystal> * Alexandre Montplaisir (alexandre.montplaisir at polymtl.ca) wrote: > Also added Javadoc comments to the .java file. merged, thanks! Mathieu > > Signed-off-by: Alexandre Montplaisir > --- > liblttng-ust-java/LTTngUst.c | 38 ++++++++++++++++---- > liblttng-ust-java/LTTngUst.java | 67 ++++++++++++++++++++++++++++++++---- > liblttng-ust-java/lttng_ust_java.h | 22 ++++++++++-- > 3 files changed, 112 insertions(+), 15 deletions(-) > > diff --git a/liblttng-ust-java/LTTngUst.c b/liblttng-ust-java/LTTngUst.c > index 3d23d6a..0bef89d 100644 > --- a/liblttng-ust-java/LTTngUst.c > +++ b/liblttng-ust-java/LTTngUst.c > @@ -22,18 +22,44 @@ > #define TRACEPOINT_CREATE_PROBES > #include "lttng_ust_java.h" > > +JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointInt(JNIEnv *env, > + jobject jobj, > + jstring ev_name, > + jint payload) > +{ > + jboolean iscopy; > + const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy); > + > + tracepoint(lttng_ust_java, int_event, ev_name_cstr, payload); > + > + (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr); > +} > + > +JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointLong(JNIEnv *env, > + jobject jobj, > + jstring ev_name, > + jlong payload) > +{ > + jboolean iscopy; > + const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy); > + > + tracepoint(lttng_ust_java, long_event, ev_name_cstr, payload); > + > + (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr); > +} > + > JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointString(JNIEnv *env, > jobject jobj, > jstring ev_name, > - jstring args) > + jstring payload) > { > jboolean iscopy; > - const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, > - &iscopy); > - const char *args_cstr = (*env)->GetStringUTFChars(env, args, &iscopy); > + const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy); > + const char *payload_cstr = (*env)->GetStringUTFChars(env, payload, &iscopy); > > - tracepoint(lttng_ust_java, string, ev_name_cstr, args_cstr); > + tracepoint(lttng_ust_java, string_event, ev_name_cstr, payload_cstr); > > (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr); > - (*env)->ReleaseStringUTFChars(env, args, args_cstr); > + (*env)->ReleaseStringUTFChars(env, payload, payload_cstr); > } > + > diff --git a/liblttng-ust-java/LTTngUst.java b/liblttng-ust-java/LTTngUst.java > index 68ed120..f4bea32 100644 > --- a/liblttng-ust-java/LTTngUst.java > +++ b/liblttng-ust-java/LTTngUst.java > @@ -1,5 +1,6 @@ > -/* > +/** > * Copyright (C) 2011-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Alexandre Montplaisir > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Lesser General Public > @@ -18,10 +19,64 @@ > > package org.lttng.ust; > > -public class LTTngUst { > - public static native void tracepointString(String name, String arg); > - static { > - System.loadLibrary("lttng-ust-java"); > - } > +/** > + * This class implements the the Java side of the LTTng-UST Java interface. > + * > + * First, make sure you have installed "liblttng-ust-java.so" where the linker > + * can find it. You can then call LTTngUst.init() from your Java program to > + * connect the methods exposed here to the native library. > + * > + * Because of limitations in the probe declaration, all trace events generated > + * by this library will have "lttng_ust_java" for domain, and "_event" for > + * event name in the CTF trace files. The "name" parameter will instead appear > + * as the first element of the event's payload. > + * > + * @author Mathieu Desnoyers > + * @author Alexandre Montplaisir > + * > + */ > +public abstract class LTTngUst { > + > + /** > + * Initialize the UST tracer. This should always be called first, before any > + * tracepoint* method. > + */ > + public static void init() { > + System.loadLibrary("lttng-ust-java"); //$NON-NLS-1$ > + } > + > + /** > + * Insert a tracepoint with a payload of type Integer. > + * > + * @param name > + * The name assigned to this event. For best performance, this > + * should be a statically-defined String, or a literal. > + * @param payload > + * The int payload > + */ > + public static native void tracepointInt(String name, int payload); > + > + /** > + * Insert a tracepoint with a payload of type Long > + * > + * @param name > + * The name assigned to this event. For best performance, this > + * should be a statically-defined String, or a literal. > + * @param payload > + * The long payload > + */ > + public static native void tracepointLong(String name, long payload); > + > + /** > + * Insert a tracepoint with a String payload. > + * > + * @param name > + * The name assigned to this event. For best performance, this > + * should be a statically-defined String, or a literal. > + * @param payload > + * The String payload > + */ > + public static native void tracepointString(String name, String payload); > + > } > > diff --git a/liblttng-ust-java/lttng_ust_java.h b/liblttng-ust-java/lttng_ust_java.h > index 771d392..7cdbea5 100644 > --- a/liblttng-ust-java/lttng_ust_java.h > +++ b/liblttng-ust-java/lttng_ust_java.h > @@ -24,11 +24,27 @@ > > #include > > -TRACEPOINT_EVENT(lttng_ust_java, string, > - TP_ARGS(const char *, name, const char *, args), > +TRACEPOINT_EVENT(lttng_ust_java, int_event, > + TP_ARGS(const char *, name, int, payload), > TP_FIELDS( > ctf_string(name, name) > - ctf_string(args, args) > + ctf_integer(int, int_payload, payload) > + ) > +) > + > +TRACEPOINT_EVENT(lttng_ust_java, long_event, > + TP_ARGS(const char *, name, long, payload), > + TP_FIELDS( > + ctf_string(name, name) > + ctf_integer(long, long_payload, payload) > + ) > +) > + > +TRACEPOINT_EVENT(lttng_ust_java, string_event, > + TP_ARGS(const char *, name, const char *, payload), > + TP_FIELDS( > + ctf_string(name, name) > + ctf_string(string_payload, payload) > ) > ) > > -- > 1.7.10 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Tue May 22 12:35:43 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 22 May 2012 12:35:43 -0400 Subject: [lttng-dev] [lttng-ust PATCH 2/2] Add "2x int" and "2x long" types to the Java interface In-Reply-To: <1336104210-3160-2-git-send-email-alexandre.montplaisir@polymtl.ca> References: <1336104210-3160-1-git-send-email-alexandre.montplaisir@polymtl.ca> <1336104210-3160-2-git-send-email-alexandre.montplaisir@polymtl.ca> Message-ID: <20120522163542.GB5462@Krystal> * Alexandre Montplaisir (alexandre.montplaisir at polymtl.ca) wrote: > Since we have to statically define all the available event types, > offer types for two integers and two longs, which are relatively > common use cases. merged, thanks! Mathieu > > Signed-off-by: Alexandre Montplaisir > --- > liblttng-ust-java/LTTngUst.c | 28 ++++++++++++++++++++++++++++ > liblttng-ust-java/LTTngUst.java | 28 ++++++++++++++++++++++++++++ > liblttng-ust-java/lttng_ust_java.h | 18 ++++++++++++++++++ > 3 files changed, 74 insertions(+) > > diff --git a/liblttng-ust-java/LTTngUst.c b/liblttng-ust-java/LTTngUst.c > index 0bef89d..9ae3983 100644 > --- a/liblttng-ust-java/LTTngUst.c > +++ b/liblttng-ust-java/LTTngUst.c > @@ -35,6 +35,20 @@ JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointInt(JNIEnv *env, > (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr); > } > > +JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointIntInt(JNIEnv *env, > + jobject jobj, > + jstring ev_name, > + jint payload1, > + jint payload2) > +{ > + jboolean iscopy; > + const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy); > + > + tracepoint(lttng_ust_java, int_int_event, ev_name_cstr, payload1, payload2); > + > + (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr); > +} > + > JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointLong(JNIEnv *env, > jobject jobj, > jstring ev_name, > @@ -48,6 +62,20 @@ JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointLong(JNIEnv *env, > (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr); > } > > +JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointLongLong(JNIEnv *env, > + jobject jobj, > + jstring ev_name, > + jlong payload1, > + jlong payload2) > +{ > + jboolean iscopy; > + const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy); > + > + tracepoint(lttng_ust_java, long_long_event, ev_name_cstr, payload1, payload2); > + > + (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr); > +} > + > JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointString(JNIEnv *env, > jobject jobj, > jstring ev_name, > diff --git a/liblttng-ust-java/LTTngUst.java b/liblttng-ust-java/LTTngUst.java > index f4bea32..79ad97a 100644 > --- a/liblttng-ust-java/LTTngUst.java > +++ b/liblttng-ust-java/LTTngUst.java > @@ -57,6 +57,20 @@ public abstract class LTTngUst { > public static native void tracepointInt(String name, int payload); > > /** > + * Insert a tracepoint with a payload consisting of two integers. > + * > + * @param name > + * The name assigned to this event. For best performance, this > + * should be a statically-defined String, or a literal. > + * @param payload1 > + * The first int payload > + * @param payload2 > + * The second int payload > + */ > + public static native void > + tracepointIntInt(String name, int payload1, int payload2); > + > + /** > * Insert a tracepoint with a payload of type Long > * > * @param name > @@ -68,6 +82,20 @@ public abstract class LTTngUst { > public static native void tracepointLong(String name, long payload); > > /** > + * Insert a tracepoint with a payload consisting of two longs. > + * > + * @param name > + * The name assigned to this event. For best performance, this > + * should be a statically-defined String, or a literal. > + * @param payload1 > + * The first long payload > + * @param payload2 > + * The second long payload > + */ > + public static native void > + tracepointLongLong(String name, long payload1, long payload2); > + > + /** > * Insert a tracepoint with a String payload. > * > * @param name > diff --git a/liblttng-ust-java/lttng_ust_java.h b/liblttng-ust-java/lttng_ust_java.h > index 7cdbea5..7a8b391 100644 > --- a/liblttng-ust-java/lttng_ust_java.h > +++ b/liblttng-ust-java/lttng_ust_java.h > @@ -32,6 +32,15 @@ TRACEPOINT_EVENT(lttng_ust_java, int_event, > ) > ) > > +TRACEPOINT_EVENT(lttng_ust_java, int_int_event, > + TP_ARGS(const char *, name, int, payload1, int, payload2), > + TP_FIELDS( > + ctf_string(name, name) > + ctf_integer(int, int_payload1, payload1) > + ctf_integer(int, int_payload2, payload2) > + ) > +) > + > TRACEPOINT_EVENT(lttng_ust_java, long_event, > TP_ARGS(const char *, name, long, payload), > TP_FIELDS( > @@ -40,6 +49,15 @@ TRACEPOINT_EVENT(lttng_ust_java, long_event, > ) > ) > > +TRACEPOINT_EVENT(lttng_ust_java, long_long_event, > + TP_ARGS(const char *, name, long, payload1, long, payload2), > + TP_FIELDS( > + ctf_string(name, name) > + ctf_integer(long, long_payload1, payload1) > + ctf_integer(long, long_payload2, payload2) > + ) > +) > + > TRACEPOINT_EVENT(lttng_ust_java, string_event, > TP_ARGS(const char *, name, const char *, payload), > TP_FIELDS( > -- > 1.7.10 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Tue May 22 13:03:37 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 22 May 2012 13:03:37 -0400 Subject: [lttng-dev] cannot compile babeltrace in cygwin because of undefined symbols In-Reply-To: References: Message-ID: <20120522170337.GA6800@Krystal> I compiled babeltrace with a recent cygwin, and it worked fine. What is your linker version ? Can you try with a recent cygwin installation ? Thanks, Mathieu * Carlos C?spedes (cespedes at ieee.org) wrote: > Hello there, > > Sadly I have not been able to compile babeltrace uder cygwin because it has > undefined symbols. This is the error I get from make: > > .libs/ctf-text.o: In function `ctf_text_write_event': > /cygdrive/c/Users/cespedec/Downloads/babeltrace/babeltrace-1.0.0-rc2/formats/ctf-text/ctf-text.c:249: > undefined reference to `_ctf_print_timestamp' > /cygdrive/c/Users/cespedec/Downloads/babeltrace/babeltrace-1.0.0-rc2/formats/ctf-text/ctf-text.c:251: > undefined reference to `_ctf_print_timestamp' > /cygdrive/c/Users/cespedec/Downloads/babeltrace/babeltrace-1.0.0-rc2/formats/ctf-text/ctf-text.c:263: > undefined reference to `_ctf_print_timestamp' > collect2: ld returned 1 exit status > Makefile:374: recipe for target `libbabeltrace-ctf-text.la' failed > > I am using $LDFLAGS=-no-undefined which is a linker flag passed to libtool > in order not to allow undefined symbols. > If I don't use the flag then I get other warnings about: > > libtool: link: warning: undefined symbols not allowed in > i686-pc-cygwin shared libraries > > *** Warning: This system can not link to static lib archive > ../mailbox/libmailutils.la. > *** I have the capability to make that library automatically link in when > *** you link to this library. But I can only do this if you have a > *** shared version of the library, which you do not appear to have. > libtool: link: warning: undefined symbols not allowed in > i686-pc-cygwin shared libraries > > The libtool issue is well explained on this thread: > http://cygwin.com/ml/cygwin/2005-08/msg00052.html > > Simply put cygwin's libtool does not cope well with undefined symbols. > > > Thanks for your help. > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From paulbarrette at gmail.com Thu May 24 11:07:41 2012 From: paulbarrette at gmail.com (Paul Barrette) Date: Thu, 24 May 2012 11:07:41 -0400 Subject: [lttng-dev] compiling liburcu for powerpc error: void value not ignored as it ought to be Message-ID: I am seeing this error compiling for powerpc: urcu-pointer.c: In function 'rcu_set_pointer_sym': urcu-pointer.c:43:2: error: void value not ignored as it ought to be powerpc-wrs-linux-libtool: compile: powerpc-wrs-linux-gcc -m32 -mhard-float -mcpu=603e --sysroot=/pb_scratch/WL3/yocto-wrlinux-4.3/wrlinux-4.3/qemu-ppc/bitbake_build/tmp/sysroots/qemuppc -DHAVE_CONFIG_H -I. -I./urcu -I./urcu -DRCU_MB -O2 -pipe -g -feliminate-unused-debug-types -c urcu-pointer.c -fPIC -DPIC -o .libs/liburcu_mb_la-urcu-pointer.o Removing the return statements produces a warning, but it exposes more of the same compile errors. Pb -- -- Paul Barrette Linked In Profile http://sitarplayer.net ? \\=^% (*)---(*) ^^~~^~~~^^^~~^ -------------- next part -------------- An HTML attachment was scrubbed... URL: From mathieu.desnoyers at efficios.com Thu May 24 11:49:19 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 24 May 2012 11:49:19 -0400 Subject: [lttng-dev] compiling liburcu for powerpc error: void value not ignored as it ought to be In-Reply-To: References: Message-ID: <20120524154919.GA21310@Krystal> * Paul Barrette (paulbarrette at gmail.com) wrote: > I am seeing this error compiling for powerpc: > > urcu-pointer.c: In function 'rcu_set_pointer_sym': > urcu-pointer.c:43:2: error: void value not ignored as it ought to be > powerpc-wrs-linux-libtool: compile: powerpc-wrs-linux-gcc -m32 > -mhard-float -mcpu=603e > --sysroot=/pb_scratch/WL3/yocto-wrlinux-4.3/wrlinux-4.3/qemu-ppc/bitbake_build/tmp/sysroots/qemuppc > -DHAVE_CONFIG_H -I. -I./urcu -I./urcu -DRCU_MB -O2 -pipe -g > -feliminate-unused-debug-types -c urcu-pointer.c -fPIC -DPIC -o > .libs/liburcu_mb_la-urcu-pointer.o > > Removing the return statements produces a warning, but it exposes more of > the same compile errors. Thanks for reporting !! I pushed the fix in urcu master branch: commit 424d4ed5e7b0ca5e05c3078f15abf473c6879521 Author: Mathieu Desnoyers Date: Thu May 24 11:51:03 2012 -0400 fix: uatomic_set return value compile fix for non-x86 arch. Signed-off-by: Mathieu Desnoyers can you confirm that it fixes your problem ? Thanks, Mathieu > > Pb > -- > -- > Paul Barrette > Linked In Profile > http://sitarplayer.net > ? > \\=^% > (*)---(*) > ^^~~^~~~^^^~~^ > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Thu May 24 13:22:49 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 24 May 2012 13:22:49 -0400 Subject: [lttng-dev] [RELEASE] Userspace RCU 0.7.1 Message-ID: <20120524172249.GA27643@Krystal> liburcu is a LGPLv2.1 userspace RCU (read-copy-update) library. This data synchronization library provides read-side access which scales linearly with the number of cores. It does so by allowing multiples copies of a given data structure to live at the same time, and by monitoring the data structure accesses to detect grace periods after which memory reclamation is possible. liburcu-cds provides efficient data structures based on RCU and lock-free algorithms. Those structures include hash tables, queues, stacks, and doubly-linked lists. This is a compile-fix release, fixing a compile issue introduced a few days before the 0.7.0 release. We plan to deploy a continuous integration test setup to catch this kind of issue earlier in a very near future. Changelog: 2012-05-24 Userspace RCU 0.7.1 * fix: uatomic_set return value compile fix for non-x86 arch. -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From paulbarrette at gmail.com Thu May 24 15:17:53 2012 From: paulbarrette at gmail.com (Paul Barrette) Date: Thu, 24 May 2012 15:17:53 -0400 Subject: [lttng-dev] lttng-tools 2.0.1 has no gpl copy Message-ID: FYI, the git tree for lttng-tools has a copy lgpl and gpl licenses, but the tarball release has none. Is this design intent? Pb -- -- Paul Barrette Linked In Profile http://sitarplayer.net ? \\=^% (*)---(*) ^^~~^~~~^^^~~^ -------------- next part -------------- An HTML attachment was scrubbed... URL: From mathieu.desnoyers at efficios.com Thu May 24 15:19:27 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 24 May 2012 15:19:27 -0400 Subject: [lttng-dev] lttng-tools 2.0.1 has no gpl copy In-Reply-To: References: Message-ID: <20120524191927.GB2830@Krystal> * Paul Barrette (paulbarrette at gmail.com) wrote: > FYI, > the git tree for lttng-tools has a copy lgpl and gpl licenses, but the > tarball release has none. Is this design intent? this needs to be fixed. Can you file a bug on bugs.lttng.org ? Thanks, Mathieu > > Pb > > -- > -- > Paul Barrette > Linked In Profile > http://sitarplayer.net > ? > \\=^% > (*)---(*) > ^^~~^~~~^^^~~^ > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From david.goulet at polymtl.ca Thu May 24 15:19:52 2012 From: david.goulet at polymtl.ca (David Goulet) Date: Thu, 24 May 2012 15:19:52 -0400 Subject: [lttng-dev] lttng-tools 2.0.1 has no gpl copy In-Reply-To: References: Message-ID: <4FBE89D8.7050201@polymtl.ca> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hmmmm... nope, will look into that! Thanks! David On 24/05/12 03:17 PM, Paul Barrette wrote: > FYI, the git tree for lttng-tools has a copy lgpl and gpl licenses, but the > tarball release has none. Is this design intent? > > Pb > > -- -- Paul Barrette Linked In Profile > > http://sitarplayer.net ? \\=^% (*)---(*) ^^~~^~~~^^^~~^ > > > > > _______________________________________________ lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQEcBAEBAgAGBQJPvonVAAoJEELoaioR9I02ICIIAI4G71mhlnP8FfMLznEk9h1v t2Pm/5TVOhdhKHZCG5RvdPthr3Dllb0L7soPanx0/lq3x76Ho3sw7Yl5AM3BUM2J /4Jf3LsCbYhVYpxpBHD2n1FbjK/0sf0adzJpzoRNS2+MDZ7Z1acdJmgAWJMdq7GQ FM+WncKujkERP6gEMn6vzC88h6BPWu8R31NbygR66WkUp2enuliKNLG0EGvznHtm I1qrgnFybPjeoUyIqUl6MwqUq+PsAUPtosZWmqPO3qfpilgaEF/qd67y6wEh+Y0v Eymy/Dgk92USeEPP2A91xh+wHMAtrm5bvMAeloS8k93RlLEehE9xHDqWijhG5VU= =hV9Y -----END PGP SIGNATURE----- From mathieu.desnoyers at efficios.com Thu May 24 17:27:15 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 24 May 2012 17:27:15 -0400 Subject: [lttng-dev] [RELEASE] Userspace RCU 0.7.2 In-Reply-To: <20120524172249.GA27643@Krystal> References: <20120524172249.GA27643@Krystal> Message-ID: <20120524212715.GA11757@Krystal> There goes 0.7.2, fixing an unforeseen library binary compatibility issue between 0.6.x lib versions and 0.7.x (we did not intend to break binary compatibility between those two). 2012-05-24 Userspace RCU 0.7.2 * Fix library compatibility Thanks for everyone reporting issues, Mathieu * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > liburcu is a LGPLv2.1 userspace RCU (read-copy-update) library. This > data synchronization library provides read-side access which scales > linearly with the number of cores. It does so by allowing multiples > copies of a given data structure to live at the same time, and by > monitoring the data structure accesses to detect grace periods after > which memory reclamation is possible. > > liburcu-cds provides efficient data structures based on RCU and > lock-free algorithms. Those structures include hash tables, queues, > stacks, and doubly-linked lists. > > This is a compile-fix release, fixing a compile issue introduced a few > days before the 0.7.0 release. We plan to deploy a continuous > integration test setup to catch this kind of issue earlier in a very > near future. > > Changelog: > 2012-05-24 Userspace RCU 0.7.1 > * fix: uatomic_set return value compile fix for non-x86 arch. > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From montarcyber at gmail.com Sun May 27 12:45:25 2012 From: montarcyber at gmail.com (tchak adim) Date: Sun, 27 May 2012 12:45:25 -0400 Subject: [lttng-dev] Displaying graphical results Message-ID: Hi all, i already install the lastest releases of lttng-module and lttng-ust , for displaying results of captured traces i use babletrace . i wanna display graphical results of these traces . how can i do it ? Thanks . -------------- next part -------------- An HTML attachment was scrubbed... URL: From mathieu.desnoyers at efficios.com Sun May 27 14:42:55 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 27 May 2012 14:42:55 -0400 Subject: [lttng-dev] userspace-rcu test scripts patches (was: ports/168339: [patch] sysutils/userspace-rcu update to 0.7.2 In-Reply-To: <86mx4tn165.wl%umq@ueo.co.jp> References: <86mx4tn165.wl%umq@ueo.co.jp> Message-ID: <20120527184255.GA14719@Krystal> Hi Hirohisa, * Hirohisa Yamaguchi (umq at ueo.co.jp) wrote: > Hi, > > I'm Hirohisa Yamaguchi, I've sent a set of patches against > userspace-rcu to Leo the FreeBSD port maintainer. Thanks for submitting these. Here are some comments, in the spirit of trying to keep the userspace-rcu upstream as close as possible to the distro packages. > > I'll try to describe about patches, that might be relevant to upstream. > # I attach a copy of patches. The patches are cut from my reply, as they were attached (and not inlined) to the email. But let's first discuss the points you present below. > > A patch against rculfhash-mm-mmap.c is an optional patch for legacy > FreeBSD releases(i.e. releases prior to 8.2). The newer releases do > not need this patch. > Actually, the same definition is in urcu-bp.c, the definition might > need to be moved to a header file. Yesterday, I pushed a change similar to this one. It was needed to get urcu to build on freebsd 8.2 (inclusive). > > The changes for FreeBSD in test scripts are mainly consists of > following: This brings an interesting point: all the tests scripts start with "#!/bin/sh", but use bash-isms. I guess the first question would be: should be simply choose make test execution depend on bash (and push #!/bin/bash prefix), since this is only needed for tests provided with the package sources, and not needed for deployment of the library on systems ? Of course, dependency on bash for in-source-tree tests would have to be documented in the README. > 1. time(1) in FreeBSD does not have long argument name: > change --append to -a and --output to -o I will pull this change. See commit 383dac33797fd0858d6858527324a6a15aa06c09 > 2. ash (i.e. /bin/sh in FreeBSD) does not have += operator: > replace a+="b" to a="${a}b" The question on whether we specifically go for bash for in-source-tree test scripts needs to be cleared before I proceed to this change. > 3. BSD flavoured system have jot(1) instead of seq(1). > manual of jot(1) can be read at http://man.freebsd.org/jot/1 For some reason, "seq" is installed on my FreeBSD 9.0 system, but not on my 8.2. We could implement a seq-wrapper.sh in tests/ that can be sourced by test shell scripts which would use the right seq implementation underneath (and change the parameters accordingly). > 4. ash does not have PIPESTATUS: > complicated redirects using file descriptors 3 and 4 are used to > get a status of specific command (e.g. runtests.sh), because I've > wanted to know which test was failed > exec 3>&1 > STATUS=$({ { CMD1 3>&- 4>&-; echo $? 1>&4 3>&- 4>&-;} | CMD2 1>&3 3>&- 4>&-;} 4>&1) > if [ $STATUS != 0 ]; then exit 1; fi > ``autotest'' feature in autotools might be more appropriate, but > I'm not familiar with autotools. > http://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Using-Autotest.html Should decide for bash or sh first. > 5. NUM_CPUS might be determined at runtime: > `cat /proc/cpuinfo | grep -c processor` in Linux systems > `sysctl -n hw.ncpu` in BSD flavoured systems > # ``kern.smp.cpus'' is a FreeBSD specific alias for ``hw.ncpu'' > I think this varies in platforms; I'll appreciate if any guide to > testing for users. One might want to put in a number that is larger than the available number of CPUs to test overcommit, or lower than the number of CPUs if e.g. the system has hyperthreading. So I would recommend making this a parameter, and autodetect only if no parameter is provided. The autodetect would indeed have to be OS-specific. We could implement a get_nr_cpu.sh script within tests/ that detects the number of CPUs on the current OS. > > > # btw, test_perthreadlock under FreeBSD 10-CURRENT always fails > # (releases prior to 9.0 are okay). > # The change in FreeBSD libthr might cause the error. > # I haven't looked into it yet. What are the details of your test invokation ? (how many reader/writer threads, how many cores do you have ? Is this on hardware or virtualized ?) Thanks! Mathieu > > > Regards, > -- > > Hirohisa Yamaguchi > umq at ueo.co.jp -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Sun May 27 15:44:12 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 27 May 2012 15:44:12 -0400 Subject: [lttng-dev] userspace-rcu test scripts patches (was: ports/168339: [patch] sysutils/userspace-rcu update to 0.7.2 In-Reply-To: <20120527184255.GA14719@Krystal> References: <86mx4tn165.wl%umq@ueo.co.jp> <20120527184255.GA14719@Krystal> Message-ID: <20120527194412.GA18421@Krystal> * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: [...] > > > > > > # btw, test_perthreadlock under FreeBSD 10-CURRENT always fails > > # (releases prior to 9.0 are okay). -> I guess you mean "releases up to, and including 9.0, are OK". > > # The change in FreeBSD libthr might cause the error. > > # I haven't looked into it yet. > > What are the details of your test invokation ? (how many reader/writer > threads, how many cores do you have ? Is this on hardware or virtualized ?) Actually, the most interesting thing to know here would be your architecture. Moreover, as a hint, the fact that the problem seems to only arise in the perthreadlock test, which generates a lot of contention when the writer takes all the reader locks, I would guess that the bug would sit somewhere in the contention handling code, which could be either at the user-space library or kernel-level side. Thanks, Mathieu > > Thanks! > > Mathieu -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From francis.giraldeau at gmail.com Mon May 28 06:53:28 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Mon, 28 May 2012 12:53:28 +0200 Subject: [lttng-dev] How to ensure null char to string field? In-Reply-To: <1336584688-20303-1-git-send-email-francis.giraldeau@gmail.com> References: <1336584688-20303-1-git-send-email-francis.giraldeau@gmail.com> Message-ID: <1338202408.25405.22.camel@blob> Hi, I want to save a string from user space through a proc file. It seems trivial, but I have a problem with null termination. The user space string is _not_ null terminated. Here is an hexdump of the string bytes for "bidon" after performing copy_from_user on the kernel stack: [ 3163.957414] 0x62 0x69 0x64 0x6F 0x6E 0xFFFFFFDF ... The tracepoint I use is: TRACE_EVENT(lttng_uevent_cfu, TP_PROTO(const char * str), TP_ARGS(str), TP_STRUCT__entry(__string_from_user(str, str)), TP_fast_assign(tp_copy_string_from_user(str, str)), TP_printk() ) The user_strlen continues beyond the real string length because it's not null terminated. The string length is already known (given as a parameter of the write callback), such that I would like to copy only this number of bytes and then set last byte to '\0'. Also, this would be required to limit the string size. I have not found a way to do it with current macros. Shall a new macro to handle this use case be added? Cheers, Francis Giraldeau From mathieu.desnoyers at efficios.com Mon May 28 11:00:36 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 28 May 2012 11:00:36 -0400 Subject: [lttng-dev] userspace-rcu test scripts patches (was: ports/168339: [patch] sysutils/userspace-rcu update to 0.7.2 In-Reply-To: <867gvxgmuf.wl%umq@ueo.co.jp> References: <86mx4tn165.wl%umq@ueo.co.jp> <20120527184255.GA14719@Krystal> <867gvxgmuf.wl%umq@ueo.co.jp> Message-ID: <20120528150036.GA17067@Krystal> * Hirohisa Yamaguchi (umq at ueo.co.jp) wrote: > Hi, Mathieu > > Thanks for your comments. > > At Sun, 27 May 2012 14:42:55 -0400, > Mathieu Desnoyers wrote: > > > The changes for FreeBSD in test scripts are mainly consists of > > > following: > > > This brings an interesting point: all the tests scripts start with > > "#!/bin/sh", but use bash-isms. I guess the first question would be: > > should be simply choose make test execution depend on bash (and push > > #!/bin/bash prefix), since this is only needed for tests provided with > > the package sources, and not needed for deployment of the library on > > systems ? Of course, dependency on bash for in-source-tree tests would > > have to be documented in the README. > > I think there're two different purposes of tests: > 1. for developers to ensure the implementations are correct > 2. for users to see his/her environment is safe to use the feature > -- built without an error does not mean it runs okay > > I think bashisms do not suit for latter purpose. I agree that we should not depend on "bash" for any script installed into the system. However, the "tests/" subdirectory is not currently installed on the user system. It's only used for in-tree testing, and "make check" execution. There might come a point where we want to deploy some tests into the system so the library users can run them, I don't know. Maybe not yet though, as we would need to clean them up first. So at this stage, I would be fine with specifying in the README that running tests depends on bash. However, if we can provide a wrapper for all the commands we need, which would be sourced by all scripts in the tests/ directory, which implements all wrappers into per-wrapper files, sourced by one toplevel wrapper file, I would be open to that too, given that it would make deployment of tests simpler for systems lacking bash support. e.g. tests/wrapper/all.sh . wrapper/seq.sh ..... tests/wrapper/seq.sh tests/wrapper/.... each test script: #!/bin/sh . wrapper/all.sh ..... > > > > 2. ash (i.e. /bin/sh in FreeBSD) does not have += operator: > > > replace a+="b" to a="${a}b" > > The question on whether we specifically go for bash for in-source-tree > > test scripts needs to be cleared before I proceed to this change. > > If the test scripts are not written for all users, there's no problem > when its shown in a document or somewhere. > > > > > 3. BSD flavoured system have jot(1) instead of seq(1). > > > manual of jot(1) can be read at http://man.freebsd.org/jot/1 > > > For some reason, "seq" is installed on my FreeBSD 9.0 system, but not on > > my 8.2. We could implement a seq-wrapper.sh in tests/ that can be > > sourced by test shell scripts which would use the right seq > > implementation underneath (and change the parameters accordingly). > > > > 4. ash does not have PIPESTATUS: > > Should decide for bash or sh first. > > I agree, as I've mentioned above. > > > > > 5. NUM_CPUS might be determined at runtime: > > So I would recommend making this a > > parameter, and autodetect only if no parameter is provided. The > > autodetect would indeed have to be OS-specific. We could implement a > > get_nr_cpu.sh script within tests/ that detects the number of CPUs on > > the current OS. > > That sounds good. Can you prepare a patch for this ? > > > At Sun, 27 May 2012 15:44:12 -0400, > Mathieu Desnoyers wrote: > > > > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > > [...] > > > > # btw, test_perthreadlock under FreeBSD 10-CURRENT always fails > > > > # (releases prior to 9.0 are okay). > > > > -> I guess you mean "releases up to, and including 9.0, are OK". > > Ah, yes. > > > > > > # The change in FreeBSD libthr might cause the error. > > > > # I haven't looked into it yet. > > > What are the details of your test invokation ? (how many reader/writer > > > threads, how many cores do you have ? Is this on hardware or virtualized ?) > > > Actually, the most interesting thing to know here would be your > > architecture. Moreover, as a hint, the fact that the problem seems to > > only arise in the perthreadlock test, which generates a lot of > > contention when the writer takes all the reader locks, I would guess > > that the bug would sit somewhere in the contention handling code, which > > could be either at the user-space library or kernel-level side. > > I've found the error first on a build farm called redports.org, which > is opened for FreeBSD port maintainers to run build and tests. > I'm not sure the architecture of the build farm, but some test shows > it runs on Phenom II X6 1075T. There's no way to know it is on > hardware or virtualized. > # The test on the build farm ran with NUM_CPUS=6, I don't have logs > # currently since they're expired. > Any parameters in runall.sh lead to error. > > My box that reproduce the error is a VMware guest on my MacBook. > # Intel(R) Core(TM)2 Duo CPU T8300 @ 2.40GHz > It is a dual-core CPU, and I ran the tests with NUM_CPUS=2. OK, so it seems to be reproducible on both AMD and Intel, that's good news. > > I attach a backtrace of a corefile when I ran: > test_perthreadlock 1 1 10 -d 0 -b 32768 > I only have stripped libthr in my environment, I haven't managed to > build one. You might want to compile userspace rcu with: make CFLAGS=-g to get debug symbols for the library. It will provide a more helpful backtrace. We should consider that the issue can come from a race between pthread_create and pthread_mutex_lock too. Thanks! Mathieu > > > Regards, > -- > > Hirohisa Yamaguchi > umq at ueo.co.jp > GNU gdb 6.1.1 [FreeBSD] > Copyright 2004 Free Software Foundation, Inc. > GDB is free software, covered by the GNU General Public License, and you are > welcome to change it and/or distribute copies of it under certain conditions. > Type "show copying" to see the conditions. > There is absolutely no warranty for GDB. Type "show warranty" for details. > This GDB was configured as "amd64-marcel-freebsd"... > Core was generated by `test_perthreadlock'. > Program terminated with signal 10, Bus error. > Reading symbols from /lib/libthr.so.3...done. > Loaded symbols for /lib/libthr.so.3 > Reading symbols from /lib/libc.so.7...done. > Loaded symbols for /lib/libc.so.7 > Reading symbols from /libexec/ld-elf.so.1...done. > Loaded symbols for /libexec/ld-elf.so.1 > #0 0x000000080082d09b in pthread_mutex_lock () from /lib/libthr.so.3 > (gdb) info thread > 3 process 100144 0x0000000800b3207c in nanosleep () from /lib/libc.so.7 > 2 process 101026 0x0000000800826b90 in pthread_create () from /lib/libthr.so.3 > * 1 process 101025 0x000000080082d09b in pthread_mutex_lock () from /lib/libthr.so.3 > (gdb) thread apply all bt full > > Thread 3 (process 100144): > #0 0x0000000800b3207c in nanosleep () from /lib/libc.so.7 > No symbol table info available. > #1 0x0000000800a952e8 in sleep () from /lib/libc.so.7 > No symbol table info available. > #2 0x0000000800828e18 in sleep () from /lib/libthr.so.3 > No symbol table info available. > #3 0x00000000004011a8 in main (argc=1, argv=0x7fffffffda90) at test_perthreadlock.c:397 > err = > Thread 2 (process 101026): > #0 0x0000000800826b90 in pthread_create () from /lib/libthr.so.3 > No symbol table info available. > #1 0x0000000000000000 in ?? () > No symbol table info available. > > Thread 1 (process 101025): > #0 0x000000080082d09b in pthread_mutex_lock () from /lib/libthr.so.3 > No symbol table info available. > #1 0x00000000004016a3 in thr_reader (data=) at test_perthreadlock.c:211 > tidx = 0 > __func__ = "thr_reader" > #2 0x0000000800826cdd in pthread_create () from /lib/libthr.so.3 > No symbol table info available. > #3 0x0000000000000000 in ?? () > No symbol table info available. > (gdb) q -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From julien.desfossez at efficios.com Mon May 28 11:02:50 2012 From: julien.desfossez at efficios.com (Julien Desfossez) Date: Mon, 28 May 2012 11:02:50 -0400 Subject: [lttng-dev] [RELEASE] LTTngTop 0.2 Message-ID: <4FC3939A.6070809@efficios.com> LTTngTop is a ncurses interface for reading and browsing traces recorded by the LTTng 2.0 tracer. It displays various statistics. As of now, the CPU usage, performance (PMU) counters and per process/file I/O bandwidth are displayed. This version currently only supports offline traces, but a live version is in progress. This tool is mainly targeted for system administrators but it provides a summarized view of the state of the machine that is useful for a wide variety of users. The manpage describes how to record LTTng traces suitable for LTTngTop analysis and all the keybindings available in the interface. The tarball of this release is here : http://lttng.org/files/lttngtop/lttngtop-0.2.tar.bz2 The git repository is here : git://git.lttng.org/lttngtop.git The Ubuntu package is also available in the LTTng PPA for 12.04 LTS (ppa:lttng/ppa). To report bugs, you can use the bugtracker : http://bugs.lttng.org/projects/lttngtop This software is still in active development mode but feedbacks, bug reports and suggestions for improvements would be appreciated. Thanks, Julien From mathieu.desnoyers at efficios.com Mon May 28 11:27:31 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 28 May 2012 11:27:31 -0400 Subject: [lttng-dev] How to ensure null char to string field? In-Reply-To: <1338202408.25405.22.camel@blob> References: <1336584688-20303-1-git-send-email-francis.giraldeau@gmail.com> <1338202408.25405.22.camel@blob> Message-ID: <20120528152731.GA18055@Krystal> * Francis Giraldeau (francis.giraldeau at gmail.com) wrote: > Hi, > > I want to save a string from user space through a proc file. It seems > trivial, but I have a problem with null termination. The user space > string is _not_ null terminated. Here is an hexdump of the string bytes > for "bidon" after performing copy_from_user on the kernel stack: > > [ 3163.957414] 0x62 0x69 0x64 0x6F 0x6E 0xFFFFFFDF ... > > The tracepoint I use is: > > TRACE_EVENT(lttng_uevent_cfu, > TP_PROTO(const char * str), > TP_ARGS(str), > TP_STRUCT__entry(__string_from_user(str, str)), > TP_fast_assign(tp_copy_string_from_user(str, str)), > TP_printk() > ) > > The user_strlen continues beyond the real string length because it's not > null terminated. The string length is already known (given as a > parameter of the write callback), such that I would like to copy only > this number of bytes and then set last byte to '\0'. Also, this would be > required to limit the string size. > > I have not found a way to do it with current macros. Shall a new macro > to handle this use case be added? I think we would need to add: for TP_STRUCT__entry: __dynamic_array_from_user_text and implement, for TP_fast_assign: __dynamic_array_from_userenc_ext which will write the string length, followed by an array of bytes, copied from userspace. Look at all the "__dynamic_array" and "tp_memcpy_dyn" match in lttng-events.h as a starting point. Thanks, Mathieu > > Cheers, > > Francis Giraldeau > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From francis.giraldeau at gmail.com Mon May 28 13:00:27 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Mon, 28 May 2012 19:00:27 +0200 Subject: [lttng-dev] [PATCH 2/3] Add destroy all session option In-Reply-To: <1338224428-16668-1-git-send-email-francis.giraldeau@gmail.com> References: <1338224428-16668-1-git-send-email-francis.giraldeau@gmail.com> Message-ID: <1338224428-16668-2-git-send-email-francis.giraldeau@gmail.com> Destroy was limited to one session at a time. The option -a, --all destroys all registered sessions at once. Signed-off-by: Francis Giraldeau --- src/bin/lttng/commands/destroy.c | 107 ++++++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 38 deletions(-) diff --git a/src/bin/lttng/commands/destroy.c b/src/bin/lttng/commands/destroy.c index a179da8..254e790 100644 --- a/src/bin/lttng/commands/destroy.c +++ b/src/bin/lttng/commands/destroy.c @@ -28,7 +28,7 @@ #include -static char *opt_session_name; +static int opt_destroy_all; enum { OPT_HELP = 1, @@ -38,6 +38,7 @@ enum { static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, + {"all", 'a', POPT_ARG_VAL, &opt_destroy_all, 1, 0, 0}, {"list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL}, {0, 0, 0, 0, 0, 0, 0} }; @@ -53,28 +54,20 @@ static void usage(FILE *ofp) fprintf(ofp, "get it from the configuration directory (.lttng).\n"); fprintf(ofp, "\n"); fprintf(ofp, " -h, --help Show this help\n"); + fprintf(ofp, " -a, --all Destroy all sessions\n"); fprintf(ofp, " --list-options Simple listing of options\n"); fprintf(ofp, "\n"); } /* - * Destroy a session removing the config directory and unregistering to the - * session daemon. + * destroy_session + * + * Unregister the provided session to the session daemon. On success, removes + * the default configuration. */ -static int destroy_session() +static int destroy_session(const char *session_name) { int ret; - char *session_name, *path; - - if (opt_session_name == NULL) { - session_name = get_session_name(); - if (session_name == NULL) { - ret = CMD_ERROR; - goto error; - } - } else { - session_name = opt_session_name; - } ret = lttng_destroy_session(session_name); if (ret < 0) { @@ -85,39 +78,61 @@ static int destroy_session() default: break; } - goto free_name; - } - - path = config_get_default_path(); - if (path == NULL) { - ret = CMD_FATAL; - goto free_name; - } - - if (opt_session_name == NULL) { - config_destroy(path); - MSG("Session %s destroyed at %s", session_name, path); - } else { - MSG("Session %s destroyed", session_name); + goto error; } + MSG("Session %s destroyed", session_name); + config_destroy_default(); ret = CMD_SUCCESS; +error: + return ret; +} -free_name: - if (opt_session_name == NULL) { - free(session_name); +/* + * destroy_all_sessions + * + * Call destroy_sessions for each registered sessions + */ +static int destroy_all_sessions() +{ + int count, i, ret = CMD_SUCCESS; + struct lttng_session *sessions; + + count = lttng_list_sessions(&sessions); + if (count == 0) + MSG("No session found, nothing to do."); + for (i = 0; i < count; i++) { + ret = destroy_session(sessions[i].name); + if (ret < 0) + goto error; } error: return ret; } /* + * get_default_session_name + * + * Returns the default sessions name, if any + */ +static int get_default_session_name(char **name) +{ + char *session_name = get_session_name(); + if (session_name == NULL) + return CMD_ERROR; + *name = session_name; + return CMD_SUCCESS; +} + +/* * The 'destroy ' first level command */ int cmd_destroy(int argc, const char **argv) { - int opt, ret = CMD_SUCCESS; + int opt; + int ret = CMD_SUCCESS; static poptContext pc; + char *session_name = NULL; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); @@ -126,22 +141,38 @@ int cmd_destroy(int argc, const char **argv) switch (opt) { case OPT_HELP: usage(stdout); - goto end; + break; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); - goto end; + break; default: usage(stderr); ret = CMD_UNDEFINED; - goto end; + break; } + goto end; } - opt_session_name = (char*) poptGetArg(pc); + session_name = (char *) poptGetArg(pc); - ret = destroy_session(); + /* + * ignore session name in case all + * sessions are to be destroyed + */ + if (opt_destroy_all) { + ret = destroy_all_sessions(); + goto end; + } + if (session_name == NULL) { + ret = get_default_session_name(&session_name); + if (ret < 0 || session_name == NULL) + goto end; + } + ret = destroy_session(session_name); end: poptFreeContext(pc); + if (session_name != NULL) + free(session_name); return ret; } -- 1.7.9.5 From francis.giraldeau at gmail.com Mon May 28 13:00:28 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Mon, 28 May 2012 19:00:28 +0200 Subject: [lttng-dev] [PATCH 3/3] Update documentation for destroy all option In-Reply-To: <1338224428-16668-1-git-send-email-francis.giraldeau@gmail.com> References: <1338224428-16668-1-git-send-email-francis.giraldeau@gmail.com> Message-ID: <1338224428-16668-3-git-send-email-francis.giraldeau@gmail.com> Document the new option -a, --all of lttng destroy Signed-off-by: Francis Giraldeau --- doc/man/lttng.1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/man/lttng.1 b/doc/man/lttng.1 index f13d5d3..a74750e 100644 --- a/doc/man/lttng.1 +++ b/doc/man/lttng.1 @@ -239,6 +239,8 @@ If NAME is omitted, the session name is taken from the .lttngrc file. .nf \-h, \-\-help Show summary of possible options and commands. +\-a, \-\-all + Destroy all sessions \-\-list-options Simple listing of options .fi -- 1.7.9.5 From francis.giraldeau at gmail.com Mon May 28 13:00:26 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Mon, 28 May 2012 19:00:26 +0200 Subject: [lttng-dev] [PATCH 1/3] Improve delete of configuration Message-ID: <1338224428-16668-1-git-send-email-francis.giraldeau@gmail.com> Adding functions to encapsulate the configuration delete. Test if path to configuration exists before attempting to remove it. Signed-off-by: Francis Giraldeau --- src/bin/lttng/conf.c | 36 +++++++++++++++++++++++++++++++++++- src/bin/lttng/conf.h | 2 ++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/bin/lttng/conf.c b/src/bin/lttng/conf.c index 6f290b7..fe6898e 100644 --- a/src/bin/lttng/conf.c +++ b/src/bin/lttng/conf.c @@ -154,15 +154,49 @@ void config_destroy(char *path) return; } + if (!config_exists(config_path)) + goto done; + + DBG("Removing %s\n", config_path); ret = remove(config_path); if (ret < 0) { perror("remove config file"); } - +done: free(config_path); } /* + * config_destroy_default + * + * Destroys the default config + */ + +void config_destroy_default(void) +{ + char *path = config_get_default_path(); + if (path == NULL) + return; + config_destroy(path); +} + +/* + * config_exists + * + * Returns 1 if config exists, 0 otherwise + */ +int config_exists(const char *path) +{ + int ret; + struct stat info; + + ret = stat(path, &info); + if (ret < 0) + return 0; + return S_ISREG(info.st_mode) || S_ISDIR(info.st_mode); +} + +/* * config_read_session_name * * Returns the session name from the config file. diff --git a/src/bin/lttng/conf.h b/src/bin/lttng/conf.h index 1c471da..2cb04b0 100644 --- a/src/bin/lttng/conf.h +++ b/src/bin/lttng/conf.h @@ -21,6 +21,8 @@ #define CONFIG_FILENAME ".lttngrc" void config_destroy(char *path); +void config_destroy_default(void); +int config_exists(const char *path); int config_init(char *path); int config_add_session_name(char *path, char *name); char *config_get_default_path(void); -- 1.7.9.5 From alexandre.montplaisir at polymtl.ca Mon May 28 15:03:18 2012 From: alexandre.montplaisir at polymtl.ca (Alexandre Montplaisir) Date: Mon, 28 May 2012 15:03:18 -0400 Subject: [lttng-dev] Displaying graphical results In-Reply-To: References: Message-ID: <4FC3CBF6.1060608@polymtl.ca> On 12-05-27 12:45 PM, tchak adim wrote: > Hi all, > > i already install the lastest releases of lttng-module and lttng-ust , for > displaying results of captured traces i use babletrace . > i wanna display graphical results of these traces . > how can i do it ? > > Thanks . > Hi, At the moment, only the Eclipse viewer can show LTTng 2.0 traces. It's not officially released yet, but you can use the following procedure to get the latest code: http://wiki.eclipse.org/Linux_Tools_Project/LTTng_Eclipse_Plug-in_Development_Environement_Setup Support in LTTV (the other, more lightweight viewer) should be just around the corner. Cheers, -- Alexandre Montplaisir DORSAL lab, ?cole Polytechnique de Montr?al From mathieu.desnoyers at efficios.com Mon May 28 22:09:46 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 28 May 2012 22:09:46 -0400 Subject: [lttng-dev] userspace-rcu test scripts patches (was: ports/168339: [patch] sysutils/userspace-rcu update to 0.7.2 In-Reply-To: <86wr3v7tgh.wl%umq@ueo.co.jp> References: <86mx4tn165.wl%umq@ueo.co.jp> <20120527184255.GA14719@Krystal> <867gvxgmuf.wl%umq@ueo.co.jp> <20120528150036.GA17067@Krystal> <86wr3v7tgh.wl%umq@ueo.co.jp> Message-ID: <20120529020946.GA30850@Krystal> * Hirohisa Yamaguchi (umq at ueo.co.jp) wrote: > Hi, > > At Mon, 28 May 2012 11:00:36 -0400, > Mathieu Desnoyers wrote: > > > I think there're two different purposes of tests: > > > 1. for developers to ensure the implementations are correct > > > 2. for users to see his/her environment is safe to use the feature > > > -- built without an error does not mean it runs okay > > > > I think bashisms do not suit for latter purpose. > > > I agree that we should not depend on "bash" for any script installed > > into the system. > > > However, the "tests/" subdirectory is not currently installed on the > > user system. It's only used for in-tree testing, and "make check" > > execution. > > > There might come a point where we want to deploy some tests into the > > system so the library users can run them, I don't know. Maybe not yet > > though, as we would need to clean them up first. > > I meant `users' to be a person who wants to port the product to > his/her environment or maintain package of the product. > > I doubt that end users such as one who brings binaries from the OS's > package repository would run the test scripts when they're installed > into the system. Agreed. > > > > So at this stage, I would be fine with specifying in the README that > > running tests depends on bash. > > I understand. > > > However, if we can provide a wrapper for > > all the commands we need, which would be sourced by all scripts in the > > tests/ directory, which implements all wrappers into per-wrapper files, > > sourced by one toplevel wrapper file, I would be open to that too, given > > that it would make deployment of tests simpler for systems lacking bash > > support. e.g. > > > tests/wrapper/all.sh > > . wrapper/seq.sh > > ..... > > > > tests/wrapper/seq.sh > > tests/wrapper/.... > > > each test script: > > > > #!/bin/sh > > . wrapper/all.sh > > > ..... Although I don't personally have the resources to create these wrappers, I would be willing to take a patch that implements them. ;-) > > > > > > 5. NUM_CPUS might be determined at runtime: > > > > So I would recommend making this a > > > > parameter, and autodetect only if no parameter is provided. The > > > > autodetect would indeed have to be OS-specific. We could implement a > > > > get_nr_cpu.sh script within tests/ that detects the number of CPUs on > > > > the current OS. > > > > > > That sounds good. > > > > Can you prepare a patch for this ? > > I'll try next weekend. Thanks! I look forward to see it. > > > > > At Sun, 27 May 2012 15:44:12 -0400, > > > Mathieu Desnoyers wrote: > > > > > > # btw, test_perthreadlock under FreeBSD 10-CURRENT always fails > > > > > > # (releases prior to 9.0 are okay). > [...] > > OK, so it seems to be reproducible on both AMD and Intel, that's good > > news. > > I observed the error on both 32bits and 64bits, to add. > > > > You might want to compile userspace rcu with: > > > > make CFLAGS=-g > > > > to get debug symbols for the library. It will provide a more helpful > > backtrace. We should consider that the issue can come from a race > > between pthread_create and pthread_mutex_lock too. > > Here's another log file. > https://gist.github.com/2821618 > > I've built urcu with -g flag but, there still seems to be some problem > getting backtrace. Ah, I got it. It's a simple uninitialized mutex. The "0x5a5a5a5a" pattern caught my attention. Fixed by upstream commit: commit dee093381aa4f642a707fb4b28dbb9df0b8ad155 Author: Mathieu Desnoyers Date: Mon May 28 22:10:54 2012 -0400 Test fix: test_perthreadlock uninitialized mutex - Initialize the per thread mutexes. (fix) - Remove unused count_reader/count_writer variables. (cleanup) Signed-off-by: Mathieu Desnoyers Thanks! Mathieu > > > > Regards, > -- > > Hirohisa Yamaguchi > umq at ueo.co.jp -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From Fredrik_Oestman at mentor.com Tue May 29 04:35:25 2012 From: Fredrik_Oestman at mentor.com (Oestman, Fredrik) Date: Tue, 29 May 2012 08:35:25 +0000 Subject: [lttng-dev] Displaying graphical results In-Reply-To: References: Message-ID: <524C960C5DFC794E82BE548D825F05CF283435F8@EU-MBX-01.mgc.mentorg.com> Hi Tchak, > i already install the lastest releases of lttng-module and lttng-ust , for displaying results of captured traces i use babletrace . > i wanna display graphical results of these? traces . > how can i do it ? Mentor Graphics offers a product called Sourcery System Analyzer which does this and which can handle CTF (LTTng 2.0) as input. Cheers, Fredrik ?stman From david.goulet at polymtl.ca Tue May 29 14:43:08 2012 From: david.goulet at polymtl.ca (David Goulet) Date: Tue, 29 May 2012 14:43:08 -0400 Subject: [lttng-dev] [PATCH 1/3] Improve delete of configuration In-Reply-To: <1338224428-16668-1-git-send-email-francis.giraldeau@gmail.com> References: <1338224428-16668-1-git-send-email-francis.giraldeau@gmail.com> Message-ID: <4FC518BC.4070200@polymtl.ca> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi Francis, Thanks for the patch. I'll just ask you small adjustments that follow code "standard" and call convention. I know this is not that fun to fix but it makes thing easier after all :). On 28/05/12 01:00 PM, Francis Giraldeau wrote: > Adding functions to encapsulate the configuration delete. Test if path to > configuration exists before attempting to remove it. > > Signed-off-by: Francis Giraldeau --- > src/bin/lttng/conf.c | 36 +++++++++++++++++++++++++++++++++++- > src/bin/lttng/conf.h | 2 ++ 2 files changed, 37 insertions(+), 1 > deletion(-) > > diff --git a/src/bin/lttng/conf.c b/src/bin/lttng/conf.c index > 6f290b7..fe6898e 100644 --- a/src/bin/lttng/conf.c +++ > b/src/bin/lttng/conf.c @@ -154,15 +154,49 @@ void config_destroy(char > *path) return; } > > + if (!config_exists(config_path)) + goto done; Please add {} even for a one liner if(). > + + DBG("Removing %s\n", config_path); ret = remove(config_path); if (ret < > 0) { perror("remove config file"); } - +done: Accross the code, we uses "end:" instead of "done:". > free(config_path); } > > /* + * config_destroy_default + * + * Destroys the default config + */ + No space here and no double space before "*__Destr..." . Most of the comments are still like that in that file but we are trying to move away from that comments format. > +void config_destroy_default(void) +{ + char *path = > config_get_default_path(); + if (path == NULL) + return; Add {} > + config_destroy(path); +} + +/* + * config_exists + * + * Returns 1 if > config exists, 0 otherwise + */ +int config_exists(const char *path) +{ + > int ret; + struct stat info; + + ret = stat(path, &info); + if (ret < 0) + > return 0; Add {} Thanks a lot! David > + return S_ISREG(info.st_mode) || S_ISDIR(info.st_mode); +} + +/* * > config_read_session_name * * Returns the session name from the config > file. diff --git a/src/bin/lttng/conf.h b/src/bin/lttng/conf.h index > 1c471da..2cb04b0 100644 --- a/src/bin/lttng/conf.h +++ > b/src/bin/lttng/conf.h @@ -21,6 +21,8 @@ #define CONFIG_FILENAME > ".lttngrc" > > void config_destroy(char *path); +void config_destroy_default(void); +int > config_exists(const char *path); int config_init(char *path); int > config_add_session_name(char *path, char *name); char > *config_get_default_path(void); -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQEcBAEBAgAGBQJPxRi5AAoJEELoaioR9I02NZgH/3yQH/B+XTHTv6DR+VS4KYcU FO+NQIHK+jP4z3C7/FA/blfkFiJxjsv3SjSg8+6wVC+6deAflQ8avtT8FIIXMeRi WTbnYBC6xm1QTVP/UQFOadpf3r36P6je0AX7YxqZqyjn0nDkyN/BU/TPnaeTz2zg XzbSMItmzaeoGzMJnRL/7CpR6SAh+RpVmnwogNF85Y3yhAdSnrND08A33DDu5kU1 /FS2MpcwEQTXjld6PEVplKwDcQGCYmOtTiJWHdRFyZCTDVPJGFYz+0RTyx85EhCt 0SfGm6TdhpMFM3uybL8hbZsF1ndyk0ZcEgXmUchIpJA/ZYhN304erF0xLB65K4I= =kd2K -----END PGP SIGNATURE----- From david.goulet at polymtl.ca Tue May 29 14:44:43 2012 From: david.goulet at polymtl.ca (David Goulet) Date: Tue, 29 May 2012 14:44:43 -0400 Subject: [lttng-dev] [PATCH 2/3] Add destroy all session option In-Reply-To: <1338224428-16668-2-git-send-email-francis.giraldeau@gmail.com> References: <1338224428-16668-1-git-send-email-francis.giraldeau@gmail.com> <1338224428-16668-2-git-send-email-francis.giraldeau@gmail.com> Message-ID: <4FC5191B.8020608@polymtl.ca> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Comments below: On 28/05/12 01:00 PM, Francis Giraldeau wrote: > Destroy was limited to one session at a time. The option -a, --all destroys > all registered sessions at once. > > Signed-off-by: Francis Giraldeau --- > src/bin/lttng/commands/destroy.c | 107 > ++++++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 38 > deletions(-) > > diff --git a/src/bin/lttng/commands/destroy.c > b/src/bin/lttng/commands/destroy.c index a179da8..254e790 100644 --- > a/src/bin/lttng/commands/destroy.c +++ b/src/bin/lttng/commands/destroy.c > @@ -28,7 +28,7 @@ > > #include > > -static char *opt_session_name; +static int opt_destroy_all; > > enum { OPT_HELP = 1, @@ -38,6 +38,7 @@ enum { static struct poptOption > long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, > argDesc */ {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, + {"all", > 'a', POPT_ARG_VAL, &opt_destroy_all, 1, 0, 0}, {"list-options", 0, > POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL}, {0, 0, 0, 0, 0, 0, 0} > }; @@ -53,28 +54,20 @@ static void usage(FILE *ofp) fprintf(ofp, "get it > from the configuration directory (.lttng).\n"); fprintf(ofp, "\n"); > fprintf(ofp, " -h, --help Show this help\n"); + fprintf(ofp, " > -a, --all Destroy all sessions\n"); fprintf(ofp, " > --list-options Simple listing of options\n"); fprintf(ofp, "\n"); } > > /* - * Destroy a session removing the config directory and unregistering to > the - * session daemon. + * destroy_session + * + * Unregister the provided > session to the session daemon. On success, removes + * the default > configuration. */ -static int destroy_session() +static int > destroy_session(const char *session_name) { int ret; - char *session_name, > *path; - - if (opt_session_name == NULL) { - session_name = > get_session_name(); - if (session_name == NULL) { - ret = CMD_ERROR; - > goto error; - } - } else { - session_name = opt_session_name; - } > > ret = lttng_destroy_session(session_name); if (ret < 0) { @@ -85,39 +78,61 > @@ static int destroy_session() default: break; } - goto free_name; - } - > - path = config_get_default_path(); - if (path == NULL) { - ret = > CMD_FATAL; - goto free_name; - } - - if (opt_session_name == NULL) { - > config_destroy(path); - MSG("Session %s destroyed at %s", session_name, > path); - } else { - MSG("Session %s destroyed", session_name); + goto > error; } > > + MSG("Session %s destroyed", session_name); + config_destroy_default(); > ret = CMD_SUCCESS; +error: + return ret; +} > > -free_name: - if (opt_session_name == NULL) { - free(session_name); +/* + > * destroy_all_sessions + * + * Call destroy_sessions for each registered > sessions + */ +static int destroy_all_sessions() +{ + int count, i, ret = > CMD_SUCCESS; + struct lttng_session *sessions; + + count = > lttng_list_sessions(&sessions); + if (count == 0) + MSG("No session found, > nothing to do."); Add {} > + for (i = 0; i < count; i++) { + ret = > destroy_session(sessions[i].name); + if (ret < 0) + goto error; Add {} > } error: return ret; } > > /* + * get_default_session_name + * + * Returns the default sessions name, > if any + */ +static int get_default_session_name(char **name) +{ + char > *session_name = get_session_name(); + if (session_name == NULL) + return > CMD_ERROR; Add {} > + *name = session_name; + return CMD_SUCCESS; +} + +/* * The 'destroy > ' first level command */ int cmd_destroy(int argc, const char > **argv) { - int opt, ret = CMD_SUCCESS; + int opt; + int ret = > CMD_SUCCESS; static poptContext pc; + char *session_name = NULL; > > pc = poptGetContext(NULL, argc, argv, long_options, 0); > poptReadDefaultConfig(pc, 0); @@ -126,22 +141,38 @@ int cmd_destroy(int > argc, const char **argv) switch (opt) { case OPT_HELP: usage(stdout); - > goto end; + break; case OPT_LIST_OPTIONS: list_cmd_options(stdout, > long_options); - goto end; + break; default: usage(stderr); ret = > CMD_UNDEFINED; - goto end; + break; } + goto end; } > > - opt_session_name = (char*) poptGetArg(pc); + session_name = (char *) > poptGetArg(pc); > > - ret = destroy_session(); + /* + * ignore session name in case all + * > sessions are to be destroyed + */ + if (opt_destroy_all) { + ret = > destroy_all_sessions(); + goto end; + } + if (session_name == NULL) { + > ret = get_default_session_name(&session_name); + if (ret < 0 || > session_name == NULL) + goto end; Add {} > + } + ret = destroy_session(session_name); > > end: poptFreeContext(pc); + if (session_name != NULL) + > free(session_name); Add {} Thanks! David > return ret; } -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQEcBAEBAgAGBQJPxRkbAAoJEELoaioR9I02FAIH/082CmkWWTS/YEpa+YtcaXcb OjfIKeJMA1/Bey2wC8A2y+dyEl7ZKos1qMjuiB41vxHEqAy7tTUo7ZKEKOHSUq1v WG/WtV9OAUAaOouH/XdSPy4UAnvyl7WezKdHRnAHtil8RlSQEFyYpgSex6NCbKWY w16F3gPIe9IoubDuueeZhKoWmG2nCJnGf7Z2spV8YuJWXu2ZJggF2KjIiiRNDR10 augMkSWAsInfvYxZgN69R+SPFgN2iCMQemhDLONKTLj0Ag6gurcvr4VmryzJYA1D fvlc39MTY/DQLzky/3CsmjlO8oPC+kYwjWDwNu8VdwjvZ2vQF8QSTZFt6sA/8dQ= =Qkfy -----END PGP SIGNATURE----- From mathieu.desnoyers at efficios.com Tue May 29 16:10:08 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 29 May 2012 16:10:08 -0400 Subject: [lttng-dev] [RELEASE] Babeltrace 1.0.0-rc3 Message-ID: <20120529201008.GA17289@Krystal> The Babeltrace project provides trace read and write libraries, as well as a trace converter. Plugins can be created for any trace format to allow its conversion to/from another trace format. The main format expected to be converted to/from is the Common Trace Format (CTF). The default input format of the "babeltrace" command is CTF, and its default output format is a human-readable text log. The "babeltrace-log" command converts from a text log to a CTF trace. Unless something really unexpected happens, this should be the last RC before babeltrace 1.0.0 final. Changelog: 2012-05-29 Babeltrace 1.0.0-rc3 * Fix: converter error logic * Fix: report appropriate field in error message * Fix: support 64-bit events discarded counter types * Fix: add missing bt_ctf_get_int_len API * Fix bt_context_add_traces_recursive error code Project website: http://www.efficios.com/babeltrace Download link: http://www.efficios.com/files/babeltrace/ CTF specification: http://www.efficios.com/ctf -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From francis.giraldeau at gmail.com Wed May 30 05:10:57 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Wed, 30 May 2012 11:10:57 +0200 Subject: [lttng-dev] [PATCH 1/3] Improve delete of configuration In-Reply-To: <4FC518BC.4070200@polymtl.ca> References: <1338224428-16668-1-git-send-email-francis.giraldeau@gmail.com> <4FC518BC.4070200@polymtl.ca> Message-ID: <4FC5E421.8060807@gmail.com> Le 2012-05-29 20:43, David Goulet a ?crit : > > + if (!config_exists(config_path)) + goto done; > > Please add {} even for a one liner if(). I used checkpatch.pl from kernel scripts and the standard there is to remove them. I can add them, but then patches will not pass the check. IMHO I would follow the kernel style, since this makes easier for everyone to check their patches. Or maybe there are options to skip on-line-if-brace check? There is "--ignore BRACES" but then errors are reported, only the description is not shown. Will wait for your input on this. > > > + + DBG("Removing %s\n", config_path); ret = remove(config_path); if (ret < > > 0) { perror("remove config file"); } - +done: > > Accross the code, we uses "end:" instead of "done:". ok > > > free(config_path); } > > > /* + * config_destroy_default + * + * Destroys the default config + */ + > > No space here and no double space before "*__Destr..." . Most of the comments > are still like that in that file but we are trying to move away from that > comments format. ok, better to put only a space, I put two because there were two at many places. Will then provide a patch to fix other comments in the same file. Francis -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4476 bytes Desc: Signature cryptographique S/MIME URL: From Fredrik_Oestman at mentor.com Wed May 30 07:41:06 2012 From: Fredrik_Oestman at mentor.com (Oestman, Fredrik) Date: Wed, 30 May 2012 11:41:06 +0000 Subject: [lttng-dev] [RELEASE] Babeltrace 1.0.0-rc3 In-Reply-To: <20120529201008.GA17289@Krystal> References: <20120529201008.GA17289@Krystal> Message-ID: <524C960C5DFC794E82BE548D825F05CF28343A73@EU-MBX-01.mgc.mentorg.com> > Unless something really unexpected happens, this should be the last RC > before babeltrace 1.0.0 final. Please make this little change, otherwise ctf-text is always output regardless of "-o". Cheers, Fredrik ?stman diff --git a/converter/babeltrace.c b/converter/babeltrace.c index 55d89c8..fdbedae 100644 --- a/converter/babeltrace.c +++ b/converter/babeltrace.c @@ -487,7 +487,7 @@ int main(int argc, char **argv) } strlower(opt_input_format); } - if (opt_output_format) { + if (opt_output_format_arg) { opt_output_format = strdup(opt_output_format_arg); if (!opt_output_format) { partial_error = 1; From david.goulet at polymtl.ca Wed May 30 08:28:46 2012 From: david.goulet at polymtl.ca (David Goulet) Date: Wed, 30 May 2012 08:28:46 -0400 Subject: [lttng-dev] [PATCH 1/3] Improve delete of configuration In-Reply-To: <4FC5E421.8060807@gmail.com> References: <1338224428-16668-1-git-send-email-francis.giraldeau@gmail.com> <4FC518BC.4070200@polymtl.ca> <4FC5E421.8060807@gmail.com> Message-ID: <4FC6127E.3000509@polymtl.ca> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 30/05/12 05:10 AM, Francis Giraldeau wrote: > Le 2012-05-29 20:43, David Goulet a ?crit : >>> + if (!config_exists(config_path)) + goto done; >> >> Please add {} even for a one liner if(). > > I used checkpatch.pl from kernel scripts and the standard there is to > remove them. I can add them, but then patches will not pass the check. IMHO > I would follow the kernel style, since this makes easier for everyone to > check their patches. Or maybe there are options to skip on-line-if-brace > check? There is "--ignore BRACES" but then errors are reported, only the > description is not shown. Will wait for your input on this. Agreed but we don't use all of the kernel standard ;) ... the braces around the if...then is almost the only thing different. Thanks! David > >> >>> + + DBG("Removing %s\n", config_path); ret = remove(config_path); if >>> (ret < 0) { perror("remove config file"); } - +done: >> >> Accross the code, we uses "end:" instead of "done:". > > ok > >> >>> free(config_path); } >> >>> /* + * config_destroy_default + * + * Destroys the default config + */ >>> + >> >> No space here and no double space before "*__Destr..." . Most of the >> comments are still like that in that file but we are trying to move away >> from that comments format. > > ok, better to put only a space, I put two because there were two at many > places. Will then provide a patch to fix other comments in the same file. > > Francis > > > > _______________________________________________ lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQEcBAEBAgAGBQJPxhJ+AAoJEELoaioR9I022gYH/27ZkGP2opkvjVNF0mo7Sp7j YQrJyl87oi7uJ/4QWQt2GHkDnofFJKAqL4P5hgpkNeU2sTr9xPvtoMqm6GeweUW0 QwKMQ2VT85Oim98GuY+4jBPkqhehEy+eEPbsmKRJwUoKeJTpJ+uCAE8aZdmP8Qis cTMx2P+z4gb32230kJNAzSq6tyBkYrosC2rNTgV6ez+2Tml/LncqKXSlrtSG1Nrt jfiFoAjryX5ucH7M5hT60DLVWYxUkzaZu1bv4z2KalBVm212tfxIU64s9Yd9oUFS hf5VPXcycj5W0DipQdVeqzBZEJNf5dXqilTBYB03g2nOClQdujaKggAXLJmUluM= =QkM+ -----END PGP SIGNATURE----- From yannick.brosseau at gmail.com Wed May 30 08:32:44 2012 From: yannick.brosseau at gmail.com (Yannick Brosseau) Date: Wed, 30 May 2012 08:32:44 -0400 Subject: [lttng-dev] [PATCH 1/3] Improve delete of configuration In-Reply-To: <4FC5E421.8060807@gmail.com> References: <1338224428-16668-1-git-send-email-francis.giraldeau@gmail.com> <4FC518BC.4070200@polymtl.ca> <4FC5E421.8060807@gmail.com> Message-ID: <4FC6136C.9020308@gmail.com> On 2012-05-30 05:10, Francis Giraldeau wrote: > Le 2012-05-29 20:43, David Goulet a ?crit : > > > + if (!config_exists(config_path)) + goto done; > > > > Please add {} even for a one liner if(). > > I used checkpatch.pl from kernel scripts and the standard there is to > remove them. I can add them, but then patches will not pass the check. > IMHO I would follow the kernel style, since this makes easier for > everyone to check their patches. Or maybe there are options to skip > on-line-if-brace check? There is "--ignore BRACES" but then errors are > reported, only the description is not shown. Will wait for your input > on this. It's not because it's the kernel style that it's a good style... ;-) Yannick -------------- next part -------------- An HTML attachment was scrubbed... URL: From mathieu.desnoyers at efficios.com Wed May 30 08:33:51 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 30 May 2012 08:33:51 -0400 Subject: [lttng-dev] [RELEASE] Babeltrace 1.0.0-rc3 In-Reply-To: <524C960C5DFC794E82BE548D825F05CF28343A73@EU-MBX-01.mgc.mentorg.com> References: <20120529201008.GA17289@Krystal> <524C960C5DFC794E82BE548D825F05CF28343A73@EU-MBX-01.mgc.mentorg.com> Message-ID: <20120530123351.GA10522@Krystal> * Oestman, Fredrik (Fredrik_Oestman at mentor.com) wrote: > > Unless something really unexpected happens, this should be the last RC > > before babeltrace 1.0.0 final. > > Please make this little change, otherwise ctf-text is always output regardless of "-o". Merged. Thanks Fredrik ! Mathieu > > > Cheers, > > Fredrik ?stman > > > diff --git a/converter/babeltrace.c b/converter/babeltrace.c > index 55d89c8..fdbedae 100644 > --- a/converter/babeltrace.c > +++ b/converter/babeltrace.c > @@ -487,7 +487,7 @@ int main(int argc, char **argv) > } > strlower(opt_input_format); > } > - if (opt_output_format) { > + if (opt_output_format_arg) { > opt_output_format = strdup(opt_output_format_arg); > if (!opt_output_format) { > partial_error = 1; > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed May 30 08:37:52 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 30 May 2012 08:37:52 -0400 Subject: [lttng-dev] [PATCH 1/3] Improve delete of configuration In-Reply-To: <4FC6136C.9020308@gmail.com> References: <1338224428-16668-1-git-send-email-francis.giraldeau@gmail.com> <4FC518BC.4070200@polymtl.ca> <4FC5E421.8060807@gmail.com> <4FC6136C.9020308@gmail.com> Message-ID: <20120530123752.GA10772@Krystal> * Yannick Brosseau (yannick.brosseau at gmail.com) wrote: > On 2012-05-30 05:10, Francis Giraldeau wrote: > > Le 2012-05-29 20:43, David Goulet a ?crit : > > > > + if (!config_exists(config_path)) + goto done; > > > > > > Please add {} even for a one liner if(). > > > > I used checkpatch.pl from kernel scripts and the standard there is to > > remove them. I can add them, but then patches will not pass the check. > > IMHO I would follow the kernel style, since this makes easier for > > everyone to check their patches. Or maybe there are options to skip > > on-line-if-brace check? There is "--ignore BRACES" but then errors are > > reported, only the description is not shown. Will wait for your input > > on this. > It's not because it's the kernel style that it's a good style... ;-) All that being said, the reason why we agreed on having lttng-tools and lttv use brackets for single-liner if/else is because that code is exposed to less experienced programmers than, say, the Linux kernel. It's just too easy for someone to go from: if (cond) do_something(); to: if (cond) printf("test"); do_something(); as you notice, the condition does not apply to do_something anymore. Brackets ensure that this type of code change does not create any bug. I strictly follow the Linux kernel coding style for userspace rcu, lttng-ust and lttng-modules though. Thanks, Mathieu > > Yannick > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From yannick.brosseau at gmail.com Wed May 30 08:42:22 2012 From: yannick.brosseau at gmail.com (Yannick Brosseau) Date: Wed, 30 May 2012 08:42:22 -0400 Subject: [lttng-dev] [PATCH 1/3] Improve delete of configuration In-Reply-To: <20120530123752.GA10772@Krystal> References: <1338224428-16668-1-git-send-email-francis.giraldeau@gmail.com> <4FC518BC.4070200@polymtl.ca> <4FC5E421.8060807@gmail.com> <4FC6136C.9020308@gmail.com> <20120530123752.GA10772@Krystal> Message-ID: <4FC615AE.6070308@gmail.com> On 2012-05-30 08:37, Mathieu Desnoyers wrote: > * > > I strictly follow the Linux kernel coding style for userspace rcu, > lttng-ust and lttng-modules though. BTW, I don't think we've put this information anywhere in the tree. > Thanks, > > Mathieu > > >> Yannick >> _______________________________________________ >> lttng-dev mailing list >> lttng-dev at lists.lttng.org >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > From mathieu.desnoyers at efficios.com Wed May 30 09:08:54 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 30 May 2012 09:08:54 -0400 Subject: [lttng-dev] [PATCH 1/3] Improve delete of configuration In-Reply-To: <4FC615AE.6070308@gmail.com> References: <1338224428-16668-1-git-send-email-francis.giraldeau@gmail.com> <4FC518BC.4070200@polymtl.ca> <4FC5E421.8060807@gmail.com> <4FC6136C.9020308@gmail.com> <20120530123752.GA10772@Krystal> <4FC615AE.6070308@gmail.com> Message-ID: <20120530130854.GA12010@Krystal> * Yannick Brosseau (yannick.brosseau at gmail.com) wrote: > On 2012-05-30 08:37, Mathieu Desnoyers wrote: > > * > > > > I strictly follow the Linux kernel coding style for userspace rcu, > > lttng-ust and lttng-modules though. > BTW, I don't think we've put this information anywhere in the tree. Good point. I just pushed CodingStyle documents into userspace-rcu, lttng-tools, lttng-ust, lttng-modules, and babeltrace. Thanks, Mathieu > > > Thanks, > > > > Mathieu > > > > > >> Yannick > >> _______________________________________________ > >> lttng-dev mailing list > >> lttng-dev at lists.lttng.org > >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed May 30 14:28:29 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 30 May 2012 14:28:29 -0400 Subject: [lttng-dev] [RELEASE] Babeltrace 1.0.0-rc4 Message-ID: <20120530182829.GA27707@Krystal> The Babeltrace project provides trace read and write libraries, as well as a trace converter. Plugins can be created for any trace format to allow its conversion to/from another trace format. The main format expected to be converted to/from is the Common Trace Format (CTF). The default input format of the "babeltrace" command is CTF, and its default output format is a human-readable text log. The "babeltrace-log" command converts from a text log to a CTF trace. Mainly due to the fix for page-aligned mmap, this calls for another RC round. Changelog: 2012-05-30 Babeltrace 1.0.0-rc4 * Add CodingStyle to tarball * Add coding style document * Fix: babeltrace should use output format argument * Fix: accept traces which skip stream ids * Use mmap_align * align header: define PAGE_SIZE * Implement mmap alignment header * Cleanup: type warnings * Cleanup: do not overwrite const argv parameters Project website: http://www.efficios.com/babeltrace Download link: http://www.efficios.com/files/babeltrace/ CTF specification: http://www.efficios.com/ctf -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From francis.giraldeau at gmail.com Wed May 30 19:43:59 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Thu, 31 May 2012 01:43:59 +0200 Subject: [lttng-dev] [PATCH 1/3] Add destroy all session option Message-ID: <1338421441-21682-1-git-send-email-francis.giraldeau@gmail.com> Destroy was limited to one session at a time. The option -a, --all destroys all registered sessions at once. * fixed braces Signed-off-by: Francis Giraldeau --- src/bin/lttng/commands/destroy.c | 112 +++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 38 deletions(-) diff --git a/src/bin/lttng/commands/destroy.c b/src/bin/lttng/commands/destroy.c index a179da8..5b69cb5 100644 --- a/src/bin/lttng/commands/destroy.c +++ b/src/bin/lttng/commands/destroy.c @@ -28,7 +28,7 @@ #include -static char *opt_session_name; +static int opt_destroy_all; enum { OPT_HELP = 1, @@ -38,6 +38,7 @@ enum { static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, + {"all", 'a', POPT_ARG_VAL, &opt_destroy_all, 1, 0, 0}, {"list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL}, {0, 0, 0, 0, 0, 0, 0} }; @@ -53,28 +54,20 @@ static void usage(FILE *ofp) fprintf(ofp, "get it from the configuration directory (.lttng).\n"); fprintf(ofp, "\n"); fprintf(ofp, " -h, --help Show this help\n"); + fprintf(ofp, " -a, --all Destroy all sessions\n"); fprintf(ofp, " --list-options Simple listing of options\n"); fprintf(ofp, "\n"); } /* - * Destroy a session removing the config directory and unregistering to the - * session daemon. + * destroy_session + * + * Unregister the provided session to the session daemon. On success, removes + * the default configuration. */ -static int destroy_session() +static int destroy_session(const char *session_name) { int ret; - char *session_name, *path; - - if (opt_session_name == NULL) { - session_name = get_session_name(); - if (session_name == NULL) { - ret = CMD_ERROR; - goto error; - } - } else { - session_name = opt_session_name; - } ret = lttng_destroy_session(session_name); if (ret < 0) { @@ -85,39 +78,64 @@ static int destroy_session() default: break; } - goto free_name; - } - - path = config_get_default_path(); - if (path == NULL) { - ret = CMD_FATAL; - goto free_name; - } - - if (opt_session_name == NULL) { - config_destroy(path); - MSG("Session %s destroyed at %s", session_name, path); - } else { - MSG("Session %s destroyed", session_name); + goto error; } + MSG("Session %s destroyed", session_name); + config_destroy_default(); ret = CMD_SUCCESS; +error: + return ret; +} -free_name: - if (opt_session_name == NULL) { - free(session_name); +/* + * destroy_all_sessions + * + * Call destroy_sessions for each registered sessions + */ +static int destroy_all_sessions() +{ + int count, i, ret = CMD_SUCCESS; + struct lttng_session *sessions; + + count = lttng_list_sessions(&sessions); + if (count == 0) { + MSG("No session found, nothing to do."); + } + for (i = 0; i < count; i++) { + ret = destroy_session(sessions[i].name); + if (ret < 0) { + goto error; + } } error: return ret; } /* + * get_default_session_name + * + * Returns the default sessions name, if any + */ +static int get_default_session_name(char **name) +{ + char *session_name = get_session_name(); + if (session_name == NULL) { + return CMD_ERROR; + } + *name = session_name; + return CMD_SUCCESS; +} + +/* * The 'destroy ' first level command */ int cmd_destroy(int argc, const char **argv) { - int opt, ret = CMD_SUCCESS; + int opt; + int ret = CMD_SUCCESS; static poptContext pc; + char *session_name = NULL; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); @@ -126,22 +144,40 @@ int cmd_destroy(int argc, const char **argv) switch (opt) { case OPT_HELP: usage(stdout); - goto end; + break; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); - goto end; + break; default: usage(stderr); ret = CMD_UNDEFINED; - goto end; + break; } + goto end; } - opt_session_name = (char*) poptGetArg(pc); + session_name = (char *) poptGetArg(pc); - ret = destroy_session(); + /* + * ignore session name in case all + * sessions are to be destroyed + */ + if (opt_destroy_all) { + ret = destroy_all_sessions(); + goto end; + } + if (session_name == NULL) { + ret = get_default_session_name(&session_name); + if (ret < 0 || session_name == NULL) { + goto end; + } + } + ret = destroy_session(session_name); end: poptFreeContext(pc); + if (session_name != NULL) { + free(session_name); + } return ret; } -- 1.7.9.5 From francis.giraldeau at gmail.com Wed May 30 19:44:00 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Thu, 31 May 2012 01:44:00 +0200 Subject: [lttng-dev] [PATCH 2/3] Update documentation for destroy all option In-Reply-To: <1338421441-21682-1-git-send-email-francis.giraldeau@gmail.com> References: <1338421441-21682-1-git-send-email-francis.giraldeau@gmail.com> Message-ID: <1338421441-21682-2-git-send-email-francis.giraldeau@gmail.com> Document the new option -a, --all of lttng destroy Signed-off-by: Francis Giraldeau --- doc/man/lttng.1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/man/lttng.1 b/doc/man/lttng.1 index f13d5d3..a74750e 100644 --- a/doc/man/lttng.1 +++ b/doc/man/lttng.1 @@ -239,6 +239,8 @@ If NAME is omitted, the session name is taken from the .lttngrc file. .nf \-h, \-\-help Show summary of possible options and commands. +\-a, \-\-all + Destroy all sessions \-\-list-options Simple listing of options .fi -- 1.7.9.5 From francis.giraldeau at gmail.com Wed May 30 19:44:01 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Thu, 31 May 2012 01:44:01 +0200 Subject: [lttng-dev] [PATCH 3/3] Fix comments formating in conf.c In-Reply-To: <1338421441-21682-1-git-send-email-francis.giraldeau@gmail.com> References: <1338421441-21682-1-git-send-email-francis.giraldeau@gmail.com> Message-ID: <1338421441-21682-3-git-send-email-francis.giraldeau@gmail.com> Comments should be indented with one space only. Signed-off-by: Francis Giraldeau --- src/bin/lttng/conf.c | 68 +++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/bin/lttng/conf.c b/src/bin/lttng/conf.c index 50af228..dd386fe 100644 --- a/src/bin/lttng/conf.c +++ b/src/bin/lttng/conf.c @@ -29,10 +29,10 @@ #include "conf.h" /* - * config_get_file_path + * config_get_file_path * - * Returns the path with '/CONFIG_FILENAME' added to it; - * path will be NULL if an error occurs. + * Returns the path with '/CONFIG_FILENAME' added to it; + * path will be NULL if an error occurs. */ char *config_get_file_path(char *path) { @@ -48,10 +48,10 @@ char *config_get_file_path(char *path) } /* - * open_config + * open_config * - * Returns an open FILE pointer to the config file; - * on error, NULL is returned. + * Returns an open FILE pointer to the config file; + * on error, NULL is returned. */ static FILE *open_config(char *path, const char *mode) { @@ -76,11 +76,11 @@ error: } /* - * create_config_file + * create_config_file * - * Creates the empty config file at the path. - * On success, returns 0; - * on error, returns -1. + * Creates the empty config file at the path. + * On success, returns 0; + * on error, returns -1. */ static int create_config_file(char *path) { @@ -101,11 +101,11 @@ error: } /* - * write_config + * write_config * - * Append data to the config file in file_path - * On success, returns 0; - * on error, returns -1. + * Append data to the config file in file_path + * On success, returns 0; + * on error, returns -1. */ static int write_config(char *file_path, size_t size, char *data) { @@ -130,9 +130,9 @@ end: } /* - * config_get_default_path + * config_get_default_path * - * Returns the HOME directory path. Caller MUST NOT free(3) the return pointer. + * Returns the HOME directory path. Caller MUST NOT free(3) the return pointer. */ char *config_get_default_path(void) { @@ -140,9 +140,9 @@ char *config_get_default_path(void) } /* - * config_destroy + * config_destroy * - * Destroys directory config and file config. + * Destroys directory config and file config. */ void config_destroy(char *path) { @@ -168,9 +168,9 @@ end: } /* - * config_destroy_default + * config_destroy_default * - * Destroys the default config + * Destroys the default config */ void config_destroy_default(void) @@ -183,9 +183,9 @@ void config_destroy_default(void) } /* - * config_exists + * config_exists * - * Returns 1 if config exists, 0 otherwise + * Returns 1 if config exists, 0 otherwise */ int config_exists(const char *path) { @@ -200,11 +200,11 @@ int config_exists(const char *path) } /* - * config_read_session_name + * config_read_session_name * - * Returns the session name from the config file. - * The caller is responsible for freeing the returned string. - * On error, NULL is returned. + * Returns the session name from the config file. + * The caller is responsible for freeing the returned string. + * On error, NULL is returned. */ char *config_read_session_name(char *path) { @@ -252,11 +252,11 @@ found: } /* - * config_add_session_name + * config_add_session_name * - * Write session name option to the config file. - * On success, returns 0; - * on error, returns -1. + * Write session name option to the config file. + * On success, returns 0; + * on error, returns -1. */ int config_add_session_name(char *path, char *name) { @@ -278,11 +278,11 @@ error: } /* - * config_init + * config_init * - * Init configuration directory and file. - * On success, returns 0; - * on error, returns -1. + * Init configuration directory and file. + * On success, returns 0; + * on error, returns -1. */ int config_init(char *session_name) { -- 1.7.9.5 From francis.giraldeau at gmail.com Wed May 30 19:45:01 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Thu, 31 May 2012 01:45:01 +0200 Subject: [lttng-dev] [PATCH 1/3] Add destroy all session option Message-ID: <1338421503-21766-1-git-send-email-francis.giraldeau@gmail.com> Destroy was limited to one session at a time. The option -a, --all destroys all registered sessions at once. * fixed braces Signed-off-by: Francis Giraldeau --- src/bin/lttng/commands/destroy.c | 112 +++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 38 deletions(-) diff --git a/src/bin/lttng/commands/destroy.c b/src/bin/lttng/commands/destroy.c index a179da8..5b69cb5 100644 --- a/src/bin/lttng/commands/destroy.c +++ b/src/bin/lttng/commands/destroy.c @@ -28,7 +28,7 @@ #include -static char *opt_session_name; +static int opt_destroy_all; enum { OPT_HELP = 1, @@ -38,6 +38,7 @@ enum { static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, + {"all", 'a', POPT_ARG_VAL, &opt_destroy_all, 1, 0, 0}, {"list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL}, {0, 0, 0, 0, 0, 0, 0} }; @@ -53,28 +54,20 @@ static void usage(FILE *ofp) fprintf(ofp, "get it from the configuration directory (.lttng).\n"); fprintf(ofp, "\n"); fprintf(ofp, " -h, --help Show this help\n"); + fprintf(ofp, " -a, --all Destroy all sessions\n"); fprintf(ofp, " --list-options Simple listing of options\n"); fprintf(ofp, "\n"); } /* - * Destroy a session removing the config directory and unregistering to the - * session daemon. + * destroy_session + * + * Unregister the provided session to the session daemon. On success, removes + * the default configuration. */ -static int destroy_session() +static int destroy_session(const char *session_name) { int ret; - char *session_name, *path; - - if (opt_session_name == NULL) { - session_name = get_session_name(); - if (session_name == NULL) { - ret = CMD_ERROR; - goto error; - } - } else { - session_name = opt_session_name; - } ret = lttng_destroy_session(session_name); if (ret < 0) { @@ -85,39 +78,64 @@ static int destroy_session() default: break; } - goto free_name; - } - - path = config_get_default_path(); - if (path == NULL) { - ret = CMD_FATAL; - goto free_name; - } - - if (opt_session_name == NULL) { - config_destroy(path); - MSG("Session %s destroyed at %s", session_name, path); - } else { - MSG("Session %s destroyed", session_name); + goto error; } + MSG("Session %s destroyed", session_name); + config_destroy_default(); ret = CMD_SUCCESS; +error: + return ret; +} -free_name: - if (opt_session_name == NULL) { - free(session_name); +/* + * destroy_all_sessions + * + * Call destroy_sessions for each registered sessions + */ +static int destroy_all_sessions() +{ + int count, i, ret = CMD_SUCCESS; + struct lttng_session *sessions; + + count = lttng_list_sessions(&sessions); + if (count == 0) { + MSG("No session found, nothing to do."); + } + for (i = 0; i < count; i++) { + ret = destroy_session(sessions[i].name); + if (ret < 0) { + goto error; + } } error: return ret; } /* + * get_default_session_name + * + * Returns the default sessions name, if any + */ +static int get_default_session_name(char **name) +{ + char *session_name = get_session_name(); + if (session_name == NULL) { + return CMD_ERROR; + } + *name = session_name; + return CMD_SUCCESS; +} + +/* * The 'destroy ' first level command */ int cmd_destroy(int argc, const char **argv) { - int opt, ret = CMD_SUCCESS; + int opt; + int ret = CMD_SUCCESS; static poptContext pc; + char *session_name = NULL; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); @@ -126,22 +144,40 @@ int cmd_destroy(int argc, const char **argv) switch (opt) { case OPT_HELP: usage(stdout); - goto end; + break; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); - goto end; + break; default: usage(stderr); ret = CMD_UNDEFINED; - goto end; + break; } + goto end; } - opt_session_name = (char*) poptGetArg(pc); + session_name = (char *) poptGetArg(pc); - ret = destroy_session(); + /* + * ignore session name in case all + * sessions are to be destroyed + */ + if (opt_destroy_all) { + ret = destroy_all_sessions(); + goto end; + } + if (session_name == NULL) { + ret = get_default_session_name(&session_name); + if (ret < 0 || session_name == NULL) { + goto end; + } + } + ret = destroy_session(session_name); end: poptFreeContext(pc); + if (session_name != NULL) { + free(session_name); + } return ret; } -- 1.7.9.5 From francis.giraldeau at gmail.com Wed May 30 19:45:02 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Thu, 31 May 2012 01:45:02 +0200 Subject: [lttng-dev] [PATCH 2/3] Update documentation for destroy all option In-Reply-To: <1338421503-21766-1-git-send-email-francis.giraldeau@gmail.com> References: <1338421503-21766-1-git-send-email-francis.giraldeau@gmail.com> Message-ID: <1338421503-21766-2-git-send-email-francis.giraldeau@gmail.com> Document the new option -a, --all of lttng destroy Signed-off-by: Francis Giraldeau --- doc/man/lttng.1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/man/lttng.1 b/doc/man/lttng.1 index f13d5d3..a74750e 100644 --- a/doc/man/lttng.1 +++ b/doc/man/lttng.1 @@ -239,6 +239,8 @@ If NAME is omitted, the session name is taken from the .lttngrc file. .nf \-h, \-\-help Show summary of possible options and commands. +\-a, \-\-all + Destroy all sessions \-\-list-options Simple listing of options .fi -- 1.7.9.5 From francis.giraldeau at gmail.com Wed May 30 19:50:03 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Thu, 31 May 2012 01:50:03 +0200 Subject: [lttng-dev] (no subject) Message-ID: <1338421807-21921-1-git-send-email-francis.giraldeau@gmail.com> Sorry for the noise about previous patches, I did a mistake when specifying revs. Here is the good patch series. From francis.giraldeau at gmail.com Wed May 30 19:50:04 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Thu, 31 May 2012 01:50:04 +0200 Subject: [lttng-dev] [PATCH 1/4] Improve delete of configuration In-Reply-To: <1338421807-21921-1-git-send-email-francis.giraldeau@gmail.com> References: <1338421807-21921-1-git-send-email-francis.giraldeau@gmail.com> Message-ID: <1338421807-21921-2-git-send-email-francis.giraldeau@gmail.com> Adding functions to encapsulate the configuration delete. Test if path to configuration exists before attempting to remove it. * fixed braces and goto name Signed-off-by: Francis Giraldeau --- src/bin/lttng/conf.c | 39 ++++++++++++++++++++++++++++++++++++++- src/bin/lttng/conf.h | 2 ++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/bin/lttng/conf.c b/src/bin/lttng/conf.c index 6f290b7..50af228 100644 --- a/src/bin/lttng/conf.c +++ b/src/bin/lttng/conf.c @@ -154,15 +154,52 @@ void config_destroy(char *path) return; } + if (!config_exists(config_path)) { + goto end; + } + + DBG("Removing %s\n", config_path); ret = remove(config_path); if (ret < 0) { perror("remove config file"); } - +end: free(config_path); } /* + * config_destroy_default + * + * Destroys the default config + */ + +void config_destroy_default(void) +{ + char *path = config_get_default_path(); + if (path == NULL) { + return; + } + config_destroy(path); +} + +/* + * config_exists + * + * Returns 1 if config exists, 0 otherwise + */ +int config_exists(const char *path) +{ + int ret; + struct stat info; + + ret = stat(path, &info); + if (ret < 0) { + return 0; + } + return S_ISREG(info.st_mode) || S_ISDIR(info.st_mode); +} + +/* * config_read_session_name * * Returns the session name from the config file. diff --git a/src/bin/lttng/conf.h b/src/bin/lttng/conf.h index 1c471da..2cb04b0 100644 --- a/src/bin/lttng/conf.h +++ b/src/bin/lttng/conf.h @@ -21,6 +21,8 @@ #define CONFIG_FILENAME ".lttngrc" void config_destroy(char *path); +void config_destroy_default(void); +int config_exists(const char *path); int config_init(char *path); int config_add_session_name(char *path, char *name); char *config_get_default_path(void); -- 1.7.9.5 From francis.giraldeau at gmail.com Wed May 30 19:50:05 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Thu, 31 May 2012 01:50:05 +0200 Subject: [lttng-dev] [PATCH 2/4] Add destroy all session option In-Reply-To: <1338421807-21921-1-git-send-email-francis.giraldeau@gmail.com> References: <1338421807-21921-1-git-send-email-francis.giraldeau@gmail.com> Message-ID: <1338421807-21921-3-git-send-email-francis.giraldeau@gmail.com> Destroy was limited to one session at a time. The option -a, --all destroys all registered sessions at once. * fixed braces Signed-off-by: Francis Giraldeau --- src/bin/lttng/commands/destroy.c | 112 +++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 38 deletions(-) diff --git a/src/bin/lttng/commands/destroy.c b/src/bin/lttng/commands/destroy.c index a179da8..5b69cb5 100644 --- a/src/bin/lttng/commands/destroy.c +++ b/src/bin/lttng/commands/destroy.c @@ -28,7 +28,7 @@ #include -static char *opt_session_name; +static int opt_destroy_all; enum { OPT_HELP = 1, @@ -38,6 +38,7 @@ enum { static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, + {"all", 'a', POPT_ARG_VAL, &opt_destroy_all, 1, 0, 0}, {"list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL}, {0, 0, 0, 0, 0, 0, 0} }; @@ -53,28 +54,20 @@ static void usage(FILE *ofp) fprintf(ofp, "get it from the configuration directory (.lttng).\n"); fprintf(ofp, "\n"); fprintf(ofp, " -h, --help Show this help\n"); + fprintf(ofp, " -a, --all Destroy all sessions\n"); fprintf(ofp, " --list-options Simple listing of options\n"); fprintf(ofp, "\n"); } /* - * Destroy a session removing the config directory and unregistering to the - * session daemon. + * destroy_session + * + * Unregister the provided session to the session daemon. On success, removes + * the default configuration. */ -static int destroy_session() +static int destroy_session(const char *session_name) { int ret; - char *session_name, *path; - - if (opt_session_name == NULL) { - session_name = get_session_name(); - if (session_name == NULL) { - ret = CMD_ERROR; - goto error; - } - } else { - session_name = opt_session_name; - } ret = lttng_destroy_session(session_name); if (ret < 0) { @@ -85,39 +78,64 @@ static int destroy_session() default: break; } - goto free_name; - } - - path = config_get_default_path(); - if (path == NULL) { - ret = CMD_FATAL; - goto free_name; - } - - if (opt_session_name == NULL) { - config_destroy(path); - MSG("Session %s destroyed at %s", session_name, path); - } else { - MSG("Session %s destroyed", session_name); + goto error; } + MSG("Session %s destroyed", session_name); + config_destroy_default(); ret = CMD_SUCCESS; +error: + return ret; +} -free_name: - if (opt_session_name == NULL) { - free(session_name); +/* + * destroy_all_sessions + * + * Call destroy_sessions for each registered sessions + */ +static int destroy_all_sessions() +{ + int count, i, ret = CMD_SUCCESS; + struct lttng_session *sessions; + + count = lttng_list_sessions(&sessions); + if (count == 0) { + MSG("No session found, nothing to do."); + } + for (i = 0; i < count; i++) { + ret = destroy_session(sessions[i].name); + if (ret < 0) { + goto error; + } } error: return ret; } /* + * get_default_session_name + * + * Returns the default sessions name, if any + */ +static int get_default_session_name(char **name) +{ + char *session_name = get_session_name(); + if (session_name == NULL) { + return CMD_ERROR; + } + *name = session_name; + return CMD_SUCCESS; +} + +/* * The 'destroy ' first level command */ int cmd_destroy(int argc, const char **argv) { - int opt, ret = CMD_SUCCESS; + int opt; + int ret = CMD_SUCCESS; static poptContext pc; + char *session_name = NULL; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); @@ -126,22 +144,40 @@ int cmd_destroy(int argc, const char **argv) switch (opt) { case OPT_HELP: usage(stdout); - goto end; + break; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); - goto end; + break; default: usage(stderr); ret = CMD_UNDEFINED; - goto end; + break; } + goto end; } - opt_session_name = (char*) poptGetArg(pc); + session_name = (char *) poptGetArg(pc); - ret = destroy_session(); + /* + * ignore session name in case all + * sessions are to be destroyed + */ + if (opt_destroy_all) { + ret = destroy_all_sessions(); + goto end; + } + if (session_name == NULL) { + ret = get_default_session_name(&session_name); + if (ret < 0 || session_name == NULL) { + goto end; + } + } + ret = destroy_session(session_name); end: poptFreeContext(pc); + if (session_name != NULL) { + free(session_name); + } return ret; } -- 1.7.9.5 From francis.giraldeau at gmail.com Wed May 30 19:50:06 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Thu, 31 May 2012 01:50:06 +0200 Subject: [lttng-dev] [PATCH 3/4] Update documentation for destroy all option In-Reply-To: <1338421807-21921-1-git-send-email-francis.giraldeau@gmail.com> References: <1338421807-21921-1-git-send-email-francis.giraldeau@gmail.com> Message-ID: <1338421807-21921-4-git-send-email-francis.giraldeau@gmail.com> Document the new option -a, --all of lttng destroy Signed-off-by: Francis Giraldeau --- doc/man/lttng.1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/man/lttng.1 b/doc/man/lttng.1 index f13d5d3..a74750e 100644 --- a/doc/man/lttng.1 +++ b/doc/man/lttng.1 @@ -239,6 +239,8 @@ If NAME is omitted, the session name is taken from the .lttngrc file. .nf \-h, \-\-help Show summary of possible options and commands. +\-a, \-\-all + Destroy all sessions \-\-list-options Simple listing of options .fi -- 1.7.9.5 From francis.giraldeau at gmail.com Wed May 30 19:50:07 2012 From: francis.giraldeau at gmail.com (Francis Giraldeau) Date: Thu, 31 May 2012 01:50:07 +0200 Subject: [lttng-dev] [PATCH 4/4] Fix comments formating in conf.c In-Reply-To: <1338421807-21921-1-git-send-email-francis.giraldeau@gmail.com> References: <1338421807-21921-1-git-send-email-francis.giraldeau@gmail.com> Message-ID: <1338421807-21921-5-git-send-email-francis.giraldeau@gmail.com> Comments should be indented with one space only. Signed-off-by: Francis Giraldeau --- src/bin/lttng/conf.c | 68 +++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/bin/lttng/conf.c b/src/bin/lttng/conf.c index 50af228..dd386fe 100644 --- a/src/bin/lttng/conf.c +++ b/src/bin/lttng/conf.c @@ -29,10 +29,10 @@ #include "conf.h" /* - * config_get_file_path + * config_get_file_path * - * Returns the path with '/CONFIG_FILENAME' added to it; - * path will be NULL if an error occurs. + * Returns the path with '/CONFIG_FILENAME' added to it; + * path will be NULL if an error occurs. */ char *config_get_file_path(char *path) { @@ -48,10 +48,10 @@ char *config_get_file_path(char *path) } /* - * open_config + * open_config * - * Returns an open FILE pointer to the config file; - * on error, NULL is returned. + * Returns an open FILE pointer to the config file; + * on error, NULL is returned. */ static FILE *open_config(char *path, const char *mode) { @@ -76,11 +76,11 @@ error: } /* - * create_config_file + * create_config_file * - * Creates the empty config file at the path. - * On success, returns 0; - * on error, returns -1. + * Creates the empty config file at the path. + * On success, returns 0; + * on error, returns -1. */ static int create_config_file(char *path) { @@ -101,11 +101,11 @@ error: } /* - * write_config + * write_config * - * Append data to the config file in file_path - * On success, returns 0; - * on error, returns -1. + * Append data to the config file in file_path + * On success, returns 0; + * on error, returns -1. */ static int write_config(char *file_path, size_t size, char *data) { @@ -130,9 +130,9 @@ end: } /* - * config_get_default_path + * config_get_default_path * - * Returns the HOME directory path. Caller MUST NOT free(3) the return pointer. + * Returns the HOME directory path. Caller MUST NOT free(3) the return pointer. */ char *config_get_default_path(void) { @@ -140,9 +140,9 @@ char *config_get_default_path(void) } /* - * config_destroy + * config_destroy * - * Destroys directory config and file config. + * Destroys directory config and file config. */ void config_destroy(char *path) { @@ -168,9 +168,9 @@ end: } /* - * config_destroy_default + * config_destroy_default * - * Destroys the default config + * Destroys the default config */ void config_destroy_default(void) @@ -183,9 +183,9 @@ void config_destroy_default(void) } /* - * config_exists + * config_exists * - * Returns 1 if config exists, 0 otherwise + * Returns 1 if config exists, 0 otherwise */ int config_exists(const char *path) { @@ -200,11 +200,11 @@ int config_exists(const char *path) } /* - * config_read_session_name + * config_read_session_name * - * Returns the session name from the config file. - * The caller is responsible for freeing the returned string. - * On error, NULL is returned. + * Returns the session name from the config file. + * The caller is responsible for freeing the returned string. + * On error, NULL is returned. */ char *config_read_session_name(char *path) { @@ -252,11 +252,11 @@ found: } /* - * config_add_session_name + * config_add_session_name * - * Write session name option to the config file. - * On success, returns 0; - * on error, returns -1. + * Write session name option to the config file. + * On success, returns 0; + * on error, returns -1. */ int config_add_session_name(char *path, char *name) { @@ -278,11 +278,11 @@ error: } /* - * config_init + * config_init * - * Init configuration directory and file. - * On success, returns 0; - * on error, returns -1. + * Init configuration directory and file. + * On success, returns 0; + * on error, returns -1. */ int config_init(char *session_name) { -- 1.7.9.5 From david.goulet at polymtl.ca Thu May 31 12:55:50 2012 From: david.goulet at polymtl.ca (David Goulet) Date: Thu, 31 May 2012 12:55:50 -0400 Subject: [lttng-dev] [PATCH 1/4] Improve delete of configuration In-Reply-To: <1338421807-21921-2-git-send-email-francis.giraldeau@gmail.com> References: <1338421807-21921-1-git-send-email-francis.giraldeau@gmail.com> <1338421807-21921-2-git-send-email-francis.giraldeau@gmail.com> Message-ID: <4FC7A296.3040306@polymtl.ca> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Merge thanks! Neat feature :) Cheers! David On 30/05/12 07:50 PM, Francis Giraldeau wrote: > Adding functions to encapsulate the configuration delete. Test if path to > configuration exists before attempting to remove it. > > * fixed braces and goto name > > Signed-off-by: Francis Giraldeau --- > src/bin/lttng/conf.c | 39 ++++++++++++++++++++++++++++++++++++++- > src/bin/lttng/conf.h | 2 ++ 2 files changed, 40 insertions(+), 1 > deletion(-) > > diff --git a/src/bin/lttng/conf.c b/src/bin/lttng/conf.c index > 6f290b7..50af228 100644 --- a/src/bin/lttng/conf.c +++ > b/src/bin/lttng/conf.c @@ -154,15 +154,52 @@ void config_destroy(char > *path) return; } > > + if (!config_exists(config_path)) { + goto end; + } + + DBG("Removing > %s\n", config_path); ret = remove(config_path); if (ret < 0) { > perror("remove config file"); } - +end: free(config_path); } > > /* + * config_destroy_default + * + * Destroys the default config + */ + > +void config_destroy_default(void) +{ + char *path = > config_get_default_path(); + if (path == NULL) { + return; + } + > config_destroy(path); +} + +/* + * config_exists + * + * Returns 1 if > config exists, 0 otherwise + */ +int config_exists(const char *path) +{ + > int ret; + struct stat info; + + ret = stat(path, &info); + if (ret < 0) { > + return 0; + } + return S_ISREG(info.st_mode) || S_ISDIR(info.st_mode); > +} + +/* * config_read_session_name * * Returns the session name from the > config file. diff --git a/src/bin/lttng/conf.h b/src/bin/lttng/conf.h index > 1c471da..2cb04b0 100644 --- a/src/bin/lttng/conf.h +++ > b/src/bin/lttng/conf.h @@ -21,6 +21,8 @@ #define CONFIG_FILENAME > ".lttngrc" > > void config_destroy(char *path); +void config_destroy_default(void); +int > config_exists(const char *path); int config_init(char *path); int > config_add_session_name(char *path, char *name); char > *config_get_default_path(void); -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQEcBAEBAgAGBQJPx6KTAAoJEELoaioR9I02WnwH/3vZiMcGoiBNgEZ9D0zdVPsD ro2G5Sv9e+fHV8r0PNp5IojB0o99SERqi2rvyznKEhh8KrPu56KjcgS05MqtDjnP 9Q7jTtKSE8OXpQSUeCxHcLdgMoaDIX1Lh7FMeiFpxaPJTY3RkBA7vQJjvMTS2PlB QV94+qc6ZfS89keBt+IxWix5Wmgu9TX7YoMPDmb2cv+I2Sc01eyrdxSz68GhMSp7 bgEYNn54HhvF7SM0rTMrLrQo8NlEoi32U+ZkYyZjcdb0JFnIajmw/AaSb6Vv2Vnw xvi7nRamjGjDOBmjcK3iZn4Xi0op7DK8h/W09FvXD95b687wfmwrv3Q7q9lzJLE= =tV7S -----END PGP SIGNATURE----- From vannigenua at gmail.com Thu May 17 05:20:59 2012 From: vannigenua at gmail.com (Vanni Genua) Date: Thu, 17 May 2012 09:20:59 -0000 Subject: [lttng-dev] ERROR while "making" lttng-ust-2.0.1 Message-ID: Why do I get the following error? localhost lttng-ust-2.0.1 # make make all-recursive make[1]: Entering directory `/usr/src/lttng-ust-2.0.1' Making all in . make[2]: Entering directory `/usr/src/lttng-ust-2.0.1' make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1' Making all in include make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/include' make[2]: Nothing to be done for `all'. make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/include' Making all in snprintf make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/snprintf' make[2]: Nothing to be done for `all'. make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/snprintf' Making all in libringbuffer make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/libringbuffer' CC libringbuffer_la-ring_buffer_backend.lo CC libringbuffer_la-ring_buffer_frontend.lo CCLD libringbuffer.la make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/libringbuffer' Making all in liblttng-ust-comm make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' make[2]: Nothing to be done for `all'. make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' Making all in liblttng-ust make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust' CC liblttng_ust_tracepoint_la-tracepoint.lo CCLD liblttng-ust-tracepoint.la CC lttng-ust-comm.lo CC lttng-ust-abi.lo CC ltt-probes.lo cccd CC lttng-probe-ust.lo CC lttng-context-vtid.lo CC lttng-context-vpid.lo CC lttng-context-pthread-id.lo CC lttng-context-procname.lo CC ltt-context.lo CC ltt-events.lo CCLD liblttng-ust-runtime.la CC ust-core.lo CC ltt-ring-buffer-client-discard.lo CC ltt-ring-buffer-client-overwrite.lo CC ltt-ring-buffer-metadata-client.lo CCLD liblttng-ust-support.la CCLD liblttng-ust.la copying selected object files to avoid basename conflicts... make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust' Making all in liblttng-ust-ctl make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' CC ustctl.lo CCLD liblttng-ust-ctl.la make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' Making all in liblttng-ust-fork make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' CCLD liblttng-ust-fork.la make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' Making all in liblttng-ust-libc-wrapper make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' CC lttng-ust-malloc.lo CCLD liblttng-ust-libc-wrapper.la make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' Making all in tools make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/tools' make[2]: Nothing to be done for `all'. make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/tools' Making all in tests make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/tests' Making all in . make[3]: Entering directory `/usr/src/lttng-ust-2.0.1/tests' make[3]: Nothing to be done for `all-am'. make[3]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests' Making all in hello make[3]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/hello' CC tp.o CCLD hello ../../liblttng-ust/.libs/liblttng-ust.a(libringbuffer_la-shm.o): In function `shm_object_table_append': /usr/src/lttng-ust-2.0.1/libringbuffer/shm.c:108: warning: the use of `mktemp' is dangerous, better use `mkstemp' make[3]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/hello' Making all in hello-static-lib make[3]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/hello-static-lib' CC tp.lo CCLD liblttng-ust-provider-ust-test-hello.la CCLD hello /usr/src/lttng-ust-2.0.1/liblttng-ust/.libs/liblttng-ust.a(libringbuffer_la-shm.o): In function `shm_object_table_append': /usr/src/lttng-ust-2.0.1/libringbuffer/shm.c:108: warning: the use of `mktemp' is dangerous, better use `mkstemp' make[3]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/hello-static-lib' Making all in fork make[3]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/fork' CC fork.o CCLD fork ../../liblttng-ust/.libs/liblttng-ust.a(libringbuffer_la-shm.o): In function `shm_object_table_append': /usr/src/lttng-ust-2.0.1/libringbuffer/shm.c:108: warning: the use of `mktemp' is dangerous, better use `mkstemp' CC fork2.o CCLD fork2 ../../liblttng-ust/.libs/liblttng-ust.a(libringbuffer_la-shm.o): In function `shm_object_table_append': /usr/src/lttng-ust-2.0.1/libringbuffer/shm.c:108: warning: the use of `mktemp' is dangerous, better use `mkstemp' make[3]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/fork' Making all in ust-basic-tracing make[3]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/ust-basic-tracing' CC ust-basic-tracing.o CCLD ust-basic-tracing ../../libringbuffer/.libs/libringbuffer.a(libringbuffer_la-shm.o): In function `shm_object_table_append': /usr/src/lttng-ust-2.0.1/libringbuffer/shm.c:108: warning: the use of `mktemp' is dangerous, better use `mkstemp' make[3]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/ust-basic-tracing' Making all in ust-multi-test make[3]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/ust-multi-test' CC ust-multi-test.o CCLD ust-multi-test ../../libringbuffer/.libs/libringbuffer.a(libringbuffer_la-shm.o): In function `shm_object_table_append': /usr/src/lttng-ust-2.0.1/libringbuffer/shm.c:108: warning: the use of `mktemp' is dangerous, better use `mkstemp' make[3]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/ust-multi-test' Making all in demo make[3]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/demo' CC tp.lo CC tp2.lo CCLD liblttng-ust-provider-ust-tests-demo.la libtool: link: can not build a shared library libtool: link: See the libtool documentation for more information. libtool: link: Fatal configuration error. make[3]: *** [liblttng-ust-provider-ust-tests-demo.la] Error 1 make[3]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/demo' make[2]: *** [all-recursive] Error 1 make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1' make: *** [all] Error 2 -------------- next part -------------- An HTML attachment was scrubbed... URL: From vannigenua at gmail.com Fri May 18 03:23:47 2012 From: vannigenua at gmail.com (Vanni Genua) Date: Fri, 18 May 2012 07:23:47 -0000 Subject: [lttng-dev] HOW TO DOWNLOAD LTTng 2.0 stable? In-Reply-To: <20120517143031.GA30839@Krystal> References: <4FB3EDC0.7080006@polymtl.ca> <4FB50A3E.7030508@polymtl.ca> <20120517143031.GA30839@Krystal> Message-ID: I did it a minute ago, now the problems are the undefined references at the end of this logs: localhost lttng-ust-2.0.1 # ./configure --build=armv7a-unknown-linux- gnueabi checking build system type... armv7a-unknown-linux-gnueabi checking host system type... armv7a-unknown-linux-gnueabi checking target system type... armv7a-unknown-linux-gnueabi checking how to convert armv7a-unknown-linux-gnueabi file names to armv7a-unknown-linux-gnueabi format... func_convert_file_noop checking how to convert armv7a-unknown-linux-gnueabi file names to toolchain format... func_convert_file_noop checking library format for the host system... elf32-littlearm configure: creating ./config.status config.status: creating Makefile config.status: creating doc/Makefile config.status: creating doc/examples/Makefile config.status: creating include/Makefile config.status: creating include/lttng/ust-version.h config.status: creating snprintf/Makefile config.status: creating libringbuffer/Makefile config.status: creating liblttng-ust-comm/Makefile config.status: creating liblttng-ust/Makefile config.status: creating liblttng-ust-ctl/Makefile config.status: creating liblttng-ust-fork/Makefile config.status: creating liblttng-ust-java/Makefile config.status: creating liblttng-ust-libc-wrapper/Makefile config.status: creating tools/Makefile config.status: creating tests/Makefile config.status: creating tests/hello/Makefile config.status: creating tests/hello-static-lib/Makefile config.status: creating tests/hello.cxx/Makefile config.status: creating tests/demo/Makefile config.status: creating tests/fork/Makefile config.status: creating tests/ust-basic-tracing/Makefile config.status: creating tests/ust-multi-test/Makefile config.status: creating lttng-ust.pc config.status: creating config.h config.status: config.h is unchanged config.status: creating include/lttng/ust-config.h config.status: include/lttng/ust-config.h is unchanged config.status: executing depfiles commands config.status: executing libtool commands Version name: Annedd'ale New type of beer, 100% from Quebec, flavored with sapin beaumier needles, with a touch of hops. LTTng-UST will be built with the following options: Library format: elf32-littlearm Java support (JNI): Disabled sdt.h integration: Disabled Type 'make' to compile. localhost lttng-ust-2.0.1 # make make all-recursive make[1]: Entering directory `/usr/src/lttng-ust-2.0.1' Making all in . make[2]: Entering directory `/usr/src/lttng-ust-2.0.1' make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1' Making all in include make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/include' make[2]: Nothing to be done for `all'. make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/include' Making all in snprintf make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/snprintf' make[2]: Nothing to be done for `all'. make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/snprintf' Making all in libringbuffer make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/libringbuffer' CC libringbuffer_la-ring_buffer_backend.lo CC libringbuffer_la-ring_buffer_frontend.lo CCLD libringbuffer.la make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/libringbuffer' Making all in liblttng-ust-comm make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' make[2]: Nothing to be done for `all'. make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' Making all in liblttng-ust make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust' CC liblttng_ust_tracepoint_la-tracepoint.lo CCLD liblttng-ust-tracepoint.la CC lttng-ust-comm.lo CC lttng-ust-abi.lo CC ltt-probes.lo CC lttng-probe-ust.lo CC lttng-context-vtid.lo CC lttng-context-vpid.lo CC lttng-context-pthread-id.lo CC lttng-context-procname.lo CC ltt-context.lo CC ltt-events.lo CCLD liblttng-ust-runtime.la CC ust-core.lo CC ltt-ring-buffer-client-discard.lo CC ltt-ring-buffer-client-overwrite.lo CC ltt-ring-buffer-metadata-client.lo CCLD liblttng-ust-support.la CCLD liblttng-ust.la /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/../../../../armv7a-unknown-linux-gnueabi/bin/ld: warning: creating a DT_TEXTREL in object. copying selected object files to avoid basename conflicts... make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust' Making all in liblttng-ust-ctl make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' CC ustctl.lo CCLD liblttng-ust-ctl.la /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/../../../../armv7a-unknown-linux-gnueabi/bin/ld: warning: creating a DT_TEXTREL in object. make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' Making all in liblttng-ust-fork make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' CCLD liblttng-ust-fork.la make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' Making all in liblttng-ust-libc-wrapper make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' CC lttng-ust-malloc.lo CCLD liblttng-ust-libc-wrapper.la make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' Making all in tools make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/tools' make[2]: Nothing to be done for `all'. make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/tools' Making all in tests make[2]: Entering directory `/usr/src/lttng-ust-2.0.1/tests' Making all in . make[3]: Entering directory `/usr/src/lttng-ust-2.0.1/tests' make[3]: Nothing to be done for `all-am'. make[3]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests' Making all in hello make[3]: Entering directory `/usr/src/lttng-ust-2.0.1/tests/hello' CC tp.o CCLD hello ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to `__num_possible_cpus' ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to `shm_object_table_create' ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to `shm_object_table_append_shadow' ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to `shm_object_table_append' ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to `zalloc_shm' ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to `_get_num_possible_cpus' ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to `align_shm' ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to `shm_object_table_destroy' collect2: ld returned 1 exit status make[3]: *** [hello] Error 1 make[3]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests/hello' make[2]: *** [all-recursive] Error 1 make[2]: Leaving directory `/usr/src/lttng-ust-2.0.1/tests' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/usr/src/lttng-ust-2.0.1' make: *** [all] Error 2 localhost lttng-ust-2.0.1 # On Thu, May 17, 2012 at 2:30 PM, Mathieu Desnoyers < mathieu.desnoyers at efficios.com> wrote: > * Alexandre Montplaisir (alexandre.montplaisir at polymtl.ca) wrote: > > This is an interesting problem, I'll forward it to the mailing list. > > > > > > On 12-05-17 10:02 AM, Vanni Genua wrote: > > > Also why I get this error? > > > see the attached log file. > > > Best regards. > > > V.G. > > > > > > > > > > localhost lttng-ust-2.0.1 # ./configure > > checking build system type... armv7l-unknown-linux-gnueabi > > checking host system type... armv7l-unknown-linux-gnueabi > > checking target system type... armv7l-unknown-linux-gnueabi > > checking for a BSD-compatible install... /usr/bin/install -c > > checking whether build environment is sane... yes > > checking for a thread-safe mkdir -p... /bin/mkdir -p > > checking for gawk... gawk > > checking whether make sets $(MAKE)... yes > > checking whether make supports nested variables... yes > > checking for a sed that does not truncate output... /bin/sed > > checking for gcc... gcc > > checking whether the C compiler works... yes > > checking for C compiler default output file name... a.out > > checking for suffix of executables... > > checking whether we are cross compiling... no > > checking for suffix of object files... o > > checking whether we are using the GNU C compiler... yes > > checking whether gcc accepts -g... yes > > checking for gcc option to accept ISO C89... none needed > > checking for style of include used by make... GNU > > checking dependency style of gcc... gcc3 > > checking for g++... g++ > > checking whether we are using the GNU C++ compiler... yes > > checking whether g++ accepts -g... yes > > checking dependency style of g++... gcc3 > > checking whether make sets $(MAKE)... (cached) yes > > checking how to print strings... printf > > checking for a sed that does not truncate output... (cached) /bin/sed > > checking for grep that handles long lines and -e... /bin/grep > > checking for egrep... /bin/grep -E > > checking for fgrep... /bin/grep -F > > checking for ld used by gcc... /usr/armv7a-unknown-linux-gnueabi/bin/ld > > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is GNU > ld... yes > > checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B > > checking the name lister (/usr/bin/nm -B) interface... BSD nm > > checking whether ln -s works... yes > > checking the maximum length of command line arguments... 1572864 > > checking whether the shell understands some XSI constructs... yes > > checking whether the shell understands "+="... yes > > checking how to convert armv7l-unknown-linux-gnueabi file names to > armv7l-unknown-linux-gnueabi format... func_convert_file_noop > > checking how to convert armv7l-unknown-linux-gnueabi file names to > toolchain format... func_convert_file_noop > > checking for /usr/armv7a-unknown-linux-gnueabi/bin/ld option to reload > object files... -r > > checking for objdump... objdump > > checking how to recognize dependent libraries... pass_all > > checking for dlltool... no > > checking how to associate runtime and link libraries... printf %s\n > > checking for ar... ar > > checking for archiver @FILE support... @ > > checking for strip... strip > > checking for ranlib... ranlib > > checking command to parse /usr/bin/nm -B output from gcc object... ok > > checking for sysroot... no > > checking for mt... no > > checking if : is a manifest tool... no > > checking how to run the C preprocessor... gcc -E > > checking for ANSI C header files... yes > > checking for sys/types.h... yes > > checking for sys/stat.h... yes > > checking for stdlib.h... yes > > checking for string.h... yes > > checking for memory.h... yes > > checking for strings.h... yes > > checking for inttypes.h... yes > > checking for stdint.h... yes > > checking for unistd.h... yes > > checking for dlfcn.h... yes > > checking for objdir... .libs > > checking if gcc supports -fno-rtti -fno-exceptions... no > > checking for gcc option to produce PIC... -fPIC -DPIC > > checking if gcc PIC flag -fPIC -DPIC works... yes > > checking if gcc static flag -static works... yes > > checking if gcc supports -c -o file.o... yes > > checking if gcc supports -c -o file.o... (cached) yes > > checking whether the gcc linker > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... yes > > checking whether -lc should be explicitly linked in... no > > checking dynamic linker characteristics... GNU/Linux ld.so > > checking how to hardcode library paths into programs... immediate > > checking whether stripping libraries is possible... yes > > checking if libtool supports shared libraries... yes > > checking whether to build shared libraries... yes > > checking whether to build static libraries... yes > > checking how to run the C++ preprocessor... g++ -E > > checking for ld used by g++... /usr/armv7a-unknown-linux-gnueabi/bin/ld > > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is GNU > ld... yes > > checking whether the g++ linker > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... yes > > checking for g++ option to produce PIC... -fPIC -DPIC > > checking if g++ PIC flag -fPIC -DPIC works... yes > > checking if g++ static flag -static works... yes > > checking if g++ supports -c -o file.o... yes > > checking if g++ supports -c -o file.o... (cached) yes > > checking whether the g++ linker > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... yes > > checking dynamic linker characteristics... (cached) GNU/Linux ld.so > > checking how to hardcode library paths into programs... immediate > > checking for dlopen in -ldl... yes > > checking for pthread_create in -lpthread... yes > > checking for uuid_generate in -luuid... yes > > checking for inline... inline > > checking for stdlib.h... (cached) yes > > checking for GNU libc compatible malloc... yes > > checking for gettimeofday... yes > > checking for munmap... yes > > checking for socket... yes > > checking for strerror... yes > > checking for strtol... yes > > checking for sched_getcpu... yes > > checking for sysconf... yes > > checking for makeinfo... yes > > checking urcu-bp.h usability... yes > > checking urcu-bp.h presence... yes > > checking for urcu-bp.h... yes > > checking caa_likely()... yes > > checking for synchronize_rcu_bp in -lurcu-bp... yes > > checking for call_rcu_bp in -lurcu-bp... yes > > checking library format for the host system... configure: error: unable > to detect library format (unsupported architecture (armv7l)?) > > Does it help if you add a line: > > armv7l) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; > > near line 188 of configure.ac ? > > What we did in userspace RCU is to use "arm*". > > Thanks, > > Mathieu > > > > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > -------------- next part -------------- An HTML attachment was scrubbed... URL: From vannigenua at gmail.com Fri May 18 12:15:30 2012 From: vannigenua at gmail.com (Vanni Genua) Date: Fri, 18 May 2012 16:15:30 -0000 Subject: [lttng-dev] HOW TO DOWNLOAD LTTng 2.0 stable? In-Reply-To: <20120518151850.GA17152@Krystal> References: <4FB3EDC0.7080006@polymtl.ca> <4FB50A3E.7030508@polymtl.ca> <20120517143031.GA30839@Krystal> <20120518151850.GA17152@Krystal> Message-ID: I asked you about the HEAD download (mater and stable2.0), I found its size was about 180kB, whereas the 2.0.1 was over 500KB. I also wrote you that the HEAD (master?) missed the configure file, so it was not possible to run ./configure ) May you post me the exact link where the full HEAD is? I'm using gcc 4.4.2 (I guess, because now I'm not at the office). Thanks. Vanni On 5/18/12, Mathieu Desnoyers wrote: > * Vanni Genua (vannigenua at gmail.com) wrote: >> I did it a minute ago, now the problems are the undefined references at >> the >> end of this logs: >> >> localhost lttng-ust-2.0.1 # ./configure --build=armv7a-unknown-linux- >> gnueabi > > This looks like a problem with your toolchain (gcc/ld/...), since AFAIK > Alexandre is able to cross-build for ARMv7 on Ubuntu. You should ask > your distribution vendor. > > Also, you seem to be still using lttng-ust 2.0.1 instead of "HEAD". > Which commit ID are you using ? > > Thanks, > > Mathieu > > > >> >> checking build system type... >> armv7a-unknown-linux-gnueabi >> >> checking host system type... >> armv7a-unknown-linux-gnueabi >> >> checking target system type... >> armv7a-unknown-linux-gnueabi >> >> checking how to convert armv7a-unknown-linux-gnueabi file names to >> armv7a-unknown-linux-gnueabi format... >> func_convert_file_noop >> checking how to convert armv7a-unknown-linux-gnueabi file names to >> toolchain format... >> func_convert_file_noop >> checking library format for the host system... >> elf32-littlearm >> >> configure: creating >> ./config.status >> >> config.status: creating >> Makefile >> >> config.status: creating >> doc/Makefile >> >> config.status: creating >> doc/examples/Makefile >> >> config.status: creating >> include/Makefile >> >> config.status: creating >> include/lttng/ust-version.h >> >> config.status: creating >> snprintf/Makefile >> >> config.status: creating >> libringbuffer/Makefile >> >> config.status: creating >> liblttng-ust-comm/Makefile >> >> config.status: creating >> liblttng-ust/Makefile >> >> config.status: creating >> liblttng-ust-ctl/Makefile >> >> config.status: creating >> liblttng-ust-fork/Makefile >> >> config.status: creating >> liblttng-ust-java/Makefile >> >> config.status: creating >> liblttng-ust-libc-wrapper/Makefile >> >> config.status: creating >> tools/Makefile >> >> config.status: creating >> tests/Makefile >> >> config.status: creating >> tests/hello/Makefile >> >> config.status: creating >> tests/hello-static-lib/Makefile >> >> config.status: creating >> tests/hello.cxx/Makefile >> >> config.status: creating >> tests/demo/Makefile >> >> config.status: creating >> tests/fork/Makefile >> >> config.status: creating >> tests/ust-basic-tracing/Makefile >> >> config.status: creating >> tests/ust-multi-test/Makefile >> >> config.status: creating >> lttng-ust.pc >> >> config.status: creating >> config.h >> >> config.status: config.h is >> unchanged >> >> config.status: creating >> include/lttng/ust-config.h >> >> config.status: include/lttng/ust-config.h is >> unchanged >> >> config.status: executing depfiles >> commands >> >> config.status: executing libtool >> commands >> >> >> >> Version name: >> Annedd'ale >> >> New type of beer, 100% from Quebec, flavored with sapin beaumier needles, >> with a touch of >> hops. >> >> >> LTTng-UST will be built with the following >> options: >> >> Library format: >> elf32-littlearm >> >> >> >> Java support (JNI): >> Disabled >> >> sdt.h integration: >> Disabled >> >> >> >> Type 'make' to >> compile. >> >> localhost lttng-ust-2.0.1 # >> make >> >> make >> all-recursive >> >> make[1]: Entering directory >> `/usr/src/lttng-ust-2.0.1' >> >> Making all in >> . >> >> make[2]: Entering directory >> `/usr/src/lttng-ust-2.0.1' >> >> make[2]: Leaving directory >> `/usr/src/lttng-ust-2.0.1' >> >> Making all in >> include >> >> make[2]: Entering directory >> `/usr/src/lttng-ust-2.0.1/include' >> >> make[2]: Nothing to be done for >> `all'. >> >> make[2]: Leaving directory >> `/usr/src/lttng-ust-2.0.1/include' >> >> Making all in >> snprintf >> >> make[2]: Entering directory >> `/usr/src/lttng-ust-2.0.1/snprintf' >> >> make[2]: Nothing to be done for >> `all'. >> >> make[2]: Leaving directory >> `/usr/src/lttng-ust-2.0.1/snprintf' >> >> Making all in >> libringbuffer >> >> make[2]: Entering directory >> `/usr/src/lttng-ust-2.0.1/libringbuffer' >> >> CC >> libringbuffer_la-ring_buffer_backend.lo >> >> CC >> libringbuffer_la-ring_buffer_frontend.lo >> >> CCLD libringbuffer.la >> >> make[2]: Leaving directory >> `/usr/src/lttng-ust-2.0.1/libringbuffer' >> >> Making all in >> liblttng-ust-comm >> >> make[2]: Entering directory >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' >> >> make[2]: Nothing to be done for >> `all'. >> >> make[2]: Leaving directory >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' >> >> Making all in >> liblttng-ust >> >> make[2]: Entering directory >> `/usr/src/lttng-ust-2.0.1/liblttng-ust' >> >> CC >> liblttng_ust_tracepoint_la-tracepoint.lo >> >> CCLD liblttng-ust-tracepoint.la >> >> CC >> lttng-ust-comm.lo >> >> CC >> lttng-ust-abi.lo >> >> CC >> ltt-probes.lo >> >> CC >> lttng-probe-ust.lo >> >> CC >> lttng-context-vtid.lo >> >> CC >> lttng-context-vpid.lo >> >> CC >> lttng-context-pthread-id.lo >> >> CC >> lttng-context-procname.lo >> >> CC >> ltt-context.lo >> >> CC >> ltt-events.lo >> >> CCLD liblttng-ust-runtime.la >> >> CC >> ust-core.lo >> >> CC >> ltt-ring-buffer-client-discard.lo >> >> CC >> ltt-ring-buffer-client-overwrite.lo >> >> CC >> ltt-ring-buffer-metadata-client.lo >> >> CCLD liblttng-ust-support.la >> >> CCLD liblttng-ust.la >> >> /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/../../../../armv7a-unknown-linux-gnueabi/bin/ld: >> warning: creating a DT_TEXTREL in object. >> copying selected object files to avoid basename >> conflicts... >> >> make[2]: Leaving directory >> `/usr/src/lttng-ust-2.0.1/liblttng-ust' >> >> Making all in >> liblttng-ust-ctl >> >> make[2]: Entering directory >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' >> >> CC >> ustctl.lo >> >> CCLD liblttng-ust-ctl.la >> >> /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/../../../../armv7a-unknown-linux-gnueabi/bin/ld: >> warning: creating a DT_TEXTREL in object. >> make[2]: Leaving directory >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' >> >> Making all in >> liblttng-ust-fork >> >> make[2]: Entering directory >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' >> >> CCLD liblttng-ust-fork.la >> >> make[2]: Leaving directory >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' >> >> Making all in >> liblttng-ust-libc-wrapper >> >> make[2]: Entering directory >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' >> >> CC >> lttng-ust-malloc.lo >> >> CCLD liblttng-ust-libc-wrapper.la >> >> make[2]: Leaving directory >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' >> >> Making all in >> tools >> >> make[2]: Entering directory >> `/usr/src/lttng-ust-2.0.1/tools' >> >> make[2]: Nothing to be done for >> `all'. >> >> make[2]: Leaving directory >> `/usr/src/lttng-ust-2.0.1/tools' >> >> Making all in >> tests >> >> make[2]: Entering directory >> `/usr/src/lttng-ust-2.0.1/tests' >> >> Making all in >> . >> >> make[3]: Entering directory >> `/usr/src/lttng-ust-2.0.1/tests' >> >> make[3]: Nothing to be done for >> `all-am'. >> >> make[3]: Leaving directory >> `/usr/src/lttng-ust-2.0.1/tests' >> >> Making all in >> hello >> >> make[3]: Entering directory >> `/usr/src/lttng-ust-2.0.1/tests/hello' >> >> CC >> tp.o >> >> CCLD >> hello >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to >> `__num_possible_cpus' >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to >> `shm_object_table_create' >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to >> `shm_object_table_append_shadow' >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to >> `shm_object_table_append' >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to >> `zalloc_shm' >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to >> `_get_num_possible_cpus' >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to >> `align_shm' >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to >> `shm_object_table_destroy' >> >> collect2: ld returned 1 exit >> status >> >> make[3]: *** [hello] Error >> 1 >> >> make[3]: Leaving directory >> `/usr/src/lttng-ust-2.0.1/tests/hello' >> >> make[2]: *** [all-recursive] Error >> 1 >> >> make[2]: Leaving directory >> `/usr/src/lttng-ust-2.0.1/tests' >> >> make[1]: *** [all-recursive] Error >> 1 >> >> make[1]: Leaving directory >> `/usr/src/lttng-ust-2.0.1' >> >> make: *** [all] Error >> 2 >> >> localhost lttng-ust-2.0.1 # >> >> >> On Thu, May 17, 2012 at 2:30 PM, Mathieu Desnoyers < >> mathieu.desnoyers at efficios.com> wrote: >> >> > * Alexandre Montplaisir (alexandre.montplaisir at polymtl.ca) wrote: >> > > This is an interesting problem, I'll forward it to the mailing list. >> > > >> > > >> > > On 12-05-17 10:02 AM, Vanni Genua wrote: >> > > > Also why I get this error? >> > > > see the attached log file. >> > > > Best regards. >> > > > V.G. >> > > > >> > > > >> > > >> > > localhost lttng-ust-2.0.1 # ./configure >> > > checking build system type... armv7l-unknown-linux-gnueabi >> > > checking host system type... armv7l-unknown-linux-gnueabi >> > > checking target system type... armv7l-unknown-linux-gnueabi >> > > checking for a BSD-compatible install... /usr/bin/install -c >> > > checking whether build environment is sane... yes >> > > checking for a thread-safe mkdir -p... /bin/mkdir -p >> > > checking for gawk... gawk >> > > checking whether make sets $(MAKE)... yes >> > > checking whether make supports nested variables... yes >> > > checking for a sed that does not truncate output... /bin/sed >> > > checking for gcc... gcc >> > > checking whether the C compiler works... yes >> > > checking for C compiler default output file name... a.out >> > > checking for suffix of executables... >> > > checking whether we are cross compiling... no >> > > checking for suffix of object files... o >> > > checking whether we are using the GNU C compiler... yes >> > > checking whether gcc accepts -g... yes >> > > checking for gcc option to accept ISO C89... none needed >> > > checking for style of include used by make... GNU >> > > checking dependency style of gcc... gcc3 >> > > checking for g++... g++ >> > > checking whether we are using the GNU C++ compiler... yes >> > > checking whether g++ accepts -g... yes >> > > checking dependency style of g++... gcc3 >> > > checking whether make sets $(MAKE)... (cached) yes >> > > checking how to print strings... printf >> > > checking for a sed that does not truncate output... (cached) /bin/sed >> > > checking for grep that handles long lines and -e... /bin/grep >> > > checking for egrep... /bin/grep -E >> > > checking for fgrep... /bin/grep -F >> > > checking for ld used by gcc... >> > > /usr/armv7a-unknown-linux-gnueabi/bin/ld >> > > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is >> > > GNU >> > ld... yes >> > > checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B >> > > checking the name lister (/usr/bin/nm -B) interface... BSD nm >> > > checking whether ln -s works... yes >> > > checking the maximum length of command line arguments... 1572864 >> > > checking whether the shell understands some XSI constructs... yes >> > > checking whether the shell understands "+="... yes >> > > checking how to convert armv7l-unknown-linux-gnueabi file names to >> > armv7l-unknown-linux-gnueabi format... func_convert_file_noop >> > > checking how to convert armv7l-unknown-linux-gnueabi file names to >> > toolchain format... func_convert_file_noop >> > > checking for /usr/armv7a-unknown-linux-gnueabi/bin/ld option to >> > > reload >> > object files... -r >> > > checking for objdump... objdump >> > > checking how to recognize dependent libraries... pass_all >> > > checking for dlltool... no >> > > checking how to associate runtime and link libraries... printf %s\n >> > > checking for ar... ar >> > > checking for archiver @FILE support... @ >> > > checking for strip... strip >> > > checking for ranlib... ranlib >> > > checking command to parse /usr/bin/nm -B output from gcc object... ok >> > > checking for sysroot... no >> > > checking for mt... no >> > > checking if : is a manifest tool... no >> > > checking how to run the C preprocessor... gcc -E >> > > checking for ANSI C header files... yes >> > > checking for sys/types.h... yes >> > > checking for sys/stat.h... yes >> > > checking for stdlib.h... yes >> > > checking for string.h... yes >> > > checking for memory.h... yes >> > > checking for strings.h... yes >> > > checking for inttypes.h... yes >> > > checking for stdint.h... yes >> > > checking for unistd.h... yes >> > > checking for dlfcn.h... yes >> > > checking for objdir... .libs >> > > checking if gcc supports -fno-rtti -fno-exceptions... no >> > > checking for gcc option to produce PIC... -fPIC -DPIC >> > > checking if gcc PIC flag -fPIC -DPIC works... yes >> > > checking if gcc static flag -static works... yes >> > > checking if gcc supports -c -o file.o... yes >> > > checking if gcc supports -c -o file.o... (cached) yes >> > > checking whether the gcc linker >> > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... >> > yes >> > > checking whether -lc should be explicitly linked in... no >> > > checking dynamic linker characteristics... GNU/Linux ld.so >> > > checking how to hardcode library paths into programs... immediate >> > > checking whether stripping libraries is possible... yes >> > > checking if libtool supports shared libraries... yes >> > > checking whether to build shared libraries... yes >> > > checking whether to build static libraries... yes >> > > checking how to run the C++ preprocessor... g++ -E >> > > checking for ld used by g++... >> > > /usr/armv7a-unknown-linux-gnueabi/bin/ld >> > > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) is >> > > GNU >> > ld... yes >> > > checking whether the g++ linker >> > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... >> > yes >> > > checking for g++ option to produce PIC... -fPIC -DPIC >> > > checking if g++ PIC flag -fPIC -DPIC works... yes >> > > checking if g++ static flag -static works... yes >> > > checking if g++ supports -c -o file.o... yes >> > > checking if g++ supports -c -o file.o... (cached) yes >> > > checking whether the g++ linker >> > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared libraries... >> > yes >> > > checking dynamic linker characteristics... (cached) GNU/Linux ld.so >> > > checking how to hardcode library paths into programs... immediate >> > > checking for dlopen in -ldl... yes >> > > checking for pthread_create in -lpthread... yes >> > > checking for uuid_generate in -luuid... yes >> > > checking for inline... inline >> > > checking for stdlib.h... (cached) yes >> > > checking for GNU libc compatible malloc... yes >> > > checking for gettimeofday... yes >> > > checking for munmap... yes >> > > checking for socket... yes >> > > checking for strerror... yes >> > > checking for strtol... yes >> > > checking for sched_getcpu... yes >> > > checking for sysconf... yes >> > > checking for makeinfo... yes >> > > checking urcu-bp.h usability... yes >> > > checking urcu-bp.h presence... yes >> > > checking for urcu-bp.h... yes >> > > checking caa_likely()... yes >> > > checking for synchronize_rcu_bp in -lurcu-bp... yes >> > > checking for call_rcu_bp in -lurcu-bp... yes >> > > checking library format for the host system... configure: error: >> > > unable >> > to detect library format (unsupported architecture (armv7l)?) >> > >> > Does it help if you add a line: >> > >> > armv7l) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; >> > >> > near line 188 of configure.ac ? >> > >> > What we did in userspace RCU is to use "arm*". >> > >> > Thanks, >> > >> > Mathieu >> > >> > > >> > > >> > > _______________________________________________ >> > > lttng-dev mailing list >> > > lttng-dev at lists.lttng.org >> > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev >> > >> > -- >> > Mathieu Desnoyers >> > Operating System Efficiency R&D Consultant >> > EfficiOS Inc. >> > http://www.efficios.com >> > > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > From vannigenua at gmail.com Fri May 18 14:36:47 2012 From: vannigenua at gmail.com (Vanni Genua) Date: Fri, 18 May 2012 18:36:47 -0000 Subject: [lttng-dev] HOW TO DOWNLOAD LTTng 2.0 stable? In-Reply-To: <20120518164440.GB18739@Krystal> References: <4FB3EDC0.7080006@polymtl.ca> <4FB50A3E.7030508@polymtl.ca> <20120517143031.GA30839@Krystal> <20120518151850.GA17152@Krystal> <20120518164440.GB18739@Krystal> Message-ID: I tried to ./bootstrap but it didn't work. tomorrow I'll try to checkout master as you have written. then I'm going to tell you if it will work. Thanks. Vanni On 5/18/12, Mathieu Desnoyers wrote: > Hi Vanni, > > * Vanni Genua (vannigenua at gmail.com) wrote: >> I asked you about the HEAD download (mater and stable2.0), >> I found its size was about 180kB, whereas the 2.0.1 was over 500KB. >> I also wrote you that the HEAD (master?) missed the configure file, so >> it was not possible to run ./configure ) > > The lttng-ust README file states to run ./bootstrap before configure. > >> May you post me the exact link where the full HEAD is? > > git clone git://git.lttng.org/lttng-ust.git > cd lttng-ust > #then either: > git checkout master (for master branch) > > # or > git checkout stable-2.0 > > Side-note: the linking problem you are seeing might be caused by an > issue in lttng-ust Makefile.am regarding support for cross-compiling. > Unfortunately, I don't have a setup readily available, but if other > people could test cross-build and report issues, it might help us. > > Thanks! > > Mathieu > >> I'm using gcc 4.4.2 (I guess, because now I'm not at the office). >> Thanks. >> Vanni >> >> On 5/18/12, Mathieu Desnoyers wrote: >> > * Vanni Genua (vannigenua at gmail.com) wrote: >> >> I did it a minute ago, now the problems are the undefined references >> >> at >> >> the >> >> end of this logs: >> >> >> >> localhost lttng-ust-2.0.1 # ./configure --build=armv7a-unknown-linux- >> >> gnueabi >> > >> > This looks like a problem with your toolchain (gcc/ld/...), since AFAIK >> > Alexandre is able to cross-build for ARMv7 on Ubuntu. You should ask >> > your distribution vendor. >> > >> > Also, you seem to be still using lttng-ust 2.0.1 instead of "HEAD". >> > Which commit ID are you using ? >> > >> > Thanks, >> > >> > Mathieu >> > >> > >> > >> >> >> >> checking build system type... >> >> armv7a-unknown-linux-gnueabi >> >> >> >> checking host system type... >> >> armv7a-unknown-linux-gnueabi >> >> >> >> checking target system type... >> >> armv7a-unknown-linux-gnueabi >> >> >> >> checking how to convert armv7a-unknown-linux-gnueabi file names to >> >> armv7a-unknown-linux-gnueabi format... >> >> func_convert_file_noop >> >> checking how to convert armv7a-unknown-linux-gnueabi file names to >> >> toolchain format... >> >> func_convert_file_noop >> >> checking library format for the host system... >> >> elf32-littlearm >> >> >> >> configure: creating >> >> ./config.status >> >> >> >> config.status: creating >> >> Makefile >> >> >> >> config.status: creating >> >> doc/Makefile >> >> >> >> config.status: creating >> >> doc/examples/Makefile >> >> >> >> config.status: creating >> >> include/Makefile >> >> >> >> config.status: creating >> >> include/lttng/ust-version.h >> >> >> >> config.status: creating >> >> snprintf/Makefile >> >> >> >> config.status: creating >> >> libringbuffer/Makefile >> >> >> >> config.status: creating >> >> liblttng-ust-comm/Makefile >> >> >> >> config.status: creating >> >> liblttng-ust/Makefile >> >> >> >> config.status: creating >> >> liblttng-ust-ctl/Makefile >> >> >> >> config.status: creating >> >> liblttng-ust-fork/Makefile >> >> >> >> config.status: creating >> >> liblttng-ust-java/Makefile >> >> >> >> config.status: creating >> >> liblttng-ust-libc-wrapper/Makefile >> >> >> >> config.status: creating >> >> tools/Makefile >> >> >> >> config.status: creating >> >> tests/Makefile >> >> >> >> config.status: creating >> >> tests/hello/Makefile >> >> >> >> config.status: creating >> >> tests/hello-static-lib/Makefile >> >> >> >> config.status: creating >> >> tests/hello.cxx/Makefile >> >> >> >> config.status: creating >> >> tests/demo/Makefile >> >> >> >> config.status: creating >> >> tests/fork/Makefile >> >> >> >> config.status: creating >> >> tests/ust-basic-tracing/Makefile >> >> >> >> config.status: creating >> >> tests/ust-multi-test/Makefile >> >> >> >> config.status: creating >> >> lttng-ust.pc >> >> >> >> config.status: creating >> >> config.h >> >> >> >> config.status: config.h is >> >> unchanged >> >> >> >> config.status: creating >> >> include/lttng/ust-config.h >> >> >> >> config.status: include/lttng/ust-config.h is >> >> unchanged >> >> >> >> config.status: executing depfiles >> >> commands >> >> >> >> config.status: executing libtool >> >> commands >> >> >> >> >> >> >> >> Version name: >> >> Annedd'ale >> >> >> >> New type of beer, 100% from Quebec, flavored with sapin beaumier >> >> needles, >> >> with a touch of >> >> hops. >> >> >> >> >> >> LTTng-UST will be built with the following >> >> options: >> >> >> >> Library format: >> >> elf32-littlearm >> >> >> >> >> >> >> >> Java support (JNI): >> >> Disabled >> >> >> >> sdt.h integration: >> >> Disabled >> >> >> >> >> >> >> >> Type 'make' to >> >> compile. >> >> >> >> localhost lttng-ust-2.0.1 # >> >> make >> >> >> >> make >> >> all-recursive >> >> >> >> make[1]: Entering directory >> >> `/usr/src/lttng-ust-2.0.1' >> >> >> >> Making all in >> >> . >> >> >> >> make[2]: Entering directory >> >> `/usr/src/lttng-ust-2.0.1' >> >> >> >> make[2]: Leaving directory >> >> `/usr/src/lttng-ust-2.0.1' >> >> >> >> Making all in >> >> include >> >> >> >> make[2]: Entering directory >> >> `/usr/src/lttng-ust-2.0.1/include' >> >> >> >> make[2]: Nothing to be done for >> >> `all'. >> >> >> >> make[2]: Leaving directory >> >> `/usr/src/lttng-ust-2.0.1/include' >> >> >> >> Making all in >> >> snprintf >> >> >> >> make[2]: Entering directory >> >> `/usr/src/lttng-ust-2.0.1/snprintf' >> >> >> >> make[2]: Nothing to be done for >> >> `all'. >> >> >> >> make[2]: Leaving directory >> >> `/usr/src/lttng-ust-2.0.1/snprintf' >> >> >> >> Making all in >> >> libringbuffer >> >> >> >> make[2]: Entering directory >> >> `/usr/src/lttng-ust-2.0.1/libringbuffer' >> >> >> >> CC >> >> libringbuffer_la-ring_buffer_backend.lo >> >> >> >> CC >> >> libringbuffer_la-ring_buffer_frontend.lo >> >> >> >> CCLD libringbuffer.la >> >> >> >> make[2]: Leaving directory >> >> `/usr/src/lttng-ust-2.0.1/libringbuffer' >> >> >> >> Making all in >> >> liblttng-ust-comm >> >> >> >> make[2]: Entering directory >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' >> >> >> >> make[2]: Nothing to be done for >> >> `all'. >> >> >> >> make[2]: Leaving directory >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-comm' >> >> >> >> Making all in >> >> liblttng-ust >> >> >> >> make[2]: Entering directory >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust' >> >> >> >> CC >> >> liblttng_ust_tracepoint_la-tracepoint.lo >> >> >> >> CCLD liblttng-ust-tracepoint.la >> >> >> >> CC >> >> lttng-ust-comm.lo >> >> >> >> CC >> >> lttng-ust-abi.lo >> >> >> >> CC >> >> ltt-probes.lo >> >> >> >> CC >> >> lttng-probe-ust.lo >> >> >> >> CC >> >> lttng-context-vtid.lo >> >> >> >> CC >> >> lttng-context-vpid.lo >> >> >> >> CC >> >> lttng-context-pthread-id.lo >> >> >> >> CC >> >> lttng-context-procname.lo >> >> >> >> CC >> >> ltt-context.lo >> >> >> >> CC >> >> ltt-events.lo >> >> >> >> CCLD liblttng-ust-runtime.la >> >> >> >> CC >> >> ust-core.lo >> >> >> >> CC >> >> ltt-ring-buffer-client-discard.lo >> >> >> >> CC >> >> ltt-ring-buffer-client-overwrite.lo >> >> >> >> CC >> >> ltt-ring-buffer-metadata-client.lo >> >> >> >> CCLD liblttng-ust-support.la >> >> >> >> CCLD liblttng-ust.la >> >> >> >> /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/../../../../armv7a-unknown-linux-gnueabi/bin/ld: >> >> warning: creating a DT_TEXTREL in object. >> >> copying selected object files to avoid basename >> >> conflicts... >> >> >> >> make[2]: Leaving directory >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust' >> >> >> >> Making all in >> >> liblttng-ust-ctl >> >> >> >> make[2]: Entering directory >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' >> >> >> >> CC >> >> ustctl.lo >> >> >> >> CCLD liblttng-ust-ctl.la >> >> >> >> /usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.3/../../../../armv7a-unknown-linux-gnueabi/bin/ld: >> >> warning: creating a DT_TEXTREL in object. >> >> make[2]: Leaving directory >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-ctl' >> >> >> >> Making all in >> >> liblttng-ust-fork >> >> >> >> make[2]: Entering directory >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' >> >> >> >> CCLD liblttng-ust-fork.la >> >> >> >> make[2]: Leaving directory >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-fork' >> >> >> >> Making all in >> >> liblttng-ust-libc-wrapper >> >> >> >> make[2]: Entering directory >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' >> >> >> >> CC >> >> lttng-ust-malloc.lo >> >> >> >> CCLD liblttng-ust-libc-wrapper.la >> >> >> >> make[2]: Leaving directory >> >> `/usr/src/lttng-ust-2.0.1/liblttng-ust-libc-wrapper' >> >> >> >> Making all in >> >> tools >> >> >> >> make[2]: Entering directory >> >> `/usr/src/lttng-ust-2.0.1/tools' >> >> >> >> make[2]: Nothing to be done for >> >> `all'. >> >> >> >> make[2]: Leaving directory >> >> `/usr/src/lttng-ust-2.0.1/tools' >> >> >> >> Making all in >> >> tests >> >> >> >> make[2]: Entering directory >> >> `/usr/src/lttng-ust-2.0.1/tests' >> >> >> >> Making all in >> >> . >> >> >> >> make[3]: Entering directory >> >> `/usr/src/lttng-ust-2.0.1/tests' >> >> >> >> make[3]: Nothing to be done for >> >> `all-am'. >> >> >> >> make[3]: Leaving directory >> >> `/usr/src/lttng-ust-2.0.1/tests' >> >> >> >> Making all in >> >> hello >> >> >> >> make[3]: Entering directory >> >> `/usr/src/lttng-ust-2.0.1/tests/hello' >> >> >> >> CC >> >> tp.o >> >> >> >> CCLD >> >> hello >> >> >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to >> >> `__num_possible_cpus' >> >> >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to >> >> `shm_object_table_create' >> >> >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to >> >> `shm_object_table_append_shadow' >> >> >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to >> >> `shm_object_table_append' >> >> >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to >> >> `zalloc_shm' >> >> >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to >> >> `_get_num_possible_cpus' >> >> >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to >> >> `align_shm' >> >> >> >> ../../liblttng-ust/.libs/liblttng-ust.so: undefined reference to >> >> `shm_object_table_destroy' >> >> >> >> collect2: ld returned 1 exit >> >> status >> >> >> >> make[3]: *** [hello] Error >> >> 1 >> >> >> >> make[3]: Leaving directory >> >> `/usr/src/lttng-ust-2.0.1/tests/hello' >> >> >> >> make[2]: *** [all-recursive] Error >> >> 1 >> >> >> >> make[2]: Leaving directory >> >> `/usr/src/lttng-ust-2.0.1/tests' >> >> >> >> make[1]: *** [all-recursive] Error >> >> 1 >> >> >> >> make[1]: Leaving directory >> >> `/usr/src/lttng-ust-2.0.1' >> >> >> >> make: *** [all] Error >> >> 2 >> >> >> >> localhost lttng-ust-2.0.1 # >> >> >> >> >> >> On Thu, May 17, 2012 at 2:30 PM, Mathieu Desnoyers < >> >> mathieu.desnoyers at efficios.com> wrote: >> >> >> >> > * Alexandre Montplaisir (alexandre.montplaisir at polymtl.ca) wrote: >> >> > > This is an interesting problem, I'll forward it to the mailing >> >> > > list. >> >> > > >> >> > > >> >> > > On 12-05-17 10:02 AM, Vanni Genua wrote: >> >> > > > Also why I get this error? >> >> > > > see the attached log file. >> >> > > > Best regards. >> >> > > > V.G. >> >> > > > >> >> > > > >> >> > > >> >> > > localhost lttng-ust-2.0.1 # ./configure >> >> > > checking build system type... armv7l-unknown-linux-gnueabi >> >> > > checking host system type... armv7l-unknown-linux-gnueabi >> >> > > checking target system type... armv7l-unknown-linux-gnueabi >> >> > > checking for a BSD-compatible install... /usr/bin/install -c >> >> > > checking whether build environment is sane... yes >> >> > > checking for a thread-safe mkdir -p... /bin/mkdir -p >> >> > > checking for gawk... gawk >> >> > > checking whether make sets $(MAKE)... yes >> >> > > checking whether make supports nested variables... yes >> >> > > checking for a sed that does not truncate output... /bin/sed >> >> > > checking for gcc... gcc >> >> > > checking whether the C compiler works... yes >> >> > > checking for C compiler default output file name... a.out >> >> > > checking for suffix of executables... >> >> > > checking whether we are cross compiling... no >> >> > > checking for suffix of object files... o >> >> > > checking whether we are using the GNU C compiler... yes >> >> > > checking whether gcc accepts -g... yes >> >> > > checking for gcc option to accept ISO C89... none needed >> >> > > checking for style of include used by make... GNU >> >> > > checking dependency style of gcc... gcc3 >> >> > > checking for g++... g++ >> >> > > checking whether we are using the GNU C++ compiler... yes >> >> > > checking whether g++ accepts -g... yes >> >> > > checking dependency style of g++... gcc3 >> >> > > checking whether make sets $(MAKE)... (cached) yes >> >> > > checking how to print strings... printf >> >> > > checking for a sed that does not truncate output... (cached) >> >> > > /bin/sed >> >> > > checking for grep that handles long lines and -e... /bin/grep >> >> > > checking for egrep... /bin/grep -E >> >> > > checking for fgrep... /bin/grep -F >> >> > > checking for ld used by gcc... >> >> > > /usr/armv7a-unknown-linux-gnueabi/bin/ld >> >> > > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) >> >> > > is >> >> > > GNU >> >> > ld... yes >> >> > > checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm >> >> > > -B >> >> > > checking the name lister (/usr/bin/nm -B) interface... BSD nm >> >> > > checking whether ln -s works... yes >> >> > > checking the maximum length of command line arguments... 1572864 >> >> > > checking whether the shell understands some XSI constructs... yes >> >> > > checking whether the shell understands "+="... yes >> >> > > checking how to convert armv7l-unknown-linux-gnueabi file names to >> >> > armv7l-unknown-linux-gnueabi format... func_convert_file_noop >> >> > > checking how to convert armv7l-unknown-linux-gnueabi file names to >> >> > toolchain format... func_convert_file_noop >> >> > > checking for /usr/armv7a-unknown-linux-gnueabi/bin/ld option to >> >> > > reload >> >> > object files... -r >> >> > > checking for objdump... objdump >> >> > > checking how to recognize dependent libraries... pass_all >> >> > > checking for dlltool... no >> >> > > checking how to associate runtime and link libraries... printf >> >> > > %s\n >> >> > > checking for ar... ar >> >> > > checking for archiver @FILE support... @ >> >> > > checking for strip... strip >> >> > > checking for ranlib... ranlib >> >> > > checking command to parse /usr/bin/nm -B output from gcc object... >> >> > > ok >> >> > > checking for sysroot... no >> >> > > checking for mt... no >> >> > > checking if : is a manifest tool... no >> >> > > checking how to run the C preprocessor... gcc -E >> >> > > checking for ANSI C header files... yes >> >> > > checking for sys/types.h... yes >> >> > > checking for sys/stat.h... yes >> >> > > checking for stdlib.h... yes >> >> > > checking for string.h... yes >> >> > > checking for memory.h... yes >> >> > > checking for strings.h... yes >> >> > > checking for inttypes.h... yes >> >> > > checking for stdint.h... yes >> >> > > checking for unistd.h... yes >> >> > > checking for dlfcn.h... yes >> >> > > checking for objdir... .libs >> >> > > checking if gcc supports -fno-rtti -fno-exceptions... no >> >> > > checking for gcc option to produce PIC... -fPIC -DPIC >> >> > > checking if gcc PIC flag -fPIC -DPIC works... yes >> >> > > checking if gcc static flag -static works... yes >> >> > > checking if gcc supports -c -o file.o... yes >> >> > > checking if gcc supports -c -o file.o... (cached) yes >> >> > > checking whether the gcc linker >> >> > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared >> >> > libraries... >> >> > yes >> >> > > checking whether -lc should be explicitly linked in... no >> >> > > checking dynamic linker characteristics... GNU/Linux ld.so >> >> > > checking how to hardcode library paths into programs... immediate >> >> > > checking whether stripping libraries is possible... yes >> >> > > checking if libtool supports shared libraries... yes >> >> > > checking whether to build shared libraries... yes >> >> > > checking whether to build static libraries... yes >> >> > > checking how to run the C++ preprocessor... g++ -E >> >> > > checking for ld used by g++... >> >> > > /usr/armv7a-unknown-linux-gnueabi/bin/ld >> >> > > checking if the linker (/usr/armv7a-unknown-linux-gnueabi/bin/ld) >> >> > > is >> >> > > GNU >> >> > ld... yes >> >> > > checking whether the g++ linker >> >> > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared >> >> > libraries... >> >> > yes >> >> > > checking for g++ option to produce PIC... -fPIC -DPIC >> >> > > checking if g++ PIC flag -fPIC -DPIC works... yes >> >> > > checking if g++ static flag -static works... yes >> >> > > checking if g++ supports -c -o file.o... yes >> >> > > checking if g++ supports -c -o file.o... (cached) yes >> >> > > checking whether the g++ linker >> >> > (/usr/armv7a-unknown-linux-gnueabi/bin/ld) supports shared >> >> > libraries... >> >> > yes >> >> > > checking dynamic linker characteristics... (cached) GNU/Linux >> >> > > ld.so >> >> > > checking how to hardcode library paths into programs... immediate >> >> > > checking for dlopen in -ldl... yes >> >> > > checking for pthread_create in -lpthread... yes >> >> > > checking for uuid_generate in -luuid... yes >> >> > > checking for inline... inline >> >> > > checking for stdlib.h... (cached) yes >> >> > > checking for GNU libc compatible malloc... yes >> >> > > checking for gettimeofday... yes >> >> > > checking for munmap... yes >> >> > > checking for socket... yes >> >> > > checking for strerror... yes >> >> > > checking for strtol... yes >> >> > > checking for sched_getcpu... yes >> >> > > checking for sysconf... yes >> >> > > checking for makeinfo... yes >> >> > > checking urcu-bp.h usability... yes >> >> > > checking urcu-bp.h presence... yes >> >> > > checking for urcu-bp.h... yes >> >> > > checking caa_likely()... yes >> >> > > checking for synchronize_rcu_bp in -lurcu-bp... yes >> >> > > checking for call_rcu_bp in -lurcu-bp... yes >> >> > > checking library format for the host system... configure: error: >> >> > > unable >> >> > to detect library format (unsupported architecture (armv7l)?) >> >> > >> >> > Does it help if you add a line: >> >> > >> >> > armv7l) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; >> >> > >> >> > near line 188 of configure.ac ? >> >> > >> >> > What we did in userspace RCU is to use "arm*". >> >> > >> >> > Thanks, >> >> > >> >> > Mathieu >> >> > >> >> > > >> >> > > >> >> > > _______________________________________________ >> >> > > lttng-dev mailing list >> >> > > lttng-dev at lists.lttng.org >> >> > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev >> >> > >> >> > -- >> >> > Mathieu Desnoyers >> >> > Operating System Efficiency R&D Consultant >> >> > EfficiOS Inc. >> >> > http://www.efficios.com >> >> > >> > >> > -- >> > Mathieu Desnoyers >> > Operating System Efficiency R&D Consultant >> > EfficiOS Inc. >> > http://www.efficios.com >> > > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > From vannigenua at gmail.com Mon May 21 09:55:17 2012 From: vannigenua at gmail.com (Vanni Genua) Date: Mon, 21 May 2012 13:55:17 +0000 Subject: [lttng-dev] BABELTRACE Message-ID: Hi there, so once I have correctly installed LTTng-modules, LTTng-ust and LTTng-tools, I can use LTTng but not LTTng view. In order to use #lttng view command I have to install Babeltrace, but it seems still to be a rc version. As a matter of fact I downloaded it from http://lttng.org/downloadand, according to README file, I launched #./bootsrap but this file is not in the directory: it doesn't exist! I'm stuck here now, any idea? Vanni -------------- next part -------------- An HTML attachment was scrubbed... URL: From vannigenua at gmail.com Mon May 21 10:18:13 2012 From: vannigenua at gmail.com (Vanni Genua) Date: Mon, 21 May 2012 14:18:13 +0000 Subject: [lttng-dev] BABELTRACE In-Reply-To: References: Message-ID: Soved with Babeltrace Master. V.G. On Mon, May 21, 2012 at 1:55 PM, Vanni Genua wrote: > Hi there, > so once I have correctly installed LTTng-modules, LTTng-ust and > LTTng-tools, I can use LTTng but not LTTng view. In order to use #lttng > view command I have to install Babeltrace, but it seems still to be a rc > version. As a matter of fact I downloaded it from > http://lttng.org/download and, according to README file, I launched > #./bootsrap but this file is not in the directory: it doesn't exist! > I'm stuck here now, any idea? > Vanni > -------------- next part -------------- An HTML attachment was scrubbed... URL: From vannigenua at gmail.com Mon May 21 10:26:09 2012 From: vannigenua at gmail.com (Vanni Genua) Date: Mon, 21 May 2012 14:26:09 +0000 Subject: [lttng-dev] BABELTRACE In-Reply-To: References: Message-ID: I did #./bootstrap and it was ok Then I did #./configure and I got this error: checking for bison... bison -y checking for flex... flex checking lex output file root... lex.yy checking lex library... -lfl checking whether yytext is a pointer... yes ./configure: line 11626: syntax error near unexpected token `0.16' ./configure: line 11626: ` PKG_PROG_PKG_CONFIG(0.16)' How to solve this bug? Thanks V.G. On Mon, May 21, 2012 at 2:18 PM, Vanni Genua wrote: > Soved with Babeltrace Master. > V.G. > > > On Mon, May 21, 2012 at 1:55 PM, Vanni Genua wrote: > >> Hi there, >> so once I have correctly installed LTTng-modules, LTTng-ust and >> LTTng-tools, I can use LTTng but not LTTng view. In order to use #lttng >> view command I have to install Babeltrace, but it seems still to be a rc >> version. As a matter of fact I downloaded it from >> http://lttng.org/download and, according to README file, I launched >> #./bootsrap but this file is not in the directory: it doesn't exist! >> I'm stuck here now, any idea? >> Vanni >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From toojays at toojays.net Tue May 22 03:35:19 2012 From: toojays at toojays.net (John Steele Scott) Date: Tue, 22 May 2012 17:05:19 +0930 Subject: [lttng-dev] UST "Tracepoint signature mismatch" with C99 bool. Message-ID: <8762bo7jns.fsf@quantum.com> I'm just getting started wiring my up to lttng-ust, and unfortunately ran into an issue with the first probe I tried, which used a C99 bool argument. The problem can be seen by patching the demo test from lttng-ust as follows: --- a/tests/demo/ust_tests_demo3.h +++ b/tests/demo/ust_tests_demo3.h @@ -22,12 +22,14 @@ extern "C" { * all copies or substantial portions of the Software. */ +#include + #include TRACEPOINT_EVENT(ust_tests_demo3, done, - TP_ARGS(int, value), + TP_ARGS(bool, value), TP_FIELDS( - ctf_integer(int, value, value) + ctf_integer(bool, value, value) ) ) Then when the demo is run with LTTNG_UST_DEBUG=1, a warning is shown, like: liblttng_ust_tracepoint[3315/3315]: Warning: Tracepoint signature mismatch, not enabling one or more tracepoints. Ensure that the tracepoint probes prototypes match the application. (in set_tracepoint() at tracepoint.c:310) liblttng_ust_tracepoint[3315/3315]: Warning: Tracepoint "ust_tests_demo3:done" signatures: call: "_Bool, value" vs probe: "bool, value". (in set_tracepoint() at tracepoint.c:312) It seems that TP_ARGS does not perform preprocessor expansion on the "bool" type spec, while something underneath TP_FIELDS does. And since (at least on this Centos 6.2 box) stdbool.h uses a #define rather than a typedef to make bool equivalent to _Bool, liblttng detects a mismatch. So in my tracepoint specifications, I need to remember to use the less attractive _Bool instead of bool. Perhaps it's worth having a special case for this where the trace/probe signatures are compared? On the other hand, I guess nobody complained until now? :) cheers, John From umq at ueo.co.jp Sun May 27 20:39:52 2012 From: umq at ueo.co.jp (Hirohisa Yamaguchi) Date: Mon, 28 May 2012 09:39:52 +0900 Subject: [lttng-dev] userspace-rcu test scripts patches (was: ports/168339: [patch] sysutils/userspace-rcu update to 0.7.2 In-Reply-To: <20120527184255.GA14719@Krystal> References: <86mx4tn165.wl%umq@ueo.co.jp> <20120527184255.GA14719@Krystal> Message-ID: <867gvxgmuf.wl%umq@ueo.co.jp> Hi, Mathieu Thanks for your comments. At Sun, 27 May 2012 14:42:55 -0400, Mathieu Desnoyers wrote: > > The changes for FreeBSD in test scripts are mainly consists of > > following: > This brings an interesting point: all the tests scripts start with > "#!/bin/sh", but use bash-isms. I guess the first question would be: > should be simply choose make test execution depend on bash (and push > #!/bin/bash prefix), since this is only needed for tests provided with > the package sources, and not needed for deployment of the library on > systems ? Of course, dependency on bash for in-source-tree tests would > have to be documented in the README. I think there're two different purposes of tests: 1. for developers to ensure the implementations are correct 2. for users to see his/her environment is safe to use the feature -- built without an error does not mean it runs okay I think bashisms do not suit for latter purpose. > > 1. time(1) in FreeBSD does not have long argument name: > > change --append to -a and --output to -o > I will pull this change. See commit > 383dac33797fd0858d6858527324a6a15aa06c09 thanks > > 2. ash (i.e. /bin/sh in FreeBSD) does not have += operator: > > replace a+="b" to a="${a}b" > The question on whether we specifically go for bash for in-source-tree > test scripts needs to be cleared before I proceed to this change. If the test scripts are not written for all users, there's no problem when its shown in a document or somewhere. > > 3. BSD flavoured system have jot(1) instead of seq(1). > > manual of jot(1) can be read at http://man.freebsd.org/jot/1 > For some reason, "seq" is installed on my FreeBSD 9.0 system, but not on > my 8.2. We could implement a seq-wrapper.sh in tests/ that can be > sourced by test shell scripts which would use the right seq > implementation underneath (and change the parameters accordingly). > > 4. ash does not have PIPESTATUS: > Should decide for bash or sh first. I agree, as I've mentioned above. > > 5. NUM_CPUS might be determined at runtime: > So I would recommend making this a > parameter, and autodetect only if no parameter is provided. The > autodetect would indeed have to be OS-specific. We could implement a > get_nr_cpu.sh script within tests/ that detects the number of CPUs on > the current OS. That sounds good. At Sun, 27 May 2012 15:44:12 -0400, Mathieu Desnoyers wrote: > > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > [...] > > > # btw, test_perthreadlock under FreeBSD 10-CURRENT always fails > > > # (releases prior to 9.0 are okay). > > -> I guess you mean "releases up to, and including 9.0, are OK". Ah, yes. > > > # The change in FreeBSD libthr might cause the error. > > > # I haven't looked into it yet. > > What are the details of your test invokation ? (how many reader/writer > > threads, how many cores do you have ? Is this on hardware or virtualized ?) > Actually, the most interesting thing to know here would be your > architecture. Moreover, as a hint, the fact that the problem seems to > only arise in the perthreadlock test, which generates a lot of > contention when the writer takes all the reader locks, I would guess > that the bug would sit somewhere in the contention handling code, which > could be either at the user-space library or kernel-level side. I've found the error first on a build farm called redports.org, which is opened for FreeBSD port maintainers to run build and tests. I'm not sure the architecture of the build farm, but some test shows it runs on Phenom II X6 1075T. There's no way to know it is on hardware or virtualized. # The test on the build farm ran with NUM_CPUS=6, I don't have logs # currently since they're expired. Any parameters in runall.sh lead to error. My box that reproduce the error is a VMware guest on my MacBook. # Intel(R) Core(TM)2 Duo CPU T8300 @ 2.40GHz It is a dual-core CPU, and I ran the tests with NUM_CPUS=2. I attach a backtrace of a corefile when I ran: test_perthreadlock 1 1 10 -d 0 -b 32768 I only have stripped libthr in my environment, I haven't managed to build one. Regards, -- Hirohisa Yamaguchi umq at ueo.co.jp -------------- next part -------------- GNU gdb 6.1.1 [FreeBSD] Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "amd64-marcel-freebsd"... Core was generated by `test_perthreadlock'. Program terminated with signal 10, Bus error. Reading symbols from /lib/libthr.so.3...done. Loaded symbols for /lib/libthr.so.3 Reading symbols from /lib/libc.so.7...done. Loaded symbols for /lib/libc.so.7 Reading symbols from /libexec/ld-elf.so.1...done. Loaded symbols for /libexec/ld-elf.so.1 #0 0x000000080082d09b in pthread_mutex_lock () from /lib/libthr.so.3 (gdb) info thread 3 process 100144 0x0000000800b3207c in nanosleep () from /lib/libc.so.7 2 process 101026 0x0000000800826b90 in pthread_create () from /lib/libthr.so.3 * 1 process 101025 0x000000080082d09b in pthread_mutex_lock () from /lib/libthr.so.3 (gdb) thread apply all bt full Thread 3 (process 100144): #0 0x0000000800b3207c in nanosleep () from /lib/libc.so.7 No symbol table info available. #1 0x0000000800a952e8 in sleep () from /lib/libc.so.7 No symbol table info available. #2 0x0000000800828e18 in sleep () from /lib/libthr.so.3 No symbol table info available. #3 0x00000000004011a8 in main (argc=1, argv=0x7fffffffda90) at test_perthreadlock.c:397 err = Thread 2 (process 101026): #0 0x0000000800826b90 in pthread_create () from /lib/libthr.so.3 No symbol table info available. #1 0x0000000000000000 in ?? () No symbol table info available. Thread 1 (process 101025): #0 0x000000080082d09b in pthread_mutex_lock () from /lib/libthr.so.3 No symbol table info available. #1 0x00000000004016a3 in thr_reader (data=) at test_perthreadlock.c:211 tidx = 0 __func__ = "thr_reader" #2 0x0000000800826cdd in pthread_create () from /lib/libthr.so.3 No symbol table info available. #3 0x0000000000000000 in ?? () No symbol table info available. (gdb) q From umq at ueo.co.jp Mon May 28 19:54:06 2012 From: umq at ueo.co.jp (Hirohisa Yamaguchi) Date: Tue, 29 May 2012 08:54:06 +0900 Subject: [lttng-dev] userspace-rcu test scripts patches (was: ports/168339: [patch] sysutils/userspace-rcu update to 0.7.2 In-Reply-To: <20120528150036.GA17067@Krystal> References: <86mx4tn165.wl%umq@ueo.co.jp> <20120527184255.GA14719@Krystal> <867gvxgmuf.wl%umq@ueo.co.jp> <20120528150036.GA17067@Krystal> Message-ID: <86wr3v7tgh.wl%umq@ueo.co.jp> Hi, At Mon, 28 May 2012 11:00:36 -0400, Mathieu Desnoyers wrote: > > I think there're two different purposes of tests: > > 1. for developers to ensure the implementations are correct > > 2. for users to see his/her environment is safe to use the feature > > -- built without an error does not mean it runs okay > > I think bashisms do not suit for latter purpose. > I agree that we should not depend on "bash" for any script installed > into the system. > However, the "tests/" subdirectory is not currently installed on the > user system. It's only used for in-tree testing, and "make check" > execution. > There might come a point where we want to deploy some tests into the > system so the library users can run them, I don't know. Maybe not yet > though, as we would need to clean them up first. I meant `users' to be a person who wants to port the product to his/her environment or maintain package of the product. I doubt that end users such as one who brings binaries from the OS's package repository would run the test scripts when they're installed into the system. > So at this stage, I would be fine with specifying in the README that > running tests depends on bash. I understand. > However, if we can provide a wrapper for > all the commands we need, which would be sourced by all scripts in the > tests/ directory, which implements all wrappers into per-wrapper files, > sourced by one toplevel wrapper file, I would be open to that too, given > that it would make deployment of tests simpler for systems lacking bash > support. e.g. > tests/wrapper/all.sh > . wrapper/seq.sh > ..... > > tests/wrapper/seq.sh > tests/wrapper/.... > each test script: > > #!/bin/sh > . wrapper/all.sh > ..... > > > > 5. NUM_CPUS might be determined at runtime: > > > So I would recommend making this a > > > parameter, and autodetect only if no parameter is provided. The > > > autodetect would indeed have to be OS-specific. We could implement a > > > get_nr_cpu.sh script within tests/ that detects the number of CPUs on > > > the current OS. > > > > That sounds good. > > Can you prepare a patch for this ? I'll try next weekend. > > At Sun, 27 May 2012 15:44:12 -0400, > > Mathieu Desnoyers wrote: > > > > > # btw, test_perthreadlock under FreeBSD 10-CURRENT always fails > > > > > # (releases prior to 9.0 are okay). [...] > OK, so it seems to be reproducible on both AMD and Intel, that's good > news. I observed the error on both 32bits and 64bits, to add. > You might want to compile userspace rcu with: > > make CFLAGS=-g > > to get debug symbols for the library. It will provide a more helpful > backtrace. We should consider that the issue can come from a race > between pthread_create and pthread_mutex_lock too. Here's another log file. https://gist.github.com/2821618 I've built urcu with -g flag but, there still seems to be some problem getting backtrace. Regards, -- Hirohisa Yamaguchi umq at ueo.co.jp