From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-AntiVirus: Checked by Dr.Web [version: 4.33, engine: 4.33.0.10250, virus records: 125225, updated: 16.05.2006] Date: Mon, 19 Jun 2006 09:20:20 +0000 From: gosha X-Mailer: The Bat! (v3.5) UNREG / CD5BF9353B3B7091 Organization: cdbtm X-Priority: 3 (Normal) Message-ID: <1601758466.20060619092020@nm.ru> To: "devel-kernel-request@lists.altlinux.org" In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset=koi8-r Content-Transfer-Encoding: 8bit Subject: Re: [d-kernel] =?koi8-r?b?Lc7Fzc7Px88gzsXEz9DPztHMLCAtIPcga2VybmVs?= =?koi8-r?b?IDIuNi4xNiDUxdDF0tgg1sTV3cnFICDCzM/LydLP18vJIHNwaW5s?= =?koi8-r?b?b2NrKCkgIM7FINLBws/UwcDUP10gKFNlcmdleSBWbGFzb3Yp?= X-BeenThere: devel-kernel@lists.altlinux.org X-Mailman-Version: 2.1.7 Precedence: list Reply-To: gosha , ALT Linux kernel packages development List-Id: ALT Linux kernel packages development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 19 Jun 2006 05:16:46 -0000 Archived-At: List-Archive: List-Post: Здравствуйте. >Значит, этот тест был выполнен на ядре *-up, где spin_lock() >действительно ничего не делает. Spinlock используются только на SMP >для синхронизации между несколькими процессорами. Код, пытающийся >рекурсивно захватить один и тот же spinlock на одном процессоре, >недопустим - это гарантированный deadlock. > И в include/linux/spinlock*.h ничего похожего на разблокировку/ блокировку .... >Все реализации spinlock архитектурно-зависимые, и поэтому лежат в >include/asm-*. фрагмент include/linux/spinlock.h : ------------------------------------------------------- #if defined(CONFIG_SMP) # include // прикомпилируются только в случае многопроцессорных систем #else # include #endif ------------------------------------------------------- фрагмент include/linux/compiler.h : ------------------------------------------------------- #ifdef __CHECKER__ .................... # define __acquire(x) __context__(1) # define __release(x) __context__(-1) #else .......................... # define __acquire(x) (void)0 # define __release(x) (void)0 #endif ------------------------------------------------------- фрагмент include/linux/spinlock_api.h: ------------------------------------------------------- #define __LOCK(lock) do { preempt_disable(); __acquire(lock); (void)(lock); } while (0) #define __UNLOCK(lock) do { preempt_enable(); __release(lock); (void)(lock); } while (0) #define _spin_lock(lock) __LOCK(lock) #define _spin_unlock(lock) __UNLOCK(lock) ------------------------------------------------------- Т.е. для однопроцессорных систем ждущие блокировки spinlock() и не должны ничего делать в принципе?? Судя по коду это так, но это как бы нелогично... Напр касок кода /kernel/irq/hahdle.c : ------------------------------------------------------- /* do_IRQ handles all normal device IRQ's (the special SMP cross-CPU interrupts have their own specific handlers). */ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs) { irq_desc_t *desc = irq_desc + irq; struct irqaction * action; unsigned int status; kstat_this_cpu.irqs[irq]++; if (CHECK_IRQ_PER_CPU(desc->status)) { irqreturn_t action_ret; /* No locking required for CPU-local interrupts: */ if (desc->handler->ack) desc->handler->ack(irq); action_ret = handle_IRQ_event(irq, regs, desc->action); desc->handler->end(irq); return 1; } spin_lock(&desc->lock); if (desc->handler->ack) desc->handler->ack(irq); /* * REPLAY is when Linux resends an IRQ that was dropped earlier * WAITING is used by probe to mark irqs that are being tested */ status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING); status |= IRQ_PENDING; /* we _want_ to handle it */ /* * If the IRQ is disabled for whatever reason, we cannot * use the action we have. */ action = NULL; if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) { action = desc->action; status &= ~IRQ_PENDING; /* we commit to handling */ status |= IRQ_INPROGRESS; /* we are handling it */ } desc->status = status; /* * If there is no IRQ handler or it was disabled, exit early. * Since we set PENDING, if another processor is handling * a different instance of this same irq, the other processor * will take care of it. */ if (unlikely(!action)) goto out; /* * Edge triggered interrupts need to remember * pending events. * This applies to any hw interrupts that allow a second * instance of the same irq to arrive while we are in do_IRQ * or in the handler. But the code here only handles the _second_ * instance of the irq, not the third or fourth. So it is mostly * useful for irq hardware that does not mask cleanly in an * SMP environment. */ for (;;) { irqreturn_t action_ret; spin_unlock(&desc->lock); action_ret = handle_IRQ_event(irq, regs, action); spin_lock(&desc->lock); if (!noirqdebug) note_interrupt(irq, desc, action_ret, regs); if (likely(!(desc->status & IRQ_PENDING))) break; desc->status &= ~IRQ_PENDING; } desc->status &= ~IRQ_INPROGRESS; out: /* * The ->end() handler has to deal with interrupts which got * disabled while the handler was running. */ desc->handler->end(irq); spin_unlock(&desc->lock); return 1; } --------------------------------------------------------------------------- Также все работает в режиме CONFIG_DEBUG_SPINLOCK : #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) # include #else # include #endif --------------------------------------------------------------------------- Так и должно быть??? У меня во всех книжках по линуксу написано, что это ждущая блокировка и оно должно работать как мутекс! --------------------------------------------------------------------------- -- С Уважением, gosha mailto:embedded@nm.ru