locks.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
- /*
- * SMP locks primitives for building ix86 locks
- * (not yet used).
- *
- * Alan Cox, alan@cymru.net, 1995
- */
-
- /*
- * This would be much easier but far less clear and easy
- * to borrow for other processors if it was just assembler.
- */
- extern __inline__ void prim_spin_lock(struct spinlock *sp)
- {
- int processor=smp_processor_id();
-
- /*
- * Grab the lock bit
- */
-
- while(lock_set_bit(0,&sp->lock))
- {
- /*
- * Failed, but that's cos we own it!
- */
-
- if(sp->cpu==processor)
- {
- sp->users++;
- return 0;
- }
- /*
- * Spin in the cache S state if possible
- */
- while(sp->lock)
- {
- /*
- * Wait for any invalidates to go off
- */
-
- if(smp_invalidate_needed&(1<<processor))
- while(lock_clear_bit(processor,&smp_invalidate_needed))
- local_flush_tlb();
- sp->spins++;
- }
- /*
- * Someone wrote the line, we go 'I' and get
- * the cache entry. Now try to regrab
- */
- }
- sp->users++;sp->cpu=processor;
- return 1;
- }
- /*
- * Release a spin lock
- */
-
- extern __inline__ int prim_spin_unlock(struct spinlock *sp)
- {
- /* This is safe. The decrement is still guarded by the lock. A multilock would
- not be safe this way */
- if(!--sp->users)
- {
- lock_clear_bit(0,&sp->lock);sp->cpu= NO_PROC_ID;
- return 1;
- }
- return 0;
- }
- /*
- * Non blocking lock grab
- */
-
- extern __inline__ int prim_spin_lock_nb(struct spinlock *sp)
- {
- if(lock_set_bit(0,&sp->lock))
- return 0; /* Locked already */
- sp->users++;
- return 1; /* We got the lock */
- }
- /*
- * These wrap the locking primitives up for usage
- */
-
- extern __inline__ void spinlock(struct spinlock *sp)
- {
- if(sp->priority<current->lock_order)
- panic("lock order violation: %s (%d)n", sp->name, current->lock_order);
- if(prim_spin_lock(sp))
- {
- /*
- * We got a new lock. Update the priority chain
- */
- sp->oldpri=current->lock_order;
- current->lock_order=sp->priority;
- }
- }
- extern __inline__ void spinunlock(struct spinlock *sp)
- {
- if(current->lock_order!=sp->priority)
- panic("lock release order violation %s (%d)n", sp->name, current->lock_order);
- if(prim_spin_unlock(sp))
- {
- /*
- * Update the debugging lock priority chain. We dumped
- * our last right to the lock.
- */
- current->lock_order=sp->oldpri;
- }
- }
- extern __inline__ void spintestlock(struct spinlock *sp)
- {
- /*
- * We do no sanity checks, it's legal to optimistically
- * get a lower lock.
- */
- prim_spin_lock_nb(sp);
- }
- extern __inline__ void spintestunlock(struct spinlock *sp)
- {
- /*
- * A testlock doesn't update the lock chain so we
- * must not update it on free
- */
- prim_spin_unlock(sp);
- }