Re: [Xenomai-core] [PATCH 10/12] Report current shadow thread mode to user space
Gilles Chanteperdrix wrote: > Jan Kiszka wrote: > > Ok. I still liked the solution of using a piece of shared heap. This was > more general and would have allowed us to use this piece of shared heap > for future purposes. Shared heaps do not allow for the __thread optimization. Jan signature.asc Description: OpenPGP digital signature ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] rt_task_info.status encoding
Gilles Chanteperdrix wrote: > Jan Kiszka wrote: >> Gilles Chanteperdrix wrote: >>> Jan Kiszka wrote: I start to believe we are arguing with different (miss-)use case in mind. Mine is definitely not about "helping" the user to switch the thread mode even more actively. It is about validating application states, it is about thread state reflection without any other actions than reporting errors. T_PRIMARY is part of the picture for the dual kernel Xenomai version, and it will remain such as long as there are two kernels. Even better, it is a very helpful application debugging tool when it comes to runtime validation of their real-time behavior. Again, it is NOT about promoting more use of rt_task_set_mode! >>> SIGXCPU may be used validate current thread mode, and it has the >>> advantage that it can not be misused. >> You are not always able to install or switch signal handlers when >> crossing application module boundaries. And you can't use it to validate >> the opposite (RT thread calls into lengthy, not RT-context suited >> library function). > > For me, one problem of SIGXCPU is when one non RT thread acquires a > mutex shared with a RT thread, and then calls some functions which cause > it to switch to secondary mode. But we could conceivably modify the > nucleus to detect this kind of situation. > > Another problem is that malloc, free, new and delete do not necessarily > cause a switch to secondary mode. But this also could conceivably be > solved by wrapping/overriding these calls and call the SIGXCPU handler > in the wrapper. Yes, and add getimeofday to this list. Even worse: When it triggers, the backtrace stops in the vsyscall page, not allowing to identify the caller. > > Other than that, I do not see what you mean. SIGXCPU becomes useless if you are unable to install a signal handler, e.g. from within an invoked library. rt_task_inquire is then an alternative mechanism to add debug assertions. Jan signature.asc Description: OpenPGP digital signature ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 08/12] Use fast xnsynch with native skin
Gilles Chanteperdrix wrote: > Jan Kiszka wrote: > > Same remark for the #ifdefs. Yes, but most cases (maybe except for owner checking) are unavoidable due to heavy differences. I hope that we may have only FASTXNSYCH archs one day. > I also do not understand your modification > of rt_cond_wait_inner, this code is very tense; posix and native had the > same bug in this area at different times, so this change should probably > be made separately. Which modification precisely (damn, I need to find out what makes quilt cause this attachment confusion)? Note that lockcnt tracking changed with this patch: the lock owner himself is in charge of maintaining it, not some thread handing the lock over. That said, I would happily analyse the case that broke before. I will also check if I can break out the lockcnt maintenance change, but I think to recall that it was coupled to the fast path changes. Jan signature.asc Description: OpenPGP digital signature ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] application porting to Comedi4RTDM
Hi, Sorry for answering so late (not at home, no access to my private mails, not even able to answer your mail properly). Even if the Comedi API has been slightly modified, the Comedi principles remain the same. Consequently, I think you will be able to port your application to Comedi4RTDM. Which kernel driver are you using for your application? The first step would be the porting of the driver on Comedi4RTDM. I am very interested on porting legacy Comedi drivers to the new framework; unfortunately, I have no hardware to validate the new drivers... Concerning the user application, maybe the best way to get familiar with the changes in the user API would be thanks to the doxygen documentation. This documentation is available in the subversion trunk but you will have to generate it yourself. Regards. Alexis. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 09/12] Optionally replace pthread_getspecific with TLS variables
Gilles Chanteperdrix wrote: > Jan Kiszka wrote: > > The real downside here is a lot of #ifdef clutter. What about the idea > of defining an API to abstract the differences between > pthread_get/setspecific and __thread and have #ifdef only in one header ? Sometimes you only store a value that way, sometimes you also have to provide the object that is stored. Then its initialisation is fairly specific. Everything can be abstracted, but I'm not that optimistic that the result will be better readable, just look at the patched users. Or what abstractions do you have in mind? Jan signature.asc Description: OpenPGP digital signature ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] rt_task_info.status encoding
Jan Kiszka wrote: > Gilles Chanteperdrix wrote: >> Jan Kiszka wrote: >>> I start to believe we are arguing with different (miss-)use case in >>> mind. Mine is definitely not about "helping" the user to switch the >>> thread mode even more actively. It is about validating application >>> states, it is about thread state reflection without any other actions >>> than reporting errors. T_PRIMARY is part of the picture for the dual >>> kernel Xenomai version, and it will remain such as long as there are two >>> kernels. Even better, it is a very helpful application debugging tool >>> when it comes to runtime validation of their real-time behavior. Again, >>> it is NOT about promoting more use of rt_task_set_mode! >> SIGXCPU may be used validate current thread mode, and it has the >> advantage that it can not be misused. > > You are not always able to install or switch signal handlers when > crossing application module boundaries. And you can't use it to validate > the opposite (RT thread calls into lengthy, not RT-context suited > library function). For me, one problem of SIGXCPU is when one non RT thread acquires a mutex shared with a RT thread, and then calls some functions which cause it to switch to secondary mode. But we could conceivably modify the nucleus to detect this kind of situation. Another problem is that malloc, free, new and delete do not necessarily cause a switch to secondary mode. But this also could conceivably be solved by wrapping/overriding these calls and call the SIGXCPU handler in the wrapper. Other than that, I do not see what you mean. -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] rt_task_info.status encoding
Gilles Chanteperdrix wrote: > Jan Kiszka wrote: >> I start to believe we are arguing with different (miss-)use case in >> mind. Mine is definitely not about "helping" the user to switch the >> thread mode even more actively. It is about validating application >> states, it is about thread state reflection without any other actions >> than reporting errors. T_PRIMARY is part of the picture for the dual >> kernel Xenomai version, and it will remain such as long as there are two >> kernels. Even better, it is a very helpful application debugging tool >> when it comes to runtime validation of their real-time behavior. Again, >> it is NOT about promoting more use of rt_task_set_mode! > > SIGXCPU may be used validate current thread mode, and it has the > advantage that it can not be misused. You are not always able to install or switch signal handlers when crossing application module boundaries. And you can't use it to validate the opposite (RT thread calls into lengthy, not RT-context suited library function). Jan ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 12/12] Enable SMP support for user libs by default
Gilles Chanteperdrix wrote: > Jan Kiszka wrote: > > I do not like this patch. This sould be solved using the existing > features system. I do not want SMP to be enabled by default. On x86, SMP is already the default case, other archs will follow soon. I'm also fine with keeping those arch at default off which support SMP, but use it only rarely in practice yet. But at least for x86, staying with UP as default will quickly become annoying. That said, I have no problem with additionally enforcing the right configuration via the feature system. Will add that. Jan ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 06/12] Lockless fast path for xnsynch_acquire/release
Jan Kiszka wrote: > Gilles Chanteperdrix wrote: >> Jan Kiszka wrote: >>> Gilles Chanteperdrix wrote: Jan Kiszka wrote: Ok. Though I do not see the point of the FASTSEM/FASTSYNCH rename. FASTSEM is short, and we are not much interested in getting anything else than semaphores faster. >>> We aren't optimizing semaphores (at least not yet), we are optimizing >>> mutexes only. And if we ever optimize also semaphores, FASTSYNCH will >>> luckily still fit. :) >> The name was chosen because we plan to optimize semaphores as well, and >> because mutexes are simply a special kind of semaphores, so, by saying >> FASTSEM, we cover semaphores as well as mutexes. > > That depends on how you define both - most semaphore definitions do not > include the ownership concept, thus are not a superclass of > (owner-tracking) mutexes we consider here. >From my point of view, a mutex is a semaphore. If we imagine it in simple OOP terms, the mutex class inherit from the semaphore class. Yes, it has an owner member which the semaphore has not, but it still is a semaphore. -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 06/12] Lockless fast path for xnsynch_acquire/release
Gilles Chanteperdrix wrote: > Jan Kiszka wrote: >> Gilles Chanteperdrix wrote: >>> Jan Kiszka wrote: >>> >>> Ok. Though I do not see the point of the FASTSEM/FASTSYNCH rename. >>> FASTSEM is short, and we are not much interested in getting anything >>> else than semaphores faster. >> We aren't optimizing semaphores (at least not yet), we are optimizing >> mutexes only. And if we ever optimize also semaphores, FASTSYNCH will >> luckily still fit. :) > > The name was chosen because we plan to optimize semaphores as well, and > because mutexes are simply a special kind of semaphores, so, by saying > FASTSEM, we cover semaphores as well as mutexes. That depends on how you define both - most semaphore definitions do not include the ownership concept, thus are not a superclass of (owner-tracking) mutexes we consider here. Jan signature.asc Description: OpenPGP digital signature ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] rt_task_info.status encoding
Jan Kiszka wrote: > I start to believe we are arguing with different (miss-)use case in > mind. Mine is definitely not about "helping" the user to switch the > thread mode even more actively. It is about validating application > states, it is about thread state reflection without any other actions > than reporting errors. T_PRIMARY is part of the picture for the dual > kernel Xenomai version, and it will remain such as long as there are two > kernels. Even better, it is a very helpful application debugging tool > when it comes to runtime validation of their real-time behavior. Again, > it is NOT about promoting more use of rt_task_set_mode! SIGXCPU may be used validate current thread mode, and it has the advantage that it can not be misused. -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 0/2] Fix and improve task/thread inquire services
Philippe Gerum wrote: > Jan Kiszka wrote: >> Gilles Chanteperdrix wrote: >>> Jan Kiszka wrote: This series fixes the issues around rt_task_inquire I posted yesterday. Additionally, it introduces an analogous services pthread_inquire_np for the POSIX skin. That allows, among other things, to implement test cases for the upcoming fast xnsynch/mutex patches. >>> Ok. Since this applies only for debugging purpose, and displaying >>> whether a task is in primary mode may be use badly by users, maybe we >>> should make this service a shadow syscall, and not export any interface >>> to use it. This would further avoid duplication between the native and >>> posix skins. >> Debugging is not the holy, exclusive business of Xenomai hackers. >> >> The inquire services are useful in libraries as well, when you want to >> check if the caller complies to the call convention ("don't use in >> primary mode", "caller's priority must not exceed X" or whatever). >> >> That said, I'm open for unifying the code, maybe introducing some >> xnthread_inquire. >> > > That would be much better than publishing an open interface to fiddle even > more > with thread modes via rt_task_set_mode(). I would definitely merge that. Code refactoring is no problem, will work that out. I just want to keep the user interface. Jan signature.asc Description: OpenPGP digital signature ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 06/12] Lockless fast path for xnsynch_acquire/release
Jan Kiszka wrote: > Gilles Chanteperdrix wrote: >> Jan Kiszka wrote: >> >> Ok. Though I do not see the point of the FASTSEM/FASTSYNCH rename. >> FASTSEM is short, and we are not much interested in getting anything >> else than semaphores faster. > > We aren't optimizing semaphores (at least not yet), we are optimizing > mutexes only. And if we ever optimize also semaphores, FASTSYNCH will > luckily still fit. :) The name was chosen because we plan to optimize semaphores as well, and because mutexes are simply a special kind of semaphores, so, by saying FASTSEM, we cover semaphores as well as mutexes. -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 07/12] Convert POSIX skin to fast xnsynch
Gilles Chanteperdrix wrote: > Jan Kiszka wrote: > > This patch contains too many #ifdefs. > > Things like > > #ifdef CONFIG_XENO_FASTSYNCH > if (xnsynch_fast_owner_check(...)) > #else > if (xnsynch_owner(...) == ...) > #endif > > could be replaced with only one macro xnsynch_check_owner in synch.h > that would be defined with some #ifdefs, and used everywhere without > #ifdefs. Yes, that looks like a good idea. Will go through the patch again, checking for more cleanup possibilities like that. Jan signature.asc Description: OpenPGP digital signature ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 06/12] Lockless fast path for xnsynch_acquire/release
Gilles Chanteperdrix wrote: > Jan Kiszka wrote: > > Ok. Though I do not see the point of the FASTSEM/FASTSYNCH rename. > FASTSEM is short, and we are not much interested in getting anything > else than semaphores faster. We aren't optimizing semaphores (at least not yet), we are optimizing mutexes only. And if we ever optimize also semaphores, FASTSYNCH will luckily still fit. :) Jan signature.asc Description: OpenPGP digital signature ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 01/12] Generic thread registration
Gilles Chanteperdrix wrote: > Jan Kiszka wrote: > > Why the funky last parameter added to __rt_bind_helper ? As __rt_bind_helper can now be called with an xnthread object address, thus we take its offset inside RT_TASK into account. It is not a nice interface, I know, but I didn't find a better one. Jan signature.asc Description: OpenPGP digital signature ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] rt_task_info.status encoding
Philippe Gerum wrote: > Jan Kiszka wrote: >> Philippe Gerum wrote: >>> Jan Kiszka wrote: Hi, the documentation refers to the Native Task Status (T_*) when it comes to documenting rt_task_info.status. That is not correct. That field contains far more flags than T_* is describing and, even worse, comes with two collisions: T_PRIMARY and T_JOINABLE are not reported by rt_task_inquire, rather T_RELAX (!T_PRIMARY, arrrg...) and T_HELD. >>> T_PRIMARY is NOT meant to be reported by rt_task_inquire(), and actually, >>> its >>> value was picked to collide, to reflect the fact that it was a one-way >> So you preferred to break rt_task_inquire instead of letting it return a >> consistent value? Not really? > > As explained earlier, the thing you have to understand is that > rt_task_inquire() > is not broken, it just does not work your way, which is a different issue. At the bare minimum, its documentation is broken. It points to state values which rt_task_inquire does not return. > >>> specifier. You can't use T_RELAX because what is needed is a bit to force a >>> transition to primary mode using rt_task_set_mode(), which is the actual >>> source >>> of all uglinesses. Aside of this, the nucleus naturally wants a "relaxed >>> state" >>> bit, and would not get any help from a "primary mode" bit for threads. >> I'm not arguing for removing T_PRIMARY, I was just struggling with the >> confusing values rt_task_inquire reported to me. >> > > This is because you want T_PRIMARY to be part of the rt_task_inquire() return > values. It must not, really. When apps start playing with the current mode, > things start falling apart. I don't want to make T_PRIMARY a first-class > citizen > of the interface; considering it as a legitimate value of an inquiry service > would do that. So that is a NAK. I start to believe we are arguing with different (miss-)use case in mind. Mine is definitely not about "helping" the user to switch the thread mode even more actively. It is about validating application states, it is about thread state reflection without any other actions than reporting errors. T_PRIMARY is part of the picture for the dual kernel Xenomai version, and it will remain such as long as there are two kernels. Even better, it is a very helpful application debugging tool when it comes to runtime validation of their real-time behavior. Again, it is NOT about promoting more use of rt_task_set_mode! > >>> We could have used a T_RELAX bit to clear in rt_task_set_mode() instead of >>> T_PRIMARY to set, but unfortunately, such a negative logic would have been >>> somewhat confusing to users, since what is provided is the secondary -> >>> primary >>> mode switch. >>> >>> Sending back the current mode in rt_task_inquire() would lead to two >>> additional >>> issues: >>> 1) if for some reason, we would like to switch the caller to secondary mode >>> at >>> some point to be able to provide a more complete status, the >>> primary/secondary >>> status returned would make no sense at all. The fact that we don't do it now >>> does not preclude the need to do it in future releases. >> Sorry, but this is very far fetched. >> > > Sorry, you are wrong. rt_task_inquire() is currently marked as __xn_exec_any, > which means that it is processed in the current thread mode, but always from > the > Xenomai stage in the pipeline. If at some point, we extend rt_task_inquire() > to > return information from the Linux realm (e.g. protected by a RCU construct), > we > would have to move that call to __xn_exec_lostage. Conversely, if at some > point > the rt_task_inquire() service is changed so that getting information from the > nucleus involves blocking, then we would have to make that call > __xn_exec_primary. > > Far fetched, even impossible that we would need that? Not that much actually. > A > number of people have native Xenomai kernel modules interacting with native > Xenomai apps in userland; those modules maintain a significant portion of the > application logic, and some did reimplement some kind of rt_task_inquire() for > debugging and logging purposes. Instead of that, we could allow the in-kernel > part to be asked for additional information via a callback from the > rt_task_inquire() implementation, using the RT_TASK_INFO struct as a common > return header, that could be completed with more data. > In that case, rt_task_inquire() would have to be flexible when it comes to the > thread mode, currently it is not, because you may only fetch information that > is > immediately available from the Xenomai stage, without blocking. > > Therefore, in both cases, T_PRIMARY would become meaningless as a return > value. We will nevertheless be able to take a snapshot (for debugging purposes!) of the thread state before any potential mode switch, see my patch for mirroring the mode into user space for fast xnsynch services. Moreover, making a formerly primary-safe service secondary (jus
Re: [Xenomai-core] [PATCH 12/12] Enable SMP support for user libs by default
Jan Kiszka wrote: I do not like this patch. This sould be solved using the existing features system. I do not want SMP to be enabled by default. -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 11/12] Ensure mode switch in mutex fast paths
Jan Kiszka wrote: Ok. -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 10/12] Report current shadow thread mode to user space
Jan Kiszka wrote: Ok. I still liked the solution of using a piece of shared heap. This was more general and would have allowed us to use this piece of shared heap for future purposes. -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 09/12] Optionally replace pthread_getspecific with TLS variables
Jan Kiszka wrote: The real downside here is a lot of #ifdef clutter. What about the idea of defining an API to abstract the differences between pthread_get/setspecific and __thread and have #ifdef only in one header ? -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 08/12] Use fast xnsynch with native skin
Jan Kiszka wrote: Same remark for the #ifdefs. I also do not understand your modification of rt_cond_wait_inner, this code is very tense; posix and native had the same bug in this area at different times, so this change should probably be made separately. -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 0/2] Fix and improve task/thread inquire services
Jan Kiszka wrote: > Gilles Chanteperdrix wrote: >> Jan Kiszka wrote: >>> This series fixes the issues around rt_task_inquire I posted yesterday. >>> Additionally, it introduces an analogous services pthread_inquire_np for >>> the POSIX skin. That allows, among other things, to implement test cases >>> for the upcoming fast xnsynch/mutex patches. >> Ok. Since this applies only for debugging purpose, and displaying >> whether a task is in primary mode may be use badly by users, maybe we >> should make this service a shadow syscall, and not export any interface >> to use it. This would further avoid duplication between the native and >> posix skins. > > Debugging is not the holy, exclusive business of Xenomai hackers. > > The inquire services are useful in libraries as well, when you want to > check if the caller complies to the call convention ("don't use in > primary mode", "caller's priority must not exceed X" or whatever). > > That said, I'm open for unifying the code, maybe introducing some > xnthread_inquire. > That would be much better than publishing an open interface to fiddle even more with thread modes via rt_task_set_mode(). I would definitely merge that. > Jan > -- Philippe. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 07/12] Convert POSIX skin to fast xnsynch
Jan Kiszka wrote: This patch contains too many #ifdefs. Things like #ifdef CONFIG_XENO_FASTSYNCH if (xnsynch_fast_owner_check(...)) #else if (xnsynch_owner(...) == ...) #endif could be replaced with only one macro xnsynch_check_owner in synch.h that would be defined with some #ifdefs, and used everywhere without #ifdefs. -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 06/12] Lockless fast path for xnsynch_acquire/release
Jan Kiszka wrote: Ok. Though I do not see the point of the FASTSEM/FASTSYNCH rename. FASTSEM is short, and we are not much interested in getting anything else than semaphores faster. -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] rt_task_info.status encoding
Jan Kiszka wrote: > Philippe Gerum wrote: >> Jan Kiszka wrote: >>> Hi, >>> >>> the documentation refers to the Native Task Status (T_*) when it comes >>> to documenting rt_task_info.status. That is not correct. That field >>> contains far more flags than T_* is describing and, even worse, comes >>> with two collisions: T_PRIMARY and T_JOINABLE are not reported by >>> rt_task_inquire, rather T_RELAX (!T_PRIMARY, arrrg...) and T_HELD. >>> >> T_PRIMARY is NOT meant to be reported by rt_task_inquire(), and actually, its >> value was picked to collide, to reflect the fact that it was a one-way > > So you preferred to break rt_task_inquire instead of letting it return a > consistent value? Not really? As explained earlier, the thing you have to understand is that rt_task_inquire() is not broken, it just does not work your way, which is a different issue. > >> specifier. You can't use T_RELAX because what is needed is a bit to force a >> transition to primary mode using rt_task_set_mode(), which is the actual >> source >> of all uglinesses. Aside of this, the nucleus naturally wants a "relaxed >> state" >> bit, and would not get any help from a "primary mode" bit for threads. > > I'm not arguing for removing T_PRIMARY, I was just struggling with the > confusing values rt_task_inquire reported to me. > This is because you want T_PRIMARY to be part of the rt_task_inquire() return values. It must not, really. When apps start playing with the current mode, things start falling apart. I don't want to make T_PRIMARY a first-class citizen of the interface; considering it as a legitimate value of an inquiry service would do that. So that is a NAK. >> We could have used a T_RELAX bit to clear in rt_task_set_mode() instead of >> T_PRIMARY to set, but unfortunately, such a negative logic would have been >> somewhat confusing to users, since what is provided is the secondary -> >> primary >> mode switch. >> >> Sending back the current mode in rt_task_inquire() would lead to two >> additional >> issues: >> 1) if for some reason, we would like to switch the caller to secondary mode >> at >> some point to be able to provide a more complete status, the >> primary/secondary >> status returned would make no sense at all. The fact that we don't do it now >> does not preclude the need to do it in future releases. > > Sorry, but this is very far fetched. > Sorry, you are wrong. rt_task_inquire() is currently marked as __xn_exec_any, which means that it is processed in the current thread mode, but always from the Xenomai stage in the pipeline. If at some point, we extend rt_task_inquire() to return information from the Linux realm (e.g. protected by a RCU construct), we would have to move that call to __xn_exec_lostage. Conversely, if at some point the rt_task_inquire() service is changed so that getting information from the nucleus involves blocking, then we would have to make that call __xn_exec_primary. Far fetched, even impossible that we would need that? Not that much actually. A number of people have native Xenomai kernel modules interacting with native Xenomai apps in userland; those modules maintain a significant portion of the application logic, and some did reimplement some kind of rt_task_inquire() for debugging and logging purposes. Instead of that, we could allow the in-kernel part to be asked for additional information via a callback from the rt_task_inquire() implementation, using the RT_TASK_INFO struct as a common return header, that could be completed with more data. In that case, rt_task_inquire() would have to be flexible when it comes to the thread mode, currently it is not, because you may only fetch information that is immediately available from the Xenomai stage, without blocking. Therefore, in both cases, T_PRIMARY would become meaningless as a return value. >> 2) rt_task_set_mode(..., T_PRIMARY) is already vastly misused in a number of >> applications, sometimes uselessly, most of the time in a way that event kills >> performances. Giving an interface to get back the current mode would close >> the >> loop, triggering a whole set of new terminally silly usage of that hack. >> Applications should NEVER use that feature, it was initially designed for >> internal code (i.e. RTDM if my memory serves me well). Actually, the more I >> think of it, the more I convinced that I'm going to slaughter this crap in >> 2.5, >> providing an internal syscall from the XENOMAI_SYS class instead for use >> only in >> proper contexts. > > This is a different issue. > > See, I needed rt_task_inquire for precisely the purpose it is (mostly) > designed for: tracing / debugging. And for that purpose, a valid > T_PRIMARY bit is of very high importance. I even implemented the same > inquire service for POSIX in the meantime so that I was able to > implement all functional tests I needed for the fast mutexes. > See, the point is that T_PRIMARY is often misused because it belongs to the mainline interface whil
Re: [Xenomai-core] rt_task_info.status encoding
Gilles Chanteperdrix wrote: > Philippe Gerum wrote: >> Jan Kiszka wrote: >>> Hi, >>> >>> the documentation refers to the Native Task Status (T_*) when it comes >>> to documenting rt_task_info.status. That is not correct. That field >>> contains far more flags than T_* is describing and, even worse, comes >>> with two collisions: T_PRIMARY and T_JOINABLE are not reported by >>> rt_task_inquire, rather T_RELAX (!T_PRIMARY, arrrg...) and T_HELD. >>> >> T_PRIMARY is NOT meant to be reported by rt_task_inquire(), and actually, its >> value was picked to collide, to reflect the fact that it was a one-way >> specifier. You can't use T_RELAX because what is needed is a bit to force a >> transition to primary mode using rt_task_set_mode(), which is the actual >> source >> of all uglinesses. Aside of this, the nucleus naturally wants a "relaxed >> state" >> bit, and would not get any help from a "primary mode" bit for threads. >> >> We could have used a T_RELAX bit to clear in rt_task_set_mode() instead of >> T_PRIMARY to set, but unfortunately, such a negative logic would have been >> somewhat confusing to users, since what is provided is the secondary -> >> primary >> mode switch. >> >> Sending back the current mode in rt_task_inquire() would lead to two >> additional >> issues: >> 1) if for some reason, we would like to switch the caller to secondary mode >> at >> some point to be able to provide a more complete status, the >> primary/secondary >> status returned would make no sense at all. The fact that we don't do it now >> does not preclude the need to do it in future releases. >> 2) rt_task_set_mode(..., T_PRIMARY) is already vastly misused in a number of >> applications, sometimes uselessly, most of the time in a way that event kills >> performances. Giving an interface to get back the current mode would close >> the >> loop, triggering a whole set of new terminally silly usage of that hack. >> Applications should NEVER use that feature, it was initially designed for >> internal code (i.e. RTDM if my memory serves me well). Actually, the more I >> think of it, the more I convinced that I'm going to slaughter this crap in >> 2.5, >> providing an internal syscall from the XENOMAI_SYS class instead for use >> only in >> proper contexts. >> >> T_JOINABLE might be reported, though, that is a different story. >> >>> I see two ways out of this: >>> >>> a) Redirect the documentation to the nucleus thread state flags. >>> >> Which means that the documentation of the skin depends on the implementation >> of >> the core. Bad idea. > > We also have a difficulty: when pdf documentations are generated, the > nucleus and native skin documentation end up in different documents. So, > we can not redirect the native skin documentation to nucleus. > >>> b) Redefine the numerical values of T_PRIMARY and T_JOINABLE (the spare >>> bits are unused with the native skin), add missing but possibly >>> interesting flags as T_-constants and ensure that T_PRIMARY and >>> T_JOINABLE are correctly injected on rt_task_inquire from user >>> space. >> Maybe for T_JOINABLE. Gilles? > > Ok for me. > > As a side note, I happen to use pthread_set_mode_np to trigger manual > mode transitions: I do this before calling the "socket" service to > trigger rtnet socket creation in secondary mode, where it can call > safely the kernel allocation methods. So, I am not really in favor of > removing this service. > The idea is not to remove the service, but rather to make perfectly clear that such feature is not for normal usage. I did agree a long time ago that it could be needed by low-level skin code when Jan asked for it, but I'm against its widespread use. > However, if this usage disappears, and if we fix the issue with mode > switches and mutexes, I am Ok with removing the voluntary mode switches, > as I agree that they can be misused. > It should be kept, but moved out from the mainline API, only accessible via a direct XENOMAI_SYS() call, not using a high level interface such as rt_task_set_mode(). The message should be: this is an internal service for skin developers, if you need it for regular application code, then something looks broken in your code. Userland code that implements extended debugging facilities or any kind of tricky instrumentation feature would still be allowed to call the direct interface, but at least, this would not be done carelessly anymore. Hopefully. -- Philippe. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 05/12] Factor out xnsynch_acquire/release
Jan Kiszka wrote: Ok. -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 04/12] Spread xeno_set_current under all skins
Jan Kiszka wrote: Ok. -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 03/12] Remove xnarch_atomic_intptr
Jan Kiszka wrote: Ok. -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 02/12] Handle-based xeno_get_current service
Jan Kiszka wrote: ok for me. -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 01/12] Generic thread registration
Jan Kiszka wrote: Why the funky last parameter added to __rt_bind_helper ? -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 12/12] Enable SMP support for user libs by default
With fast xnsynch/mutex support in place, the importance of getting the user space library configuration right increases significantly. If the user fails to provide --enable-smp, (s)he risks to break the mutex fast path in a very subtle way. Thus, it is better to assume SMP by default (as far as the arch bothers at all) and let the user switch it off for intentional optimization for UP-only targets. Signed-off-by: Jan Kiszka <[EMAIL PROTECTED]> --- README.INSTALL |2 +- configure.in |6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) Index: b/configure.in === --- a/configure.in +++ b/configure.in @@ -132,12 +132,12 @@ AC_ARG_ENABLE(debug, esac]) AC_MSG_RESULT(${debug_symbols:-no}) -dnl SMP support (default: off) +dnl SMP support (default: on) -CONFIG_SMP= +CONFIG_SMP=y AC_MSG_CHECKING(for SMP support) AC_ARG_ENABLE(smp, - AS_HELP_STRING([--enable-smp], [Enable SMP support]), + AS_HELP_STRING([--disable-smp], [Disable SMP support (if the target supports it at all)]), [case "$enableval" in y | yes) CONFIG_SMP=y ;; *) unset CONFIG_SMP ;; Index: b/README.INSTALL === --- a/README.INSTALL +++ b/README.INSTALL @@ -143,7 +143,7 @@ NAME DESCRIPTION --prefix Installation directory /usr/xenomai --enable-debug Enable debug symbols (-g) disabled ---enable-smp Enable SMP support weak,disabled +--disable-smpDisable SMP support weak,enabled 1.3.3 Arch-specific configure options - ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 11/12] Ensure mode switch in mutex fast paths
With the help of xeno_get_current_mode(), this patch ensures that shadow threads in secondary mode will be switched to primary again in case they acquire an uncontended native or POSIX mutex, thus would otherwise only pick the user space fast path. This prevents potential priority inversions that the fast mutex optimizations introduced. Signed-off-by: Jan Kiszka <[EMAIL PROTECTED]> --- src/skins/native/mutex.c | 31 --- src/skins/posix/mutex.c | 94 +++ 2 files changed, 71 insertions(+), 54 deletions(-) Index: b/src/skins/native/mutex.c === --- a/src/skins/native/mutex.c +++ b/src/skins/native/mutex.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -78,22 +79,24 @@ static int rt_mutex_acquire_inner(RT_MUT if (!cur) return -EPERM; - err = xnsynch_fast_acquire(mutex->fastlock, cur); - if (likely(!err)) { - mutex->lockcnt = 1; - return 0; - } - - if (err == -EBUSY) { - if (mutex->lockcnt == UINT_MAX) - return -EAGAIN; + if (likely(!(xeno_get_current_mode() & XNRELAX))) { + err = xnsynch_fast_acquire(mutex->fastlock, cur); + if (likely(!err)) { + mutex->lockcnt = 1; + return 0; + } + + if (err == -EBUSY) { + if (mutex->lockcnt == UINT_MAX) + return -EAGAIN; + + mutex->lockcnt++; + return 0; + } - mutex->lockcnt++; - return 0; + if (timeout == TM_NONBLOCK && mode == XN_RELATIVE) + return -EWOULDBLOCK; } - - if (timeout == TM_NONBLOCK && mode == XN_RELATIVE) - return -EWOULDBLOCK; #endif /* CONFIG_XENO_FASTSYNCH */ err = XENOMAI_SKINCALL3(__native_muxid, Index: b/src/skins/posix/mutex.c === --- a/src/skins/posix/mutex.c +++ b/src/skins/posix/mutex.c @@ -164,31 +164,33 @@ int __wrap_pthread_mutex_lock(pthread_mu goto out; } - err = xnsynch_fast_acquire(get_ownerp(shadow), cur); + if (likely(!(xeno_get_current_mode() & XNRELAX))) { + err = xnsynch_fast_acquire(get_ownerp(shadow), cur); - if (likely(!err)) { - shadow->lockcnt = 1; - cb_read_unlock(&shadow->lock, s); - return 0; - } + if (likely(!err)) { + shadow->lockcnt = 1; + cb_read_unlock(&shadow->lock, s); + return 0; + } - if (err == -EBUSY) - switch(shadow->attr.type) { - case PTHREAD_MUTEX_NORMAL: - break; + if (err == -EBUSY) + switch(shadow->attr.type) { + case PTHREAD_MUTEX_NORMAL: + break; - case PTHREAD_MUTEX_ERRORCHECK: - err = -EDEADLK; - goto out; + case PTHREAD_MUTEX_ERRORCHECK: + err = -EDEADLK; + goto out; - case PTHREAD_MUTEX_RECURSIVE: - if (shadow->lockcnt == UINT_MAX) { - err = -EAGAIN; + case PTHREAD_MUTEX_RECURSIVE: + if (shadow->lockcnt == UINT_MAX) { + err = -EAGAIN; + goto out; + } + ++shadow->lockcnt; + err = 0; goto out; } - ++shadow->lockcnt; - err = 0; - goto out; } #endif /* CONFIG_XENO_FASTSYNCH */ @@ -226,32 +228,34 @@ int __wrap_pthread_mutex_timedlock(pthre goto out; } - err = xnsynch_fast_acquire(get_ownerp(shadow), cur); + if (likely(!(xeno_get_current_mode() & XNRELAX))) { + err = xnsynch_fast_acquire(get_ownerp(shadow), cur); - if (likely(!err)) { - shadow->lockcnt = 1; - cb_read_unlock(&shadow->lock, s); - return 0; - } + if (likely(!err)) { + shadow->lockcnt = 1; + cb_read_unlock(&shadow->lock, s); + return 0; + } - if (err == -EBUSY) - switch(shadow->attr.type) { - case PTHREAD_MUTEX_NORMAL: - break; +
Re: [Xenomai-core] [PATCH 00/12] Generic fast xnsynch support & more
Jan Kiszka wrote: > Here comes a significantly reworked patch series to improve fast mutex > support of Xenomai. > > This approach now introduces a generic fast xnsynch core and converts > the existing POSIX implementation over. It also comes with a second > user, the Native skin. Additionally, it improves xeno_get_current via > a TLS variable and addresses the issue that threads in secondary mode > acquiring an uncontended mutex need to be migrated first. > > At this chance, the TLS optimization is also applied on self-lookups of > task handles (Native, VRTX and VxWorks). And I included my > SMP-by-default patch for user libs which is highly recommended to reduce > the risk of accidental code breakage on SMP with the new mutex code. Looks like patches 11 and 12 are missing here. -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 01/12] Generic thread registration
Lay groundwork for registering every thread at least anonymously with the Xenomai registry when required (e.g. handle-based fast xnsynch support). Wrap the operations appropriately, also saving a few #ifdefs. Signed-off-by: Jan Kiszka <[EMAIL PROTECTED]> --- include/nucleus/registry.h |1 include/nucleus/thread.h | 25 + ksrc/nucleus/thread.c|2 + ksrc/skins/native/syscall.c | 61 ++- ksrc/skins/native/task.c | 13 - ksrc/skins/psos+/syscall.c | 19 - ksrc/skins/psos+/task.c | 20 +++--- ksrc/skins/vxworks/syscall.c | 31 - ksrc/skins/vxworks/taskLib.c | 10 --- 9 files changed, 102 insertions(+), 80 deletions(-) Index: b/ksrc/skins/native/syscall.c === --- a/ksrc/skins/native/syscall.c +++ b/ksrc/skins/native/syscall.c @@ -52,7 +52,8 @@ int __native_muxid; static int __rt_bind_helper(struct task_struct *p, struct pt_regs *regs, xnhandle_t *handlep, - unsigned magic, void **objaddrp) + unsigned magic, void **objaddrp, + unsigned long objoffs) { char name[XNOBJECT_NAME_LEN]; RTIME timeout; @@ -82,7 +83,7 @@ static int __rt_bind_helper(struct task_ /* Also validate the type of the bound object. */ - if (xeno_test_magic(objaddr, magic)) { + if (xeno_test_magic(objaddr + objoffs, magic)) { if (objaddrp) *objaddrp = objaddr; } else @@ -93,6 +94,11 @@ static int __rt_bind_helper(struct task_ return err; } +static RT_TASK *__rt_task_lookup(xnhandle_t threadh) +{ + return thread2rtask(xnthread_lookup(threadh)); +} + static RT_TASK *__rt_task_current(struct task_struct *p) { xnthread_t *thread = xnshadow_thread(p); @@ -223,7 +229,9 @@ static int __rt_task_bind(struct pt_regs RT_TASK_PLACEHOLDER ph; int err; - err = __rt_bind_helper(p, regs, &ph.opaque, XENO_TASK_MAGIC, NULL); + err = + __rt_bind_helper(p, regs, &ph.opaque, XENO_TASK_MAGIC, NULL, +-offsetof(RT_TASK, thread_base)); if (err) return err; @@ -253,7 +261,7 @@ static int __rt_task_start(struct pt_reg sizeof(ph))) return -EFAULT; - task = (RT_TASK *)xnregistry_fetch(ph.opaque); + task = __rt_task_lookup(ph.opaque); if (!task) return -ESRCH; @@ -279,7 +287,7 @@ static int __rt_task_suspend(struct pt_r sizeof(ph))) return -EFAULT; - task = (RT_TASK *)xnregistry_fetch(ph.opaque); + task = __rt_task_lookup(ph.opaque); } else task = __rt_task_current(p); @@ -302,7 +310,7 @@ static int __rt_task_resume(struct pt_re sizeof(ph))) return -EFAULT; - task = (RT_TASK *)xnregistry_fetch(ph.opaque); + task = __rt_task_lookup(ph.opaque); if (!task) return -ESRCH; @@ -326,7 +334,7 @@ static int __rt_task_delete(struct pt_re sizeof(ph))) return -EFAULT; - task = (RT_TASK *)xnregistry_fetch(ph.opaque); + task = __rt_task_lookup(ph.opaque); } else task = __rt_task_current(p); @@ -364,7 +372,7 @@ static int __rt_task_set_periodic(struct sizeof(ph))) return -EFAULT; - task = (RT_TASK *)xnregistry_fetch(ph.opaque); + task = __rt_task_lookup(ph.opaque); } else task = __rt_task_current(p); @@ -418,7 +426,7 @@ static int __rt_task_set_priority(struct sizeof(ph))) return -EFAULT; - task = (RT_TASK *)xnregistry_fetch(ph.opaque); + task = __rt_task_lookup(ph.opaque); } else task = __rt_task_current(p); @@ -473,7 +481,7 @@ static int __rt_task_unblock(struct pt_r sizeof(ph))) return -EFAULT; - task = (RT_TASK *)xnregistry_fetch(ph.opaque); + task = __rt_task_lookup(ph.opaque); if (!task) return -ESRCH; @@ -500,7 +508,7 @@ static int __rt_task_inquire(struct pt_r sizeof(ph))) return -EFAULT; - task = (RT_TASK *)xnregistry_fetch(ph.opaque); + task = __rt_task_lookup(ph.opaque); } else task = __rt_task_current(p); @@ -541,7 +549,7 @@ static in
[Xenomai-core] [PATCH 06/12] Lockless fast path for xnsynch_acquire/release
This patch adds optional lockless fast paths to xnsynch_acquire and xnsynch_release. Those paths are considered if CONFIG_XENO_FASTSYNC is defined and the owner-tracking xnsynch object is given a non-NULL reference to an atomic fastlock variable on initialization. This allows for a smooth migration of existing mutex implementations in Xenomai skins to a fast xnsynch scheme. Signed-off-by: Jan Kiszka <[EMAIL PROTECTED]> --- configure.in | 16 ++-- include/asm-generic/bits/bind.h | 16 ++-- include/asm-generic/features.h| 24 +++--- include/nucleus/synch.h | 54 ++- ksrc/arch/arm/Kconfig |2 ksrc/arch/powerpc/Kconfig |2 ksrc/arch/x86/Kconfig |2 ksrc/drivers/testing/switchtest.c |2 ksrc/nucleus/pipe.c |2 ksrc/nucleus/registry.c |4 - ksrc/nucleus/select.c |2 ksrc/nucleus/synch.c | 132 -- ksrc/skins/native/Kconfig |2 ksrc/skins/native/alarm.c |2 ksrc/skins/native/buffer.c|4 - ksrc/skins/native/cond.c |2 ksrc/skins/native/event.c |2 ksrc/skins/native/heap.c |2 ksrc/skins/native/intr.c |2 ksrc/skins/native/mutex.c |2 ksrc/skins/native/queue.c |2 ksrc/skins/native/sem.c |2 ksrc/skins/native/task.c |6 - ksrc/skins/posix/Kconfig |2 ksrc/skins/posix/cb_lock.h|6 - ksrc/skins/posix/cond.c | 18 ++--- ksrc/skins/posix/intr.c |2 ksrc/skins/posix/mq.c |4 - ksrc/skins/posix/mutex.c | 12 +-- ksrc/skins/posix/mutex.h |4 - ksrc/skins/posix/sem.c|2 ksrc/skins/posix/syscall.c| 20 ++--- ksrc/skins/posix/thread.c |6 - ksrc/skins/psos+/Kconfig |2 ksrc/skins/psos+/event.c |2 ksrc/skins/psos+/queue.c |2 ksrc/skins/psos+/rn.c |2 ksrc/skins/psos+/sem.c|2 ksrc/skins/rtai/Kconfig |2 ksrc/skins/rtai/sem.c |2 ksrc/skins/rtai/task.c|4 - ksrc/skins/rtdm/drvlib.c | 10 +- ksrc/skins/uitron/Kconfig |2 ksrc/skins/uitron/flag.c |2 ksrc/skins/uitron/mbx.c |3 ksrc/skins/uitron/sem.c |3 ksrc/skins/uitron/task.c |4 - ksrc/skins/vrtx/Kconfig |2 ksrc/skins/vrtx/event.c |2 ksrc/skins/vrtx/mb.c |2 ksrc/skins/vrtx/mx.c |3 ksrc/skins/vrtx/queue.c |2 ksrc/skins/vrtx/sem.c |2 ksrc/skins/vxworks/Kconfig|2 ksrc/skins/vxworks/module.c |2 ksrc/skins/vxworks/msgQLib.c |2 ksrc/skins/vxworks/semLib.c |2 ksrc/skins/vxworks/syscall.c |2 ksrc/skins/vxworks/taskLib.c |2 src/skins/posix/mutex.c | 42 ++-- 60 files changed, 309 insertions(+), 162 deletions(-) Index: b/configure.in === --- a/configure.in +++ b/configure.in @@ -59,27 +59,27 @@ AM_PROG_LEX AC_MSG_CHECKING([for target architecture]) -CONFIG_XENO_FASTSEM= +CONFIG_XENO_FASTSYNCH= case "$host" in i*86*-*) XENO_TARGET_ARCH=x86 XENO_LINUX_ARCH=i386 XENO_LINUX_INSTALL_TARGET=install - CONFIG_XENO_FASTSEM=y + CONFIG_XENO_FASTSYNCH=y ;; powerpc-*|ppc-*) XENO_TARGET_ARCH=powerpc XENO_LINUX_ARCH=ppc XENO_LINUX_INSTALL_TARGET=install_image XENO_LINUX_IMAGE=arch/ppc/boot/images/zImage.elf - CONFIG_XENO_FASTSEM=y + CONFIG_XENO_FASTSYNCH=y ;; powerpc64-*|ppc64-*) XENO_TARGET_ARCH=powerpc XENO_LINUX_ARCH=ppc64 XENO_LINUX_INSTALL_TARGET=install_image XENO_LINUX_IMAGE=arch/ppc64/boot/images/zImage - CONFIG_XENO_FASTSEM=y + CONFIG_XENO_FASTSYNCH=y ;; ia64-*) XENO_TARGET_ARCH=ia64 @@ -96,14 +96,14 @@ case "$host" in XENO_LINUX_ARCH=arm XENO_LINUX_INSTALL_TARGET=install_image XENO_LINUX_IMAGE=arch/arm/boot/zImage - # We set CONFIG_XENO_FASTSEM later, when we know what architecture we + # We set CONFIG_XENO_FASTSYNCH later, when we know what architecture we # are running ;; x86_64-*|amd64-*) XENO_TARGET_ARCH=x86 XENO_LINUX_ARCH=x86_64 XENO_LINUX_INSTALL_TARGET=install - CONFIG_XENO_FASTSEM=y + CONFIG_XENO_FASTSYNCH=y ;; *) echo "" echo "***" @@ -288,7 +288,7 @@ user-space]), AC_MSG_RESULT(${CONFIG_XENO_ARM_EABI:-no}) if test $CONFIG_XENO_ARM_ARCH -ge 6 || test x$CONFIG_SMP != xy; then - CONFIG_XENO_FASTSEM=y + CONFI
[Xenomai-core] [PATCH 07/12] Convert POSIX skin to fast xnsynch
Migrates the existing fast mutex implementation of the POSIX skin to fast xnsynch services, also fixing the build for arch that do not support fast mutexes. Lock stealing via pthread_trylock is not considered by this patch, keeping this services lockless and syscall-less until we identify the need for using the steal mechanism also for this case. Signed-off-by: Jan Kiszka <[EMAIL PROTECTED]> --- ksrc/skins/posix/cond.c| 18 ++--- ksrc/skins/posix/mutex.c | 92 ksrc/skins/posix/mutex.h | 143 +++-- ksrc/skins/posix/syscall.c | 22 ++ src/skins/posix/mutex.c| 55 - 5 files changed, 132 insertions(+), 198 deletions(-) Index: b/ksrc/skins/posix/cond.c === --- a/ksrc/skins/posix/cond.c +++ b/ksrc/skins/posix/cond.c @@ -223,27 +223,23 @@ static inline int mutex_save_count(xnthr unsigned *count_ptr) { pse51_mutex_t *mutex; - xnthread_t *owner; if (!pse51_obj_active(shadow, PSE51_MUTEX_MAGIC, struct __shadow_mutex)) return EINVAL; mutex = shadow->mutex; - if (clear_claimed(xnarch_atomic_get(mutex->owner)) != - xnthread_handle(cur)) +#ifdef CONFIG_XENO_FASTSYNCH + if (xnsynch_fast_owner_check(mutex->synchbase.fastlock, +xnthread_handle(cur)) != 0) +#else /* !CONFIG_XENO_FASTSYNCH */ + if (xnsynch_owner(&mutex->synchbase) != cur) +#endif /* !CONFIG_XENO_FASTSYNCH */ return EPERM; *count_ptr = shadow->lockcnt; - if (likely(xnarch_atomic_cmpxchg(mutex->owner, cur, XN_NO_HANDLE) == - xnthread_handle(cur))) - return 0; - - owner = xnsynch_release(&mutex->synchbase); - xnarch_atomic_set(mutex->owner, - set_claimed(xnthread_handle(owner), - xnsynch_nsleepers(&mutex->synchbase))); + xnsynch_release(&mutex->synchbase); /* Do not reschedule here, releasing the mutex and suspension must be done atomically in pthread_cond_*wait. */ Index: b/ksrc/skins/posix/mutex.c === --- a/ksrc/skins/posix/mutex.c +++ b/ksrc/skins/posix/mutex.c @@ -102,9 +102,9 @@ int pse51_mutex_init_internal(struct __s shadow->magic = PSE51_MUTEX_MAGIC; shadow->mutex = mutex; shadow->lockcnt = 0; + xnarch_atomic_set(&shadow->lock, -1); #ifdef CONFIG_XENO_FASTSYNCH - xnarch_atomic_set(&shadow->lock, -1); shadow->attr = *attr; shadow->owner_offset = xnheap_mapped_offset(&sys_ppd->sem_heap, ownerp); #endif /* CONFIG_XENO_FASTSYNCH */ @@ -112,13 +112,10 @@ int pse51_mutex_init_internal(struct __s if (attr->protocol == PTHREAD_PRIO_INHERIT) synch_flags |= XNSYNCH_PIP; - xnsynch_init(&mutex->synchbase, synch_flags, NULL); + xnsynch_init(&mutex->synchbase, synch_flags, ownerp); inith(&mutex->link); mutex->attr = *attr; - mutex->owner = ownerp; mutex->owningq = kq; - mutex->sleepers = 0; - xnarch_atomic_set(ownerp, XN_NO_HANDLE); xnlock_get_irqsave(&nklock, s); appendq(&kq->mutexq, &mutex->link); @@ -159,7 +156,7 @@ int pthread_mutex_init(pthread_mutex_t * &((union __xeno_mutex *)mx)->shadow_mutex; DECLARE_CB_LOCK_FLAGS(s); pse51_mutex_t *mutex; - xnarch_atomic_t *ownerp; + xnarch_atomic_t *ownerp = NULL; int err; if (!attr) @@ -185,6 +182,7 @@ int pthread_mutex_init(pthread_mutex_t * if (!mutex) return ENOMEM; +#ifdef CONFIG_XENO_FASTSYNCH ownerp = (xnarch_atomic_t *) xnheap_alloc(&xnsys_ppd_get(attr->pshared)->sem_heap, sizeof(xnarch_atomic_t)); @@ -192,6 +190,7 @@ int pthread_mutex_init(pthread_mutex_t * xnfree(mutex); return EAGAIN; } +#endif /* CONFIG_XENO_FASTSYNCH */ cb_force_write_lock(&shadow->lock, s); err = pse51_mutex_init_internal(shadow, mutex, ownerp, attr); @@ -199,7 +198,9 @@ int pthread_mutex_init(pthread_mutex_t * if (err) { xnfree(mutex); +#ifdef CONFIG_XENO_FASTSYNCH xnheap_free(&xnsys_ppd_get(attr->pshared)->sem_heap, ownerp); +#endif /* CONFIG_XENO_FASTSYNCH */ } return -err; } @@ -216,8 +217,10 @@ void pse51_mutex_destroy_internal(pse51_ xnsynch_destroy(&mutex->synchbase); xnlock_put_irqrestore(&nklock, s); - if (mutex->attr.pshared) - xnheap_free(&xnsys_ppd_get(1)->sem_heap, mutex->owner); +#ifdef CONFIG_XENO_FASTSYNCH + xnheap_free(&xnsys_ppd_get(mutex->attr.pshared)->sem_heap, + mutex->synchbase.fastlock); +#endif /* CONFIG_XENO
[Xenomai-core] [PATCH 02/12] Handle-based xeno_get_current service
To avoid sharing kernel object pointers with user space, a handle-based approach is installed by this patch. It also reserves a few bits of the handle value for special use (like the claimed bit of fast xnsynch). Furthermore, the patch ensures that threads are registered at least anonymously to allow them being used with fast xnsynch objects. Signed-off-by: Jan Kiszka <[EMAIL PROTECTED]> --- include/asm-generic/bits/bind.h|9 - include/asm-generic/bits/current.h |5 +-- include/nucleus/types.h| 13 +++ ksrc/nucleus/shadow.c | 16 +++-- ksrc/skins/native/Kconfig |1 ksrc/skins/native/task.c |8 +--- ksrc/skins/posix/Kconfig |1 ksrc/skins/posix/cb_lock.h | 15 ++--- ksrc/skins/posix/cond.c| 12 --- ksrc/skins/posix/mutex.c | 21 +++- ksrc/skins/posix/mutex.h | 61 +++-- ksrc/skins/posix/syscall.c | 11 +++--- ksrc/skins/posix/thread.c | 12 +++ ksrc/skins/psos+/Kconfig |2 - ksrc/skins/rtai/Kconfig|1 ksrc/skins/rtai/task.c | 10 ++ ksrc/skins/rtdm/drvlib.c |8 ksrc/skins/uitron/Kconfig |1 ksrc/skins/uitron/task.c | 11 ++ ksrc/skins/vrtx/Kconfig|2 - ksrc/skins/vrtx/task.c | 17 +- ksrc/skins/vxworks/Kconfig |2 - src/skins/posix/mutex.c| 41 23 files changed, 199 insertions(+), 81 deletions(-) Index: b/include/asm-generic/bits/current.h === --- a/include/asm-generic/bits/current.h +++ b/include/asm-generic/bits/current.h @@ -2,14 +2,15 @@ #define _XENO_ASM_GENERIC_CURRENT_H #include +#include extern pthread_key_t xeno_current_key; extern void xeno_set_current(void); -static inline void *xeno_get_current(void) +static inline xnhandle_t xeno_get_current(void) { - return pthread_getspecific(xeno_current_key); + return (xnhandle_t)pthread_getspecific(xeno_current_key); } #endif /* _XENO_ASM_GENERIC_CURRENT_H */ Index: b/include/nucleus/types.h === --- a/include/nucleus/types.h +++ b/include/nucleus/types.h @@ -61,6 +61,19 @@ typedef unsigned long xnhandle_t; #define XN_NO_HANDLE ((xnhandle_t)0) +#define XN_HANDLE_SPARE0 ((xnhandle_t)0x1000) +#define XN_HANDLE_SPARE1 ((xnhandle_t)0x2000) +#define XN_HANDLE_SPARE2 ((xnhandle_t)0x4000) +#define XN_HANDLE_SPARE3 ((xnhandle_t)0x8000) +#define XN_HANDLE_SPARE_MASK ((xnhandle_t)0xf000) + +#define xnhandle_mask_spare(handle) ((handle) & ~XN_HANDLE_SPARE_MASK) +#define xnhandle_test_spare(handle, bits) (!!((handle) & (bits))) +#define xnhandle_set_spare(handle, bits) \ + do { (handle) |= (bits); } while (0) +#define xnhandle_clear_spare(handle, bits) \ + do { (handle) &= ~(bits); } while (0) + struct xnintr; typedef int (*xnisr_t)(struct xnintr *intr); Index: b/ksrc/nucleus/shadow.c === --- a/ksrc/nucleus/shadow.c +++ b/ksrc/nucleus/shadow.c @@ -1908,13 +1908,21 @@ static int xnshadow_sys_sem_heap(struct return __xn_safe_copy_to_user(us_hinfo, &hinfo, sizeof(*us_hinfo)); } +#ifdef CONFIG_XENO_OPT_REGISTRY static int xnshadow_sys_current(struct pt_regs *regs) { - xnthread_t * __user *us_current, *cur = xnshadow_thread(current); - us_current = (xnthread_t *__user *) __xn_reg_arg1(regs); + xnthread_t *cur = xnshadow_thread(current); + xnhandle_t __user *us_handle; - return __xn_safe_copy_to_user(us_current, &cur, sizeof(*us_current)); + if (!cur) + return -EPERM; + + us_handle = (xnhandle_t __user *) __xn_reg_arg1(regs); + + return __xn_safe_copy_to_user(us_handle, &xnthread_handle(cur), + sizeof(*us_handle)); } +#endif /* CONFIG_XENO_OPT_REGISTRY */ static xnsysent_t __systab[] = { [__xn_sys_migrate] = {&xnshadow_sys_migrate, __xn_exec_current}, @@ -1925,7 +1933,9 @@ static xnsysent_t __systab[] = { [__xn_sys_barrier] = {&xnshadow_sys_barrier, __xn_exec_lostage}, [__xn_sys_trace] = {&xnshadow_sys_trace, __xn_exec_any}, [__xn_sys_sem_heap] = {&xnshadow_sys_sem_heap, __xn_exec_any}, +#ifdef CONFIG_XENO_OPT_REGISTRY [__xn_sys_current] = {&xnshadow_sys_current, __xn_exec_any}, +#endif /* CONFIG_XENO_OPT_REGISTRY */ }; static void *xnshadow_sys_event(int event, void *data) Index: b/ksrc/skins/posix/cb_lock.h === --- a/ksrc/skins/posix/cb_lock.h +++ b/ksrc/skins/posix/cb_lock.h @@ -3,15 +3,22 @@ #include #include +#include #ifndef __KERNEL__ typedef void xnt
[Xenomai-core] [PATCH 05/12] Factor out xnsynch_acquire/release
This patch addresses the increasing divergence of owner-tracking vs. owner-less xnsynch objects. Services dealing with the former will include the new, lockless xnsynch prologue for optimizing its fastpath. At the the same time, this additional code should not disturb too much in those cases where we do not track ownership (condition variables, events, semaphores etc.). Moreover, I noticed that some of the existing code assumes XNSYNCH_NOPIP means no ownership, which is surely not true. The already visible effect is that lock stealing is needlessly restricted to XNSYNCH_PIP. Going through the API, I dug out three diverging services and replaced them with two new ones: Owner-less xnsynch objects: - xnsynch_sleep_on - xnsynch_wakeup_one_sleeper - xnsynch_wakeup_this_sleeper Owner-tracking xnsynch objects: - xnsynch_acquire - xnsynch_release The latter type of objects are marked with the new flag XNSYNCH_OWNER, used only for debugging and code documentation purposes in the current implementation. Signed-off-by: Jan Kiszka <[EMAIL PROTECTED]> --- include/nucleus/synch.h | 16 + include/rtdm/rtdm_driver.h |2 ksrc/nucleus/synch.c| 418 +--- ksrc/skins/native/cond.c|2 ksrc/skins/native/mutex.c |7 ksrc/skins/native/task.c|5 ksrc/skins/posix/cond.c |2 ksrc/skins/posix/mutex.c| 10 - ksrc/skins/posix/mutex.h|6 ksrc/skins/rtai/sem.c | 10 - ksrc/skins/rtdm/drvlib.c| 15 - ksrc/skins/vrtx/mx.c|6 ksrc/skins/vxworks/semLib.c |6 13 files changed, 326 insertions(+), 179 deletions(-) Index: b/include/nucleus/synch.h === --- a/include/nucleus/synch.h +++ b/include/nucleus/synch.h @@ -30,10 +30,11 @@ #define XNSYNCH_NOPIP 0x0 #define XNSYNCH_PIP 0x2 #define XNSYNCH_DREORD 0x4 +#define XNSYNCH_OWNER 0x8 #if defined(__KERNEL__) || defined(__XENO_SIM__) -#define XNSYNCH_CLAIMED 0x8/* Claimed by other thread(s) w/ PIP */ +#define XNSYNCH_CLAIMED 0x10 /* Claimed by other thread(s) w/ PIP */ /* Spare flags usable by upper interfaces */ #define XNSYNCH_SPARE0 0x0100 @@ -105,13 +106,18 @@ void xnsynch_sleep_on(xnsynch_t *synch, struct xnthread *xnsynch_wakeup_one_sleeper(xnsynch_t *synch); -struct xnthread *xnsynch_peek_pendq(xnsynch_t *synch); - xnpholder_t *xnsynch_wakeup_this_sleeper(xnsynch_t *synch, xnpholder_t *holder); -int xnsynch_flush(xnsynch_t *synch, - xnflags_t reason); +void xnsynch_acquire(xnsynch_t *synch, +xnticks_t timeout, +xntmode_t timeout_mode); + +struct xnthread *xnsynch_release(xnsynch_t *synch); + +struct xnthread *xnsynch_peek_pendq(xnsynch_t *synch); + +int xnsynch_flush(xnsynch_t *synch, xnflags_t reason); void xnsynch_release_all_ownerships(struct xnthread *thread); Index: b/ksrc/nucleus/synch.c === --- a/ksrc/nucleus/synch.c +++ b/ksrc/nucleus/synch.c @@ -59,6 +59,12 @@ * - XNSYNCH_PRIO causes the threads waiting for the resource to pend * in priority order. Otherwise, FIFO ordering is used (XNSYNCH_FIFO). * + * - XNSYNCH_OWNER indicates that the synchronization object shall + * track its owning thread (required if XNSYNCH_PIP is selected). Note + * that setting this flag implies the use xnsynch_acquire and + * xnsynch_release instead of xnsynch_sleep_on and + * xnsynch_wakeup_one_sleeper/xnsynch_wakeup_this_sleeper. + * * - XNSYNCH_PIP causes the priority inheritance mechanism to be * automatically activated when a priority inversion is detected among * threads using this object. Otherwise, no priority inheritance takes @@ -89,7 +95,7 @@ void xnsynch_init(xnsynch_t *synch, xnfl initph(&synch->link); if (flags & XNSYNCH_PIP) - flags |= XNSYNCH_PRIO; /* Obviously... */ + flags |= XNSYNCH_PRIO | XNSYNCH_OWNER; /* Obviously... */ synch->status = flags & ~XNSYNCH_CLAIMED; synch->owner = NULL; @@ -98,6 +104,209 @@ void xnsynch_init(xnsynch_t *synch, xnfl xnarch_init_display_context(synch); } +/*! + * \fn void xnsynch_sleep_on(xnsynch_t *synch, xnticks_t timeout, + * xntmode_t timeout_mode); + * \brief Sleep on an ownerless synchronization object. + * + * Makes the calling thread sleep on the specified synchronization + * object, waiting for it to be signaled. + * + * This service should be called by upper interfaces wanting the + * current thread to pend on the given resource. It must not be used + * with synchronization objects that are supposed to track ownership + * (XNSYNCH_OWNER). + * + * @param synch The descriptor address of the synchronization object + * to sleep on. + * + * @param timeout The timeout which may be used to limit the time the + * thread pends on t
[Xenomai-core] [PATCH 09/12] Optionally replace pthread_getspecific with TLS variables
On architectures that support the __thread storage class and the initial-exec TLS model, several use cases of pthread_get/setspecific can be optimized. On x86, e.g., we are able to implement xeno_get_current() via just two instructions instead of a call into glibc and all the included pthread_key lookup. The minor downside of initial-exec TLS is that libraries using such variables are excluded from dlopen. This patch adds the required check to configure, also installing a switch (--without-__thread) in order to disable the support if dlopen compatibility should be required. It adds a __thread-variant for xeno_get_current and self-references of the current Native, VRTX and VxWorks tasks. RTDK's rt_printf services are intentionally not converted as they are heavy-weighted anyway and depend on the pthread_key destructor mechanism. Signed-off-by: Jan Kiszka <[EMAIL PROTECTED]> --- configure.in | 23 +++ include/asm-generic/bits/bind.h| 44 ++--- include/asm-generic/bits/current.h | 13 +- src/skins/native/init.c|8 +- src/skins/native/task.c| 21 + src/skins/vrtx/init.c |8 +- src/skins/vrtx/task.c | 14 ++- src/skins/vxworks/init.c |8 +- src/skins/vxworks/taskLib.c| 20 +++- 9 files changed, 137 insertions(+), 22 deletions(-) Index: b/configure.in === --- a/configure.in +++ b/configure.in @@ -762,6 +762,29 @@ LIBS="$LIBS -lrt" AC_CHECK_FUNCS([shm_open shm_unlink]) LIBS="$save_LIBS" +AC_ARG_WITH([__thread], + AC_HELP_STRING([--without-__thread], + [do not use TLS features (allows for dlopen'ing Xenomai libs)]), + [use__thread=$withval], + [use__thread=yes]) + +dnl Check whether the compiler supports the __thread keyword. +if test "x$use__thread" != xno; then + AC_CACHE_CHECK([for __thread], libc_cv_gcc___thread, + [cat > conftest.c <<\EOF +__thread int a __attribute__ ((tls_model ("initial-exec"))) = 42; +EOF + if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -c -Werror conftest.c >&AS_MESSAGE_LOG_FD]); then + libc_cv_gcc___thread=yes + else + libc_cv_gcc___thread=no + fi + rm -f conftest*]) + if test "$libc_cv_gcc___thread" = yes; then + AC_DEFINE(HAVE___THREAD,1,[config]) + fi +fi + dnl dnl Build the Makefiles dnl Index: b/include/asm-generic/bits/bind.h === --- a/include/asm-generic/bits/bind.h +++ b/include/asm-generic/bits/bind.h @@ -11,26 +11,26 @@ #include #include #include +#include #include +#ifdef HAVE___THREAD +__thread xnhandle_t xeno_current __attribute__ ((tls_model ("initial-exec"))) = + XN_NO_HANDLE; + +static inline void __xeno_set_current(xnhandle_t current) +{ + xeno_current = current; +} +#else /* !HAVE___THREAD */ __attribute__ ((weak)) pthread_key_t xeno_current_key; __attribute__ ((weak)) pthread_once_t xeno_init_current_key_once = PTHREAD_ONCE_INIT; -__attribute__ ((weak)) -void xeno_set_current(void) +static inline void __xeno_set_current(xnhandle_t current) { - void *kthread_cb; - int err; - - err = XENOMAI_SYSCALL1(__xn_sys_current, &kthread_cb); - if (err) { - fprintf(stderr, "Xenomai: error obtaining handle for current " - "thread: %s\n", strerror(err)); - exit(1); - } - pthread_setspecific(xeno_current_key, kthread_cb); + pthread_setspecific(xeno_current_key, (void *)current); } static void init_current_key(void) @@ -42,6 +42,22 @@ static void init_current_key(void) exit(1); } } +#endif /* !HAVE___THREAD */ + +__attribute__ ((weak)) +void xeno_set_current(void) +{ + xnhandle_t current; + int err; + + err = XENOMAI_SYSCALL1(__xn_sys_current, ¤t); + if (err) { + fprintf(stderr, "Xenomai: error obtaining handle for current " + "thread: %s\n", strerror(err)); + exit(1); + } + __xeno_set_current(current); +} #ifdef CONFIG_XENO_FASTSYNCH __attribute__ ((weak)) @@ -175,7 +191,9 @@ xeno_bind_skin(unsigned skin_magic, cons sa.sa_flags = 0; sigaction(SIGXCPU, &sa, NULL); +#ifndef HAVE___THREAD pthread_once(&xeno_init_current_key_once, &init_current_key); +#endif /* !HAVE___THREAD */ #ifdef CONFIG_XENO_FASTSYNCH /* In case we forked, we need to map the new local semaphore heap */ @@ -251,7 +269,9 @@ xeno_bind_skin_opt(unsigned skin_magic, xeno_arch_features_check(); #endif /* xeno_arch_features_check */ +#ifndef HAVE___THREAD pthread_once(&xeno_init_current_key_once, &init_current_key); +#endif /* !HAVE
[Xenomai-core] [PATCH 10/12] Report current shadow thread mode to user space
With this patch applied, the Xenomai skin libraries are able to obtain the execution mode the current thread without issuing a syscall. The kernel-user interface looks as follows: - On thread creation (which triggers xnshadow_map), user space passes a pointer to an unsigned long. - Before going primary and after completing the switch to secondary mode, the nucleus writes 0 or XNRELAX to that unsigned long. The mode updates use __xn_put_user, so they are fail-safe (write errors are ignored, only an initial access_wok check is reported back). - User space can check its state by calling xeno_get_current_mode(). An optional light-weight version based on __thread is also provided. Signed-off-by: Jan Kiszka <[EMAIL PROTECTED]> --- include/asm-generic/bits/bind.h| 29 + include/asm-generic/bits/current.h | 20 include/native/syscall.h |1 + include/nucleus/shadow.h |3 ++- include/nucleus/thread.h |4 include/psos+/syscall.h|8 include/vrtx/syscall.h |1 + include/vxworks/syscall.h |1 + ksrc/nucleus/shadow.c | 22 -- ksrc/skins/native/syscall.c|3 ++- ksrc/skins/posix/syscall.c | 14 +- ksrc/skins/psos+/syscall.c | 34 +- ksrc/skins/uitron/syscall.c|8 ++-- ksrc/skins/vrtx/syscall.c |4 +++- ksrc/skins/vxworks/syscall.c |4 +++- src/skins/native/task.c| 10 ++ src/skins/posix/thread.c | 33 +++-- src/skins/psos+/task.c | 16 +--- src/skins/uitron/task.c| 11 +-- src/skins/vrtx/task.c |6 ++ src/skins/vxworks/taskLib.c|6 ++ 21 files changed, 201 insertions(+), 37 deletions(-) Index: b/include/native/syscall.h === --- a/include/native/syscall.h +++ b/include/native/syscall.h @@ -134,6 +134,7 @@ struct rt_arg_bulk { u_long a3; u_long a4; u_long a5; + u_long a6; }; #ifdef __KERNEL__ Index: b/include/nucleus/shadow.h === --- a/include/nucleus/shadow.h +++ b/include/nucleus/shadow.h @@ -69,7 +69,8 @@ void xnshadow_grab_events(void); void xnshadow_release_events(void); int xnshadow_map(struct xnthread *thread, -xncompletion_t __user *u_completion); +xncompletion_t __user *u_completion, +unsigned long __user *u_mode); void xnshadow_unmap(struct xnthread *thread); Index: b/include/nucleus/thread.h === --- a/include/nucleus/thread.h +++ b/include/nucleus/thread.h @@ -248,6 +248,10 @@ typedef struct xnthread { void *cookie; /* Cookie to pass to the entry routine */ +#ifdef CONFIG_XENO_OPT_PERVASIVE + unsigned long __user *u_mode; /* Thread mode variable in userland. */ +#endif /* CONFIG_XENO_OPT_PERVASIVE */ + XNARCH_DECL_DISPLAY_CONTEXT(); } xnthread_t; Index: b/ksrc/nucleus/shadow.c === --- a/ksrc/nucleus/shadow.c +++ b/ksrc/nucleus/shadow.c @@ -1079,6 +1079,8 @@ redo: /* Grab the request token. */ return -ERESTARTSYS; + __xn_put_user(0, thread->u_mode); + preempt_disable(); /* Assume that we might have been migrated while waiting for @@ -1250,6 +1252,8 @@ void xnshadow_relax(int notify) /* "current" is now running into the Linux domain on behalf of the root thread. */ + __xn_put_user(XNRELAX, thread->u_mode); + trace_mark(xn_nucleus_shadow_relaxed, "thread %p thread_name %s comm %s", thread, xnthread_name(thread), current->comm); @@ -1264,7 +1268,9 @@ void xnshadow_exit(void) } /*! - * \fn int xnshadow_map(xnthread_t *thread, xncompletion_t __user *u_completion) + * \fn int xnshadow_map(xnthread_t *thread, + * xncompletion_t __user *u_completion, + * unsigned long __user *u_mode) * @internal * \brief Create a shadow thread context. * @@ -1288,6 +1294,11 @@ void xnshadow_exit(void) * immediately started and "current" immediately resumes in the Xenomai * domain from this service. * + * @param: u_mode is the address of a mode variable in user space that + * will reflect the current thread mode (primary or secondary). The + * nucleus will try to update the variable before switching to secondary + * or after switching from primary mode. + * * @return 0 is returned on success. Otherwise: * * - -ERESTARTSYS is returned if the current Linux task has received a @@ -1313,7 +1324,8 @@ void xn
[Xenomai-core] [PATCH 04/12] Spread xeno_set_current under all skins
Spread xeno_set_current under all user space supporting skins. Signed-off-by: Jan Kiszka <[EMAIL PROTECTED]> --- src/skins/native/task.c | 13 +++-- src/skins/psos+/task.c | 18 ++ src/skins/uitron/task.c | 18 +- src/skins/vrtx/task.c |3 +++ src/skins/vxworks/taskLib.c |3 +++ 5 files changed, 44 insertions(+), 11 deletions(-) Index: b/src/skins/native/task.c === --- a/src/skins/native/task.c +++ b/src/skins/native/task.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "wrappers.h" extern pthread_key_t __native_tskey; @@ -88,6 +89,8 @@ static void *rt_task_trampoline(void *co if (err) goto fail; + xeno_set_current(); + /* Wait on the barrier for the task to be started. The barrier could be released in order to process Linux signals while the Xenomai shadow is still dormant; in such a case, resume wait. */ @@ -169,6 +172,7 @@ int rt_task_shadow(RT_TASK *task, const struct sched_param param; struct rt_arg_bulk bulk; RT_TASK task_desc; + int err; if (task == NULL) task = &task_desc; /* Discarded. */ @@ -191,8 +195,13 @@ int rt_task_shadow(RT_TASK *task, const bulk.a4 = (u_long)mode; bulk.a5 = (u_long)pthread_self(); - return XENOMAI_SKINCALL2(__native_muxid, __native_task_create, &bulk, -NULL); + err = XENOMAI_SKINCALL2(__native_muxid, __native_task_create, &bulk, + NULL); + + if (!err) + xeno_set_current(); + + return err; } int rt_task_bind(RT_TASK *task, const char *name, RTIME timeout) Index: b/src/skins/psos+/task.c === --- a/src/skins/psos+/task.c +++ b/src/skins/psos+/task.c @@ -26,6 +26,7 @@ #include #include #include +#include extern int __psos_muxid; @@ -89,6 +90,8 @@ static void *psos_task_trampoline(void * if (err) goto fail; + xeno_set_current(); + /* Wait on the barrier for the task to be started. The barrier could be released in order to process Linux signals while the Xenomai shadow is still dormant; in such a case, resume wait. */ @@ -173,14 +176,21 @@ u_long t_shadow(const char *name, /* Xen u_long flags, u_long *tid_r) { + int err; + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); old_sigharden_handler = signal(SIGHARDEN, &psos_task_sigharden); - return XENOMAI_SKINCALL5(__psos_muxid, -__psos_t_create, -name, prio, flags, -tid_r, NULL); + err = XENOMAI_SKINCALL5(__psos_muxid, + __psos_t_create, + name, prio, flags, + tid_r, NULL); + + if (!err) + xeno_set_current(); + + return err; } u_long t_start(u_long tid, Index: b/src/skins/uitron/task.c === --- a/src/skins/uitron/task.c +++ b/src/skins/uitron/task.c @@ -25,6 +25,7 @@ #include #include #include +#include extern int __uitron_muxid; @@ -89,6 +90,8 @@ static void *uitron_task_trampoline(void if (err) goto fail; + xeno_set_current(); + /* iargs->pk_ctsk might not be valid anymore, after our parent was released from the completion sync, so do not dereference this pointer. */ @@ -150,7 +153,7 @@ ER cre_tsk(ID tskid, T_CTSK *pk_ctsk) ER shd_tsk(ID tskid, T_CTSK *pk_ctsk) /* Xenomai extension. */ { struct sched_param param; - int policy; + int policy, err; /* Make sure the POSIX library caches the right priority. */ policy = uitron_task_set_posix_priority(pk_ctsk->itskpri, ¶m); @@ -160,10 +163,15 @@ ER shd_tsk(ID tskid, T_CTSK *pk_ctsk) /* old_sigharden_handler = signal(SIGHARDEN, &uitron_task_sigharden); - return XENOMAI_SKINCALL3(__uitron_muxid, -__uitron_cre_tsk, -tskid, pk_ctsk, -NULL); + err = XENOMAI_SKINCALL3(__uitron_muxid, + __uitron_cre_tsk, + tskid, pk_ctsk, + NULL); + + if (!err) + xeno_set_current(); + + return err; } ER del_tsk(ID tskid) Index: b/src/skins/vrtx/task.c === --- a/src/skins/vrtx/task.c +++ b/src/skins/vrtx/task.c @@ -27,6 +27,7 @@ #include #include #include +#include extern pthread_key_t __vrtx_tske
[Xenomai-core] [PATCH 08/12] Use fast xnsynch with native skin
Implement a fast path for rt_mutex_acquire/release, making use of fast xnsynch services. Just as for the POSIX skin, lock stealing via trylock is sacrificed for a syscall-less user space implementation. Signed-off-by: Jan Kiszka <[EMAIL PROTECTED]> --- include/native/mutex.h | 23 ++- ksrc/skins/native/cond.c| 16 +- ksrc/skins/native/mutex.c | 314 ++-- ksrc/skins/native/syscall.c | 70 +++-- src/skins/native/cond.c | 30 src/skins/native/mutex.c| 102 +- 6 files changed, 398 insertions(+), 157 deletions(-) Index: b/include/native/mutex.h === --- a/include/native/mutex.h +++ b/include/native/mutex.h @@ -32,7 +32,7 @@ struct rt_task; */ typedef struct rt_mutex_info { - int lockcnt;/**< Lock nesting level (> 0 means "locked"). */ + int locked; /**< > 0 if mutex is locked. */ int nwaiters; /**< Number of pending tasks. */ @@ -44,7 +44,15 @@ typedef struct rt_mutex_info { } RT_MUTEX_INFO; typedef struct rt_mutex_placeholder { + xnhandle_t opaque; + +#ifdef CONFIG_XENO_FASTSYNCH + xnarch_atomic_t *fastlock; + + int lockcnt; +#endif /* CONFIG_XENO_FASTSYNCH */ + } RT_MUTEX_PLACEHOLDER; #if (defined(__KERNEL__) || defined(__XENO_SIM__)) && !defined(DOXYGEN_CPP) @@ -54,6 +62,8 @@ typedef struct rt_mutex_placeholder { #define XENO_MUTEX_MAGIC 0x0505 +#define RT_MUTEX_EXPORTED XNSYNCH_SPARE0 /* Mutex registered by name */ + typedef struct __rt_mutex { unsigned magic; /* !< Magic code - must be first */ @@ -74,7 +84,7 @@ typedef struct __rt_mutex { #define rlink2mutex(ln)container_of(ln, RT_MUTEX, rlink) -xnqueue_t *rqueue; /* !< Backpointer to resource queue. */ + xnqueue_t *rqueue; /* !< Backpointer to resource queue. */ } RT_MUTEX; @@ -93,9 +103,8 @@ static inline void __native_mutex_flush_ xeno_flush_rq(RT_MUTEX, rq, mutex); } -int rt_mutex_acquire_inner(RT_MUTEX *mutex, - xntmode_t timeout_mode, - RTIME timeout); +int rt_mutex_acquire_inner(RT_MUTEX *mutex, RTIME timeout, + xntmode_t timeout_mode); #else /* !CONFIG_XENO_OPT_NATIVE_MUTEX */ @@ -138,6 +147,10 @@ static inline int rt_mutex_unbind (RT_MU extern "C" { #endif +int rt_mutex_create_inner(RT_MUTEX *mutex, const char *name, + xnarch_atomic_t *fastlock); +int rt_mutex_delete_inner(RT_MUTEX *mutex); + /* Public interface. */ int rt_mutex_create(RT_MUTEX *mutex, Index: b/ksrc/skins/native/cond.c === --- a/ksrc/skins/native/cond.c +++ b/ksrc/skins/native/cond.c @@ -407,24 +407,26 @@ int rt_cond_wait_inner(RT_COND *cond, RT thread = xnpod_current_thread(); - if (thread != xnsynch_owner(&mutex->synch_base)) { +#ifdef CONFIG_XENO_FASTSYNCH + if (xnsynch_fast_owner_check(mutex->synch_base.fastlock, +xnthread_handle(thread)) != 0) { +#else /* !CONFIG_XENO_FASTSYNCH */ + if (xnsynch_owner(&mutex->synch_base) != thread) { +#endif /* !CONFIG_XENO_FASTSYNCH */ err = -EPERM; goto unlock_and_exit; } /* * We can't use rt_mutex_release since that might reschedule -* before enter xnsynch_sleep_on, hence most of the code is -* duplicated here. +* before enter xnsynch_sleep_on. */ lockcnt = mutex->lockcnt; /* Leave even if mutex is nested */ mutex->lockcnt = 0; - if (xnsynch_release(&mutex->synch_base)) { - mutex->lockcnt = 1; - /* Scheduling deferred */ - } + xnsynch_release(&mutex->synch_base); + /* Scheduling deferred */ xnsynch_sleep_on(&cond->synch_base, timeout, timeout_mode); Index: b/ksrc/skins/native/mutex.c === --- a/ksrc/skins/native/mutex.c +++ b/ksrc/skins/native/mutex.c @@ -57,29 +57,42 @@ static int __mutex_read_proc(char *page, off_t off, int count, int *eof, void *data) { RT_MUTEX *mutex = (RT_MUTEX *)data; +#ifdef CONFIG_XENO_FASTSYNCH + xnhandle_t lock_state; +#endif /* CONFIG_XENO_FASTSYNCH */ + xnthread_t *owner; char *p = page; int len; spl_t s; xnlock_get_irqsave(&nklock, s); - if (xnsynch_owner(&mutex->synch_base) != NULL) { - xnpholder_t *holder; +#ifndef CONFIG_XENO_FASTSYNCH + owner = xnsynch_owner(&mutex->synch_base); +#else /* CONFIG_XENO_FASTSYNCH */ + lock_state = xnarch_atomic_get(mutex->synch_base.fastlock); + + owner = (lock_state == XN_NO_HANDLE) ? NULL : + xnthread_lookup(xnsynch_fast_mask_claim
[Xenomai-core] [PATCH 00/12] Generic fast xnsynch support & more
Here comes a significantly reworked patch series to improve fast mutex support of Xenomai. This approach now introduces a generic fast xnsynch core and converts the existing POSIX implementation over. It also comes with a second user, the Native skin. Additionally, it improves xeno_get_current via a TLS variable and addresses the issue that threads in secondary mode acquiring an uncontended mutex need to be migrated first. At this chance, the TLS optimization is also applied on self-lookups of task handles (Native, VRTX and VxWorks). And I included my SMP-by-default patch for user libs which is highly recommended to reduce the risk of accidental code breakage on SMP with the new mutex code. Jan --- include/asm-generic/atomic.h | 24 - xenomai/README.INSTALL |2 xenomai/configure.in | 45 +- xenomai/include/asm-arm/atomic.h |3 xenomai/include/asm-blackfin/atomic.h |2 xenomai/include/asm-generic/Makefile.am|2 xenomai/include/asm-generic/Makefile.in|2 xenomai/include/asm-generic/bits/bind.h| 82 +++- xenomai/include/asm-generic/bits/current.h | 36 + xenomai/include/asm-generic/features.h | 24 - xenomai/include/asm-ia64/atomic.h |2 xenomai/include/asm-powerpc/atomic.h |2 xenomai/include/asm-x86/atomic.h |2 xenomai/include/native/mutex.h | 23 - xenomai/include/native/syscall.h |1 xenomai/include/nucleus/registry.h |1 xenomai/include/nucleus/shadow.h |3 xenomai/include/nucleus/synch.h| 70 +++ xenomai/include/nucleus/thread.h | 29 + xenomai/include/nucleus/types.h| 13 xenomai/include/psos+/syscall.h|8 xenomai/include/rtdm/rtdm_driver.h |2 xenomai/include/vrtx/syscall.h |1 xenomai/include/vxworks/syscall.h |1 xenomai/ksrc/arch/arm/Kconfig |2 xenomai/ksrc/arch/powerpc/Kconfig |2 xenomai/ksrc/arch/x86/Kconfig |2 xenomai/ksrc/drivers/testing/switchtest.c |2 xenomai/ksrc/nucleus/pipe.c|2 xenomai/ksrc/nucleus/registry.c|4 xenomai/ksrc/nucleus/select.c |2 xenomai/ksrc/nucleus/shadow.c | 38 +- xenomai/ksrc/nucleus/synch.c | 534 - xenomai/ksrc/nucleus/thread.c |2 xenomai/ksrc/skins/native/Kconfig |1 xenomai/ksrc/skins/native/alarm.c |2 xenomai/ksrc/skins/native/buffer.c |4 xenomai/ksrc/skins/native/cond.c | 18 xenomai/ksrc/skins/native/event.c |2 xenomai/ksrc/skins/native/heap.c |2 xenomai/ksrc/skins/native/intr.c |2 xenomai/ksrc/skins/native/mutex.c | 327 ++--- xenomai/ksrc/skins/native/queue.c |2 xenomai/ksrc/skins/native/sem.c|2 xenomai/ksrc/skins/native/syscall.c| 132 +-- xenomai/ksrc/skins/native/task.c | 28 - xenomai/ksrc/skins/posix/Kconfig |1 xenomai/ksrc/skins/posix/cb_lock.h | 21 - xenomai/ksrc/skins/posix/cond.c| 34 - xenomai/ksrc/skins/posix/intr.c|2 xenomai/ksrc/skins/posix/mq.c |4 xenomai/ksrc/skins/posix/mutex.c | 121 -- xenomai/ksrc/skins/posix/mutex.h | 136 +-- xenomai/ksrc/skins/posix/sem.c |2 xenomai/ksrc/skins/posix/syscall.c | 61 +-- xenomai/ksrc/skins/posix/thread.c | 14 xenomai/ksrc/skins/psos+/Kconfig |2 xenomai/ksrc/skins/psos+/event.c |2 xenomai/ksrc/skins/psos+/queue.c |2 xenomai/ksrc/skins/psos+/rn.c |2 xenomai/ksrc/skins/psos+/sem.c |2 xenomai/ksrc/skins/psos+/syscall.c | 53 +- xenomai/ksrc/skins/psos+/task.c| 20 - xenomai/ksrc/skins/rtai/Kconfig|1 xenomai/ksrc/skins/rtai/sem.c | 12 xenomai/ksrc/skins/rtai/task.c | 10 xenomai/ksrc/skins/rtdm/drvlib.c | 27 - xenomai/ksrc/skins/uitron/Kconfig |1 xenomai/ksrc/skins/uitron/flag.c |2 xenomai/ksrc/skins/uitron/mbx.c|3 xenomai/ksrc/skins/uitron/sem.c|3 xenomai/ksrc/skins/uitron/syscall.c|8 xenomai/ksrc/skins/uitron/task.c | 11 xenomai/ksrc/skins/vrtx/Kconfig|2 xenomai/ksrc/skins/vrtx/event.c|2 xenomai/ksrc/skins/vrtx/mb.c |2 xenomai/ksrc/skins/vrtx/mx.c |7 xenomai/ksrc/skins/vrtx/queue.c|2 xenomai/ksrc/skins/vrtx/sem.c |2 xenomai/ksrc/skins/vrtx/syscall.c |4 xenomai/ksrc/skins/vrtx/task.c
[Xenomai-core] [PATCH 03/12] Remove xnarch_atomic_intptr
No more users, no more use cases in sight, let's get rid of it. Signed-off-by: Jan Kiszka <[EMAIL PROTECTED]> --- include/asm-arm/atomic.h|3 --- include/asm-blackfin/atomic.h |2 -- include/asm-generic/Makefile.am |2 +- include/asm-generic/Makefile.in |2 +- include/asm-generic/atomic.h| 24 include/asm-ia64/atomic.h |2 -- include/asm-powerpc/atomic.h|2 -- include/asm-x86/atomic.h|2 -- 8 files changed, 2 insertions(+), 37 deletions(-) Index: b/include/asm-arm/atomic.h === --- a/include/asm-arm/atomic.h +++ b/include/asm-arm/atomic.h @@ -412,9 +412,6 @@ static __inline__ void xnarch_atomic_cle typedef unsigned long atomic_flags_t; -/* Add support for xnarch_atomic_intptr_t */ -#include - #endif /* !_XENO_ASM_ARM_ATOMIC_H */ // vim: ts=4 et sw=4 sts=4 Index: b/include/asm-blackfin/atomic.h === --- a/include/asm-blackfin/atomic.h +++ b/include/asm-blackfin/atomic.h @@ -42,8 +42,6 @@ typedef atomic_t atomic_counter_t; typedef atomic_t xnarch_atomic_t; -#include - #else /* !__KERNEL__ */ #include Index: b/include/asm-generic/Makefile.am === --- a/include/asm-generic/Makefile.am +++ b/include/asm-generic/Makefile.am @@ -1,5 +1,5 @@ includesubdir = $(includedir)/asm-generic -includesub_HEADERS = arith.h atomic.h features.h hal.h syscall.h system.h wrappers.h +includesub_HEADERS = arith.h features.h hal.h syscall.h system.h wrappers.h SUBDIRS = bits Index: b/include/asm-generic/Makefile.in === --- a/include/asm-generic/Makefile.in +++ b/include/asm-generic/Makefile.in @@ -226,7 +226,7 @@ target_vendor = @target_vendor@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ includesubdir = $(includedir)/asm-generic -includesub_HEADERS = arith.h atomic.h features.h hal.h syscall.h system.h wrappers.h +includesub_HEADERS = arith.h features.h hal.h syscall.h system.h wrappers.h SUBDIRS = bits all: all-recursive Index: b/include/asm-generic/atomic.h === --- a/include/asm-generic/atomic.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _XENO_ASM_GENERIC_ATOMIC_H -#define _XENO_ASM_GENERIC_ATOMIC_H - -typedef xnarch_atomic_t xnarch_atomic_intptr_t; - -static inline void *xnarch_atomic_intptr_get(xnarch_atomic_intptr_t *l) -{ -xnarch_atomic_t *v = (xnarch_atomic_t *)l; - -return (void *)xnarch_atomic_get(v); -} - -static inline void xnarch_atomic_intptr_set(xnarch_atomic_intptr_t *l, void *i) -{ -xnarch_atomic_t *v = (xnarch_atomic_t *)l; - -xnarch_atomic_set(v, (long)i); -} - -#define xnarch_atomic_intptr_cmpxchg(l, old, newval) \ -(void *)(xnarch_atomic_cmpxchg((xnarch_atomic_t *)(l), \ - (long)(old), (long)(newval))) - -#endif /* _XENO_ASM_GENERIC_ATOMIC_H */ Index: b/include/asm-ia64/atomic.h === --- a/include/asm-ia64/atomic.h +++ b/include/asm-ia64/atomic.h @@ -71,8 +71,6 @@ static inline void atomic_clear_mask(uns #define xnarch_atomic_cmpxchg(pcounter,old,new) \ cmpxchg((&(pcounter)->counter),(old),(new)) -#include - #else /* !__KERNEL__ */ #include Index: b/include/asm-powerpc/atomic.h === --- a/include/asm-powerpc/atomic.h +++ b/include/asm-powerpc/atomic.h @@ -262,6 +262,4 @@ xnarch_atomic_cmpxchg(xnarch_atomic_t *p typedef unsigned long atomic_flags_t; -#include - #endif /* !_XENO_ASM_POWERPC_ATOMIC_H */ Index: b/include/asm-x86/atomic.h === --- a/include/asm-x86/atomic.h +++ b/include/asm-x86/atomic.h @@ -136,6 +136,4 @@ xnarch_atomic_cmpxchg(xnarch_atomic_t *v #endif /* __KERNEL__ */ -#include - #endif /* !_XENO_ASM_X86_ATOMIC_64_H */ ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 0/2] Fix and improve task/thread inquire services
Gilles Chanteperdrix wrote: > Jan Kiszka wrote: >> This series fixes the issues around rt_task_inquire I posted yesterday. >> Additionally, it introduces an analogous services pthread_inquire_np for >> the POSIX skin. That allows, among other things, to implement test cases >> for the upcoming fast xnsynch/mutex patches. > > Ok. Since this applies only for debugging purpose, and displaying > whether a task is in primary mode may be use badly by users, maybe we > should make this service a shadow syscall, and not export any interface > to use it. This would further avoid duplication between the native and > posix skins. Debugging is not the holy, exclusive business of Xenomai hackers. The inquire services are useful in libraries as well, when you want to check if the caller complies to the call convention ("don't use in primary mode", "caller's priority must not exceed X" or whatever). That said, I'm open for unifying the code, maybe introducing some xnthread_inquire. Jan -- Siemens AG, Corporate Technology, CT SE 2 Corporate Competence Center Embedded Linux ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH 0/2] Fix and improve task/thread inquire services
Jan Kiszka wrote: > This series fixes the issues around rt_task_inquire I posted yesterday. > Additionally, it introduces an analogous services pthread_inquire_np for > the POSIX skin. That allows, among other things, to implement test cases > for the upcoming fast xnsynch/mutex patches. Ok. Since this applies only for debugging purpose, and displaying whether a task is in primary mode may be use badly by users, maybe we should make this service a shadow syscall, and not export any interface to use it. This would further avoid duplication between the native and posix skins. Philippe, what do you think ? -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 0/2] Fix and improve task/thread inquire services
This series fixes the issues around rt_task_inquire I posted yesterday. Additionally, it introduces an analogous services pthread_inquire_np for the POSIX skin. That allows, among other things, to implement test cases for the upcoming fast xnsynch/mutex patches. Jan -- Siemens AG, Corporate Technology, CT SE 2 Corporate Competence Center Embedded Linux ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 2/2] Add pthread_inquire_np service
Almost identically to what rt_task_inquire provides for the native skin, this introduces the pthread_inquire_np extension to the POSIX API. Only supported thread status values are reported back, PTHREAD_PRIMARY included. Signed-off-by: Jan Kiszka <[EMAIL PROTECTED]> --- include/posix/pthread.h| 53 ++ include/posix/syscall.h|1 ksrc/skins/posix/syscall.c | 23 ++ ksrc/skins/posix/thread.c | 56 + src/skins/posix/thread.c |7 + 5 files changed, 135 insertions(+), 5 deletions(-) Index: b/include/posix/pthread.h === --- a/include/posix/pthread.h +++ b/include/posix/pthread.h @@ -135,6 +135,7 @@ typedef struct #include_next #include #include +#include struct timespec; @@ -144,11 +145,31 @@ struct timespec; #define PTHREAD_PRIO_INHERIT 1 #define PTHREAD_PRIO_PROTECT 2 -#define PTHREAD_SHIELD XNSHIELD -#define PTHREAD_WARNSW XNTRAPSW -#define PTHREAD_LOCK_SCHED XNLOCK -#define PTHREAD_RPIOFF XNRPIOFF -#define PTHREAD_PRIMARYXNTHREAD_STATE_SPARE1 +/** + * @ingroup posix + * @defgroup thread_task_status Thread Status + * @brief Defines used to specify thread state and/or mode + * @{ + */ + +#define PTHREAD_SUSP XNSUSP /**< Suspended. */ +#define PTHREAD_BLOCKEDXNPEND /**< Sleep-wait for a resource. */ +#define PTHREAD_DELAYEDXNDELAY /**< Delayed. */ +#define PTHREAD_READY XNREADY /**< Linked to the ready queue. */ +#define PTHREAD_DORMANTXNDORMANT /**< Not started yet or killed. */ +#define PTHREAD_STARTEDXNSTARTED /**< Thread has been started. */ +#define PTHREAD_HELD XNHELD /**< Held thread from suspended partition. */ +#define PTHREAD_BOOST XNBOOST /**< Undergoes a PIP boost. */ +#define PTHREAD_DEBUG XNDEBUG /**< Hit a debugger breakpoint (user space only). */ +#define PTHREAD_LOCK_SCHED XNLOCK /**< Holds the scheduler lock (i.e. not preemptible). */ +#define PTHREAD_RRBXNRRB /**< Undergoes a round-robin scheduling. */ +#define PTHREAD_NOSIG XNASDI /**< ASR are disabled. */ +#define PTHREAD_SHIELD XNSHIELD/**< IRQ shield is enabled (user space only). */ +#define PTHREAD_WARNSW XNTRAPSW/**< Trap execution mode switches. */ +#define PTHREAD_RPIOFF XNRPIOFF/**< Stop priority coupling (user space only). */ +#define PTHREAD_USERSPACE XNSHADOW/**< User space task. */ +#define PTHREAD_PRIMARYXNTHREAD_STATE_SPARE1 /**< Running under Xenomai control (primary mode). */ +/*! @} */ /* Ends doxygen-group thread_task_status */ #define PTHREAD_INOAUTOENA XN_ISR_NOENABLE #define PTHREAD_IPROPAGATE XN_ISR_PROPAGATE @@ -183,6 +204,24 @@ struct pse51_interrupt; typedef struct pse51_interrupt *pthread_intr_t; +/** + * Structure containing thread information useful to users. + * + * @see pthread_inquire_np() + */ +typedef struct { + + int bprio; /**< Base priority. */ + int cprio; /**< Current priority. May change through Priority Inheritance.*/ + unsigned status; /**< Thread status. @see thread_state_flags */ + struct timespec relpoint; /**< Time of next release.*/ + char name[XNOBJECT_NAME_LEN]; /**< Symbolic name assigned at creation. */ + struct timespec exectime; /**< Execution time in primary mode. */ + int modeswitches; /**< Number of primary->secondary mode switches. */ + int ctxswitches; /**< Number of context switches. */ + int pagefaults; /**< Number of triggered page faults. */ +} pthread_info_t; + #if defined(__KERNEL__) || defined(__XENO_SIM__) typedef struct pse51_mutexattr pthread_mutexattr_t; @@ -385,6 +424,8 @@ int pthread_set_mode_np(int clrmask, int pthread_set_name_np(pthread_t thread, const char *name); +int pthread_inquire_np(pthread_t thread, pthread_info_t *info); + int pthread_intr_attach_np(pthread_intr_t *intr, unsigned irq, xnisr_t isr, @@ -429,6 +470,8 @@ int pthread_set_mode_np(int clrmask, int pthread_set_name_np(pthread_t thread, const char *name); +int pthread_inquire_np(pthread_t thread, pthread_info_t *info); + int pthread_intr_attach_np(pthread_intr_t *intr, unsigned irq, int mode); Index: b/include/posix/syscall.h === --- a/include/posix/syscall.h +++ b/include/posix/syscall.h @@ -102,6 +102,7 @@ #define __pse51_thread_getschedparam 75 #define __pse51_thread_kill 76 #define __pse51_select77 +#define __pse51_thread_inquire78 #ifdef __KERNEL__ Index: b/ksrc/skins/posix/syscall.c === --- a/ksrc/skins/posix/syscall.c +++ b/ksrc/
[Xenomai-core] [PATCH 1/2] Fix status values reported by rt_task_inquire
So far rt_task_inquire simply copied the nucleus thread status, leaking lots of undocumented or incorrectly described state values to the user. This patch first of all fixes the T_* documentation, adds further informative states, and then ensures that only those are reported back in RT_TASK_INFO.status. This includes correct reporting of T_PRIMARY and T_JOINABLE. Signed-off-by: Jan Kiszka <[EMAIL PROTECTED]> --- include/native/task.h | 38 +++--- ksrc/skins/native/syscall.c |7 +++ ksrc/skins/native/task.c|5 - 3 files changed, 34 insertions(+), 16 deletions(-) Index: b/include/native/task.h === --- a/include/native/task.h +++ b/include/native/task.h @@ -28,7 +28,6 @@ /* Creation flags. */ #define T_FPU XNFPU -#define T_SUSPXNSUSP /* High bits must not conflict with XNFPU|XNSHADOW|XNSHIELD|XNSUSP. */ #define T_CPU(cpu) (1 << (24 + (cpu & 7))) /* Up to 8 cpus [0-7] */ #define T_CPUMASK 0xff00 @@ -40,22 +39,31 @@ @{ */ -#define T_BLOCKED XNPEND /**< See #XNPEND*/ -#define T_DELAYED XNDELAY/**< See #XNDELAY */ -#define T_READYXNREADY/**< See #XNREADY */ -#define T_DORMANT XNDORMANT /**< See #XNDORMANT */ -#define T_STARTED XNSTARTED /**< See #XNSTARTED */ -#define T_BOOSTXNBOOST/**< See #XNBOOST */ -#define T_LOCK XNLOCK /**< See #XNLOCK*/ -#define T_RRB XNRRB /**< See #XNRRB */ -#define T_NOSIGXNASDI /**< See #XNASDI*/ -#define T_SHIELD XNSHIELD /**< See #XNSHIELD */ -#define T_WARNSW XNTRAPSW /**< See #XNTRAPSW */ -#define T_RPIOFF XNRPIOFF /**< See #XNRPIOFF */ -#define T_PRIMARY 0x0200 /* Recycle internal bits status which */ -#define T_JOINABLE 0x0400 /* won't be passed to the nucleus. */ +#define T_SUSP XNSUSP/**< Suspended. */ +#define T_BLOCKEDXNPEND/**< Sleep-wait for a resource. */ +#define T_DELAYEDXNDELAY /**< Delayed. */ +#define T_READY XNREADY /**< Linked to the ready queue. */ +#define T_DORMANTXNDORMANT /**< Not started yet or killed. */ +#define T_STARTEDXNSTARTED /**< Thread has been started. */ +/* Reuses XNRELAX flag, but invertedly. */ +#define T_PRIMARY0x0200/**< Running under Xenomai control (primary mode). */ +#define T_HELD XNHELD/**< Held thread from suspended partition. */ +#define T_BOOST XNBOOST /**< Undergoes a PIP boost. */ +#define T_DEBUG XNDEBUG /**< Hit a debugger breakpoint (user space only). */ +#define T_LOCK XNLOCK/**< Holds the scheduler lock (i.e. not preemptible). */ +#define T_RRBXNRRB /**< Undergoes a round-robin scheduling. */ +#define T_NOSIG XNASDI/**< ASR are disabled. */ +#define T_SHIELD XNSHIELD /**< IRQ shield is enabled (user space only). */ +#define T_WARNSW XNTRAPSW /**< Trap execution mode switches. */ +#define T_RPIOFF XNRPIOFF /**< Stop priority coupling (user space only). */ +#define T_USERSPACE XNSHADOW /**< User space task. */ +/* Reuses XNROOT (ROOT is not an addressable task). */ +#define T_JOINABLE 0x0040/**< Task electable for rt_task_join. */ /*! @} */ /* Ends doxygen-group native_task_status */ +/* Used to save the T_JOINABLE state after initialization. */ +#define __T_JOINABLE XNTHREAD_INFO_SPARE0 + /* Task hook types. */ #define T_HOOK_START XNHOOK_THREAD_START #define T_HOOK_SWITCH XNHOOK_THREAD_SWITCH Index: b/ksrc/skins/native/syscall.c === --- a/ksrc/skins/native/syscall.c +++ b/ksrc/skins/native/syscall.c @@ -159,6 +159,8 @@ static int __rt_task_create(struct pt_re prio = bulk.a3; /* Task init mode & CPU affinity. */ mode = bulk.a4 & (T_CPUMASK | T_SUSP | T_SHIELD); + if (bulk.a4 & T_JOINABLE) + mode |= __T_JOINABLE; task = (RT_TASK *)xnmalloc(sizeof(*task)); @@ -516,6 +518,11 @@ static int __rt_task_inquire(struct pt_r if (err) return err; + if (info.status & __T_JOINABLE) { + info.status &= ~__T_JOINABLE; + info.status |= T_JOINABLE; + } + if (__xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs), &info, sizeof(info))) return -EFAULT; Index: b/ksrc/skins/native/task.c === --- a/ksrc/skins/native/task.c +++ b/ksrc/skins/native/task.c @@ -1129,7 +1129,10 @@ int rt_task_inquire(RT_TASK *task, RT_TA strcpy(info->name, xnthread_name(&task->thread_base)); info->bprio = xnthread_base_priority(&task->thread_base); info->cprio = xnthread_current_priority(&task->thread_base); - info->status = xnthread_state_flags(&task->thread_base); + info->status = xnthread_state_flags(&task->thread_base) &