Messages in this thread |  | | Date | Tue, 19 Jun 2001 13:21:43 -0400 (EDT) | | From | "Richard B. Johnson" <> | | Subject | Re: gnu asm help... |
| |
On Tue, 19 Jun 2001, Timur Tabi wrote:
> ** Reply to message from "Petr Vandrovec" <VANDROVE@vc.cvut.cz> on Tue, 19 Jun > 2001 01:36:26 MET-1 > > > > No. Another CPU might increment value between LOCK INCL and > > fetching v->counter. On ia32 architecture you are almost out of > > luck. You can either try building atomic_inc around CMPXCHG, > > using it as conditional store (but CMPXCHG is not available > > on i386), or you can just guard your atomic variable with > > spinlock - but in that case there is no reason for using atomic_t > > at all. > > Oh, I see the problem. You could do something like this: > > cli > mov %0, %%eax > inc %%eax > mov %%eax, %0 > sti > > and then return eax, but that won't work on SMP (whereas the "lock inc" does). > Doing a global cli might work, though.
The Intel book(s) state that an interrupt is not acknowledged until so many clocks (don't remember the number) after a stack operation.
Given this, is an 'attack' by another CPU allowed within this time-frame? If not, you can do:
pushl %ebx movl INPUT_VALUE(%esp), %eax # Get input value movl INPUT_PTR(%esp), %ebx # Get input pointer lock addl %eax,(%ebx) # Add value pushl (%ebx) # Put result on stack popl %eax # Return value in EAX popl %ebx
It may be worth an experiment.
In any event, you can always use a local lock to make these operations atomic.
# Stack offsets VALUE = 0x08 POINTER = 0x0C
.section .data __local_lock: .long 0 .section .text
.global add_atom .type add_atom,@function
add_atom: pushf cli incb (__local_lock) # Set the lock 1: cmpb $1,(__local_lock) jnz 1b pushl %ebx movl VALUE(%esp), %eax movl POINTER(%esp), %ebx addl %eax, (%ebx) movl (%ebx), %eax popl %ebx decb (__local_lock) # Release the lock popf ret
The lock can also be done as:
incb (__local_lock) 1: cmpb $1,(__local_lock) jz 2f repz nop jmp 1b 2:
(maybe) the CPU being locked loops in low-power mode.
Cheers, Dick Johnson
Penguin : Linux version 2.4.1 on an i686 machine (799.53 BogoMips).
"Memory is like gasoline. You use it up when you are running. Of course you get it all back when you reboot..."; Actual explanation obtained from the Micro$oft help desk.
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |