⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smp.txt

📁 ecos实时嵌入式操作系统
💻 TXT
📖 第 1 页 / 共 2 页
字号:
All existing synchronization mechanisms work as before in an SMPsystem. Additional synchronization mechanisms have been added toprovide explicit synchronization for SMP.A set of functions have been added to the Kernel and device driverAPIs to provide spinlocks:void cyg_spinlock_init( cyg_spinlock_t *lock, cyg_bool_t locked );void cyg_drv_spinlock_init( cyg_spinlock_t *lock, cyg_bool_t locked );void cyg_spinlock_destroy( cyg_spinlock_t *lock );void cyg_drv_spinlock_destroy( cyg_spinlock_t *lock );void cyg_spinlock_spin( cyg_spinlock_t *lock );void cyg_drv_spinlock_spin( cyg_spinlock_t *lock );void cyg_spinlock_clear( cyg_spinlock_t *lock );void cyg_drv_spinlock_clear( cyg_spinlock_t *lock );cyg_bool_t cyg_spinlock_try( cyg_spinlock_t *lock );cyg_bool_t cyg_drv_spinlock_try( cyg_spinlock_t *lock );cyg_bool_t cyg_spinlock_test( cyg_spinlock_t *lock );cyg_bool_t cyg_drv_spinlock_test( cyg_spinlock_t *lock );void cyg_spinlock_spin_intsave( cyg_spinlock_t *lock,                                cyg_addrword_t *istate );void cyg_drv_spinlock_spin_intsave( cyg_spinlock_t *lock,                                    cyg_addrword_t *istate );void cyg_spinlock_clear_intsave( cyg_spinlock_t *lock,                                 cyg_addrword_t istate );void cyg_drv_spinlock_clear_intsave( cyg_spinlock_t *lock,                                     cyg_addrword_t istate );The *_init() functions initialize the lock, to either locked or clear,and the *_destroy() functions destroy the lock. Init() should be calledbefore the lock is used and destroy() should be called when it isfinished with.The *_spin() functions will cause the calling CPU to spin until it canclaim the lock and the *_clear() functions clear the lock so that thenext CPU can claim it. The *_try() functions attempts to claim the lockbut returns false if it cannot. The *_test() functions simply returnthe state of the lock.None of these functions will necessarily block interrupts while theyspin. If the spinlock is only to be used between threads on differentCPUs, or in circumstances where it is known that the relevantinterrupts are disabled, then these functions will suffice. However,if the spinlock is also to be used from an ISR, which may be called atany point, a straightforward spinlock may result in deadlock. Hencethe *_intsave() variants are supplied to disable interrupts while thelock is held.The *_spin_intsave() function disables interrupts, saving the currentstate in *istate, and then claims the lock. The *_clear_intsave()function clears the spinlock and restores the interrupt enable statefrom *istate.HAL Support-----------SMP support in any platform depends on the HAL supplying theappropriate operations. All HAL SMP support is defined in thehal_smp.h header (and if necessary var_smp.h and plf_smp.h).SMP support falls into a number of functional groups.CPU Control~~~~~~~~~~~This group consists of descriptive and control macros for managing theCPUs in an SMP system.HAL_SMP_CPU_TYPE	A type that can contain a CPU id. A CPU id is			usually a small integer that is used to index			arrays of variables that are managed on an			per-CPU basis.HAL_SMP_CPU_MAX		The maximum number of CPUs that can be			supported. This is used to provide the size of			any arrays that have an element per CPU.HAL_SMP_CPU_COUNT()	Returns the number of CPUs currently			operational. This may differ from			HAL_SMP_CPU_MAX depending on the runtime			environment.HAL_SMP_CPU_THIS()	Returns the CPU id of the current CPU.HAL_SMP_CPU_NONE	A value that does not match any real CPU			id. This is uses where a CPU type variable			must be set to a nul value.HAL_SMP_CPU_START( cpu )		        Starts the given CPU executing at a defined		        HAL entry point. After performing any HAL		        level initialization, the CPU calls up into		        the kernel at cyg_kernel_cpu_startup().HAL_SMP_CPU_RESCHEDULE_INTERRUPT( cpu, wait )			Sends the CPU a reschedule interrupt, and if			_wait_ is non-zero, waits for an			acknowledgment. The interrupted CPU should			call cyg_scheduler_set_need_reschedule() in			its DSR to cause the reschedule to occur.HAL_SMP_CPU_TIMESLICE_INTERRUPT( cpu, wait )			Sends the CPU a timeslice interrupt, and if			_wait_ is non-zero, waits for an			acknowledgment. The interrupted CPU should			call cyg_scheduler_timeslice_cpu() to cause			the timeslice event to be processed.Test-and-set Support~~~~~~~~~~~~~~~~~~~~Test-and-set is the foundation of the SMP synchronizationmechanisms.HAL_TAS_TYPE		The type for all test-and-set variables. The			test-and-set macros only support operations on			a single bit (usually the least significant			bit) of this location. This allows for maximum			flexibility in the implementation.HAL_TAS_SET( tas, oldb )		        Performs a test and set operation on the		        location _tas_. _oldb_ will contain *true* if		        the location was already set, and *false* if		        it was clear.HAL_TAS_CLEAR( tas, oldb )		        Performs a test and clear operation on the		        location _tas_. _oldb_ will contain *true* if		        the location was already set, and *false* if		        it was clear.Spinlocks~~~~~~~~~Spinlocks provide inter-CPU locking. Normally they will be implementedon top of the test-and-set mechanism above, but may also beimplemented by other means if, for example, the hardware has moredirect support for spinlocks.HAL_SPINLOCK_TYPE       The type for all spinlock variables.HAL_SPINLOCK_INIT_CLEAR	A value that may be assigned to a spinlock			variable to initialize it to clear.HAL_SPINLOCK_INIT_SET	A value that may be assigned to a spinlock			variable to initialize it to set.HAL_SPINLOCK_SPIN( lock )		        The caller spins in a busy loop waiting for		        the lock to become clear. It then sets it and		        continues. This is all handled atomically, so		        that there are no race conditions between CPUs.HAL_SPINLOCK_CLEAR( lock )			The caller clears the lock. One of any waiting			spinners will then be able to proceed.HAL_SPINLOCK_TRY( lock, val )		        Attempts to set the lock. The value put in		        _val_ will be *true* if the lock was		        claimed successfully, and *false* if it was		        not.HAL_SPINLOCK_TEST( lock, val )			Tests the current value of the lock. The value			put in _val_ will be *true* if the lock is			claimed and *false* of it is clear.Scheduler Lock~~~~~~~~~~~~~~The scheduler lock is the main protection for all kernel datastructures. By default the kernel implements the scheduler lock itselfusing a spinlock. However, if spinlocks cannot be supported by thehardware, or there is a more efficient implementation available, theHAL may provide macros to implement the scheduler lock.HAL_SMP_SCHEDLOCK_DATA_TYPE			A data type, possibly a structure, that			contains any data items needed by the			scheduler lock implementation. A variable of			this type will be instantiated as a static			member of the Cyg_Scheduler_SchedLock class			and passed to all the following macros.HAL_SMP_SCHEDLOCK_INIT( lock, data )			Initialize the scheduler lock. The _lock_			argument is the scheduler lock counter and the			_data_ argument is a variable of			HAL_SMP_SCHEDLOCK_DATA_TYPE type.HAL_SMP_SCHEDLOCK_INC( lock, data )		        Increment the scheduler lock. The first		        increment of the lock from zero to one for any		        CPU may cause it to wait until the lock is		        zeroed by another CPU. Subsequent increments		        should be less expensive since this CPU		        already holds the lock.			HAL_SMP_SCHEDLOCK_ZERO( lock, data )			Zero the scheduler lock. This operation will			also clear the lock so that other CPUs may			claim it.	HAL_SMP_SCHEDLOCK_SET( lock, data, new )			Set the lock to a different value, in			_new_. This is only called when the lock is			already known to be owned by the current			CPU. It is never called to zero the lock, or			to increment it from zero.Interrupt Routing~~~~~~~~~~~~~~~~~The routing of interrupts to different CPUs is supported by two newinterfaces in hal_intr.h.Once an interrupt has been routed to a new CPU, the existing vectormasking and configuration operations should take account of the CPUrouting. For example, if the operation is not invoked on thedestination CPU itself, then the HAL may need to arrange to transferthe operation to the destination CPU for correct application.HAL_INTERRUPT_SET_CPU( vector, cpu )		       Route the interrupt for the given _vector_ to		       the given _cpu_. HAL_INTERRUPT_GET_CPU( vector, cpu )		       Set _cpu_ to the id of the CPU to which this		       vector is routed.Annex 1 - Pentium SMP Support=============================ECos supports SMP working on Pentium class IA32 CPUs with integratedSMP support. It uses the per-CPU APIC's and the IOAPIC to provide CPUcontrol and identification, and to distribute interrupts. Only PCIinterrupts that map into the ISA interrupt space are currentlysupported. The code relies on the MP Configuration Table supplied bythe BIOS to discover the number of CPUs, IOAPIC location and interruptassignments - hardware based MP configuration discovery isnot currently supported. Inter-CPU interrupts are mapped into interrupt vectors from 64up. Each CPU has its own vector at 64+CPUID.Interrupt delivery is initially configured to deliver all interruptsto the initial CPU. HAL_INTERRUPT_SET_CPU() currently only supportsthe ability to deliver interrupts to specific CPUs, dynamic CPUselection is not currently supported.eCos has only been tested in a dual processor configuration. While thecode has been written to handle an arbitrary number of CPUs, this hasnot been tested.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -