Linux启动过程中init/main.c中的start

#ifndef __LINUX_SMPLOCK_H   #define __LINUX_SMPLOCK_H      #ifdef CONFIG_LOCK_KERNEL   

//判断内核是否支持内核锁
//而s3c2410中arch/arm/configs/s3c2410的Code maturity level options下没有定义,所以lock_kernel()什么也不做

#include <linux/sched.h>   #include <linux/spinlock.h>      #define kernel_locked()     (current->lock_depth >= 0)      extern int __lockfunc __reacquire_kernel_lock(void);   extern void __lockfunc __release_kernel_lock(void);      /*    * Release/re-acquire global kernel lock for the scheduler    */   #define release_kernel_lock(tsk) do {       \       if (unlikely((tsk)->lock_depth >= 0)) \           __release_kernel_lock();    \   } while (0)      /*    * Non-SMP kernels will never block on the kernel lock,    * so we are better off returning a constant zero from    * reacquire_kernel_lock() so that the compiler can see    * it at compile-time.    */   #if defined(CONFIG_SMP) && !defined(CONFIG_PREEMPT_BKL)   # define return_value_on_smp return   #else   # define return_value_on_smp   #endif      static inline int reacquire_kernel_lock(struct task_struct *task)   {       if (unlikely(task->lock_depth >= 0))           return_value_on_smp __reacquire_kernel_lock();       return 0;   }      extern void __lockfunc lock_kernel(void)    __acquires(kernel_lock);   extern void __lockfunc unlock_kernel(void)  __releases(kernel_lock);      #else      #define lock_kernel()               do { } while(0)   #define unlock_kernel()             do { } while(0)   #define release_kernel_lock(task)       do { } while(0)   #define reacquire_kernel_lock(task)     0   #define kernel_locked()             1      #endif /* CONFIG_LOCK_KERNEL */   #endif /* __LINUX_SMPLOCK_H */  

//如果定义了CONFIG_LOCK_KERNEL,则转到下面代码

//判断是使用big kernel semaphore还是big kernel lock
//而s3c2410中arch/arm/configs/s3c2410中没有定义

#ifdef CONFIG_PREEMPT_BKL  //判断是使用big kernel semaphore还是big kernel lock   //而s3c2410中arch/arm/configs/s3c2410中没有定义   /*    * The 'big kernel semaphore'    *    * This mutex is taken and released recursively by lock_kernel()    * and unlock_kernel().  It is transparently dropped and reacquired    * over schedule().  It is used to protect legacy code that hasn't    * been migrated to a proper locking design yet.    *    * Note: code locked by this semaphore will only be serialized against    * other code using the same locking facility. The code guarantees that    * the task remains on the same CPU.    *    * Don't use in new code.    */   static DECLARE_MUTEX(kernel_sem);      /*    * Re-acquire the kernel semaphore.    *    * This function is called with preemption off.    *    * We are executing in schedule() so the code must be extremely careful    * about recursion, both due to the down() and due to the enabling of    * preemption. schedule() will re-check the preemption flag after    * reacquiring the semaphore.    */   int __lockfunc __reacquire_kernel_lock(void)   {       struct task_struct *task = current;       int saved_lock_depth = task->lock_depth;          BUG_ON(saved_lock_depth < 0);          task->lock_depth = -1;       preempt_enable_no_resched();          down(&kernel_sem);          preempt_disable();       task->lock_depth = saved_lock_depth;          return 0;   }      void __lockfunc __release_kernel_lock(void)   {       up(&kernel_sem);   }      /*    * Getting the big kernel semaphore.    */   void __lockfunc lock_kernel(void)   {       struct task_struct *task = current;       int depth = task->lock_depth + 1;          if (likely(!depth))           /*            * No recursion worries - we set up lock_depth _after_            */           down(&kernel_sem);          task->lock_depth = depth;   }      void __lockfunc unlock_kernel(void)   {       struct task_struct *task = current;          BUG_ON(task->lock_depth < 0);          if (likely(--task->lock_depth < 0))           up(&kernel_sem);   }      #else      /*    * The 'big kernel lock'    *    * This spinlock is taken and released recursively by lock_kernel()    * and unlock_kernel().  It is transparently dropped and reacquired    * over schedule().  It is used to protect legacy code that hasn't    * been migrated to a proper locking design yet.    *    * Don't use in new code.    */   static  __cacheline_aligned_in_smp DEFINE_SPINLOCK(kernel_flag);         /*    * Acquire/release the underlying lock from the scheduler.    *    * This is called with preemption disabled, and should    * return an error value if it cannot get the lock and    * TIF_NEED_RESCHED gets set.    *    * If it successfully gets the lock, it should increment    * the preemption count like any spinlock does.    *    * (This works on UP too - _raw_spin_trylock will never    * return false in that case)    */   int __lockfunc __reacquire_kernel_lock(void)   {       while (!_raw_spin_trylock(&kernel_flag)) {           if (test_thread_flag(TIF_NEED_RESCHED))               return -EAGAIN;           cpu_relax();       }       preempt_disable();       return 0;   }      void __lockfunc __release_kernel_lock(void)   {       _raw_spin_unlock(&kernel_flag);       preempt_enable_no_resched();   }      /*    * These are the BKL spinlocks - we try to be polite about preemption.     * If SMP is not on (ie UP preemption), this all goes away because the    * _raw_spin_trylock() will always succeed.    */   #ifdef CONFIG_PREEMPT   

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wypxgz.html