-2

APUE says

We saw another example of an atomic operation when we described the O_CREAT and O_EXCL options for the open function. When both of these options are specified, the open will fail if the file already exists. We also said that the check for the existence of the file and the creation of the file was performed as an atomic operation. If we didn’t have this atomic operation, we might try

if ((fd = open(path, O_WRONLY)) < 0) {
if (errno == ENOENT) {
if ((fd = creat(path, mode)) < 0)
err_sys("creat error");
} else {
err_sys("open error");
}
}

The problem occurs if the file is created by another process between the open and the creat. If the file is created by another process between these two function calls, and if that other process writes something to the file, that data is erased when this creat is executed. Combining the test for existence and the creation into a single atomic operation avoids this problem.

Does the quote make sense only if system call open() is atomic?

More generally, in Linux or any other OS, is every system call an atomic operation?

If not, how can I tell if a system call is atomic or not?

Thanks.

closed as too broad by Jeff Schaller, schily, user88036, Romeo Ninov, JigglyNaga Oct 19 '18 at 10:34

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • I can tell of at least one system call that is not atomic: fsync. fsync can take several seconds to complete and, yet, the system doesn't freeze while it completes its action. (This is a comment and not an answer, because I don't know how to respond other parts of your question like "how can I tell if a system call is not atomic or not?") – Marcelo Oct 18 '18 at 14:26
  • Thanks. What do you mean by "the system doesn't freeze"? – Tim Oct 18 '18 at 14:47
  • It means that while the system call is running the system continues to perform several tasks. – Marcelo Oct 21 '18 at 19:38
  • Does that mean such a system call can't atomic? – Tim Oct 21 '18 at 19:41
  • In my understanding, atomicity, in its widest concept, presuppose that the state of "things" (variables, states, tasks, etc.) don't change while the action executes. If the system continues to execute other tasks, run other threads/processes, etc, then the action is, in principle, not atomic (but, as I said, this is my understanding). – Marcelo Oct 21 '18 at 19:47
1

System calls are usually atomic in the sense that they either succeed or fail. If they fail, they do a "rollback" and have no effect other than returning an error to the caller. They are also atomic in the sense that they try hard not to expose any intermediate state between the initial state and the final state to other threads/processes running on the system. For example, a file is either created or it doesn't exist.

Most of the time this inter-thread (inter-process) atomicity is not really relevant. The call open(path, O_WRONLY) is run independently on different threads, and results in the file being open for writing in the calling thread fully asynchronously to open and close calls on the file in other threads[*]. Because of this I don't see how the sensibility of the quote would depend on the atomicity of the open system call.

[*]In the case of many concurrent open calls the kernel must of course protect its own internal data structures from concurrent update, like for instance the variable counting the number of threads having the file open.

Not the answer you're looking for? Browse other questions tagged or ask your own question.