views:

321

answers:

2
+3  A: 

I think that, technically, devices are not FIFOs, so it's not at all clear that the guarantees you quote are supposed to apply.

Are you concerned about partial writes and reads within a process, or are you actually reading and/or writing the same device from different processes? Assuming the latter, you might be better off implementing a proxy process of some sort. The proxy owns the device exclusively and performs all reads and writes, thus avoiding the multi-process atomicity problem entirely.

In short, I advise not attempting to verify that "reading/writing from this device is actually an atomic operation". It will be difficult to do with confidence, and leave you with an application that is subject to subtle failures if a later version of linux (or different o/s altogether) fails to implement atomicity the way you need.

Dale Hagglund
+1. Trying to infer API guarantees by reading the source code or by running stress tests against the current version sounds like a mistake.
Jason Orendorff
@Dale,Thanks for your reply. In answer to your question there is only a single process reading/writing, but I need to ensure that the read/write occurs without an interruption. That is to say, interrupts, preemption, everything which may interfere is halted for the duration of the write or read operation. I believe the transfer amount is trivially small, 16 bits or a couple factors of 2 close by. I am wary of implementing my own process to arbitrate transactions because I will be adding something which probably has bugs to something which may have bugs. Thank you again for your help.
@JasonThanks for your reply. What do you suggest in that case?
Ok. But, I'm not sure what you mean by "without interruption"? Interrupts and pre-emption can't be disabled (at least without kernel changes). Do you have multiple threads in your process? If no, what's wrong with a standard loop around write that works through the data in whatever chunks are accepted by the driver. If yes, can you create a proxy thread, or alternatively use a mutex to control access to the device. Is there some kind of timing issue with the device your talking to?
Dale Hagglund
When I say "without interruption" I mean precisely that. So no interrupts, no context switches, no pause however brief, or of any kind, for the entire duration of each write or read. There are other threaded applications on the device, but I believe the one using RS485 will be single-threaded. I think the current implementation is as you described - a loop that iterates through chunks of data. There is no timing issue I am aware of - I have merely been tasked with verifying the atomicity of writing to this special device file since it is a non-standard usage scenario on non-standard hardware.
It's very unlikely you can get the sort of extreme atomicity you're talking about (at least without kernel changes and/or a custom rtos). I think even attempting to verify this will be a waste of your time. I'd suggest trying to clarify the real concerns of whoever asked you to do this. Almost certainly, they don't really care about atomicity per se, but about some other higher level issue. The higher-level concern probably has a solution, but the atomicity issue does not, at least as you've defined it.
Dale Hagglund
+1  A: 

I think PIPE_BUF is the right thing. Now, writes of less than PIPE_BUF bytes may not be atomic, but if they aren't it's an OS bug. I suppose you could ask here if an OS has known bugs. But really, if it has a bug like that, it just ought to be immediately fixed.

If you want to write more than PIPE_BUF atomically, I think you're out of luck. I don't think there is any way outside of application coordination and cooperation to make sure that writes of larger sizes happen atomically.

One solution to this problem is to put your own process in front of the device and make sure everybody who wants to write to the device contacts the process and sends the data to it instead. Then you can do whatever makes sense for your application in terms of atomicity guarantees.

Omnifarious
@Omnifarious, thanks for your reply. I checked the definition for PIPE_BUF, it looks like I am well below the threshold with my data structures. I agree with you that I am basically asking about known bugs. I also wonder more so because of the nature of the device I am using. It is easier for me to trust the completeness of the code for a desktop distribution which may be used by millions of people than the same on nonstandard hardware with a tiny customised kernel used by only a few people. Thank you again for your assistance, I appreciate it.