Hi, I want to do protect some of the critical regions in my program.But I can not use something like semaphore.Because I do not need any wait queues.If any task failed to access critical region, it can just return an error.
When I read the source code of the Linux, I found some of the functions use 'lock' field in the assembly language. I can not fully understand how to use this 'lock' field. Could any one give me some tips, or a link address which I can found more details about the protection of cirtical region.
On a single processor system the easiest way to get get exclusive access is to disable interrupts. Of course, this usually can only be used for short intervals. I don't understand your problem with semaphores.
That normally depends on the design rules for the system. In a lot of systems at a lot of points in the code, one is guaranteed that interrupts are disabled at entry so one can safely re-enable them at exit.
Some systems do have critical sections within critical sections, in which case the recursive protocol you hinted at is necessary.
Hi, i do not understand why disable interrupts can get exclusive access.I think disable interrupt just make the external interrupt can not disturb the current process, but other high priority process might preempt the CPU.
If you are using an operating system, consult the documentation for that OS. You might also be asking in the wrong group - there are not many people in the field of embedded programming who don't understand why disabling interrupts will protect a critical region.
A little more information (processor, OS, etc.) would help enormously.
More importantly, it's not the way to do it on x86 - even if you're in ring 0, SMM interrupts are still coming in and can still screw with you (cf: ten zillion emails here about Geode and SMM and realtime and include the word "aargh" in your search...).
In a _single processor system_ the only thing that disturbs the system is the instruction(s) executed. When you disable interrupts you prevent anything outside your program disturbing that sequence, thus maintaining control. Once you have gotten past the point at which you needed the exclusive access, you should restore the interrupt system to the enabled condition. This will normally allow other routines, such as i/o, to work.
Multi_processor systems are more complex.
[mail]: Chuck F (cbfalconer at maineline dot net)
The LOCK prefix doesn't do anything with interrupts, which are an irrelevance because LOCK only works on a single instruction and interrupts can only take effect between instructions. What the LOCK prefix does is to assert control of the system bus and maintain it for the whole duration of the instruction. This is significant if the instruction in question involves more than one memory access.
Consider as an example a shared counter which we need to atomically increment. There are a few steps that need to be taken to do this:
1) Read the value from memory and stash a temporary copy in an internal register.
2) Increment the value.
3) Store the modified value back into memory.
With x86 this can be done in a single instruction so interrupts do not play a significant role. However, we have two memory accesses
- the read and the write - and it is possible for another processor or core wants to increment the value at the same time. If the second core reads the the value after the first has completed step
1) but not step 3) then both cores are using the original unmodified value. The result is that the value has only increased by one after both cores have incremented it.
With the LOCK prefix, the first core will assert control of the bus all through the operation and the second core will not be able to access memory to perform step 1) until the first has compelted step 3). The result is that the second processor is delayed for a bit until the first completes the operation, but the result is guaranteed to be correct after both cores have incremented the value. The lock is automatically released at the end of the relevant instruction.
The "other" processor/core could also be DMA, so if you are using DMA, be careful.
On simple processors with a read/modify/write cycle and memory referenced Increment/Decrement instructions, various synchronization primitives could be created using memory location INC/DECs.
If the processor has some kind of cache, things gets ugly due to the cache coherency issues (write through/write back) or if virtual memory is used, so in practice, simple INC/DEC tricks can not be used and special instructions are needed (such as the LOCK prefix in x86) even with INC/DEC.