I’m in the process of porting a Linux device driver to a QNX resource manager. So far it’s been fairly straight forward, but I’ve run into one snag.
The driver uses ioctl functions for a bunch of low level commands, some of which block. I really need the resource manager to allow multiple threads to all execute ioctl functions on the driver concurrently.
I had assumed that writing a multi-threaded resource manager would do the trick, but it seems that only one thread can make an ioctl call at a time. That is, one thread does an ioctl that blocks, then if another thread tries to make an ioctl call to the resource manager I never see it.
Am I missing something obvious here? Is the resource manager doing some sort of locking on the ioctl function to prevent multiple threads from calling it concurrently? Any simple workarounds? Is this documented anywhere?
as far as I remember there is no such restriction in number of threads that can be created at any point of time in QNX and I have worked on it already so can assure you on this.
do you have any fork call in your driver code. why I asked because QNX does not support fork after thread creation. for clarifying your doubt I can suggeest an easier alternate. Write a small module for thread creation and inside thread / after creation of thread you give a ioctl call and see the results.
Attributes are protected. Look it up in the documentation under “attribute structures”. Read up on variable lock_tid and lock_count
Yup, my problem is that the attribute structure is locked. If I check the lock_count when the ioctl function is called, I see it’s set to 1.
I’m a little confused why the attributes structure would be locked during this call. This would definitely prevent another thread in my pool from calling any function which locks the attributes structure. Kind of defeats the purpose of writing a multi-threaded resource manager.
Does anyone know exactly which calls will be made with the attributes structure locked? Any way to prevent this locking?
One quick work around that I just tried was to unlock the attributes structure on entry to my ioctl call, then lock it again before returning. This seems to work, but makes me a little nervous; I would expect the attributes structure was locked for some reason and am therefore reluctant to unlock it without fully understanding the implications. Do you think this is a safe way to operate?
It depends on what you do with the attributes and in the callback. It’s all about being thread safes. If the way you deal with the attributes content is safe, then you should be ok.
Threading inside a resmgr is most useful when dealing with multiple attributes The idea is that an attribute should define a single entity (a serial port, an io port, etc) and dealing with a single entity with multiple thread usually requires locking.
OK, thanks for the feedback.
Since the driver I’m porting is thread safe I’ll go ahead and unlock the attributes. I don’t actually do anything with the attributes structure myself within the driver code.
Thanks for the help Mario.