From owner-freebsd-hackers@FreeBSD.ORG Fri Jun 3 17:18:41 2005 Return-Path: X-Original-To: freebsd-hackers@freebsd.org Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2FCEA16A41C for ; Fri, 3 Jun 2005 17:18:41 +0000 (GMT) (envelope-from Maksim.Yevmenkin@savvis.net) Received: from mailgate1b.savvis.net (mailgate1b.savvis.net [216.91.182.6]) by mx1.FreeBSD.org (Postfix) with ESMTP id C7ED643D4C for ; Fri, 3 Jun 2005 17:18:40 +0000 (GMT) (envelope-from Maksim.Yevmenkin@savvis.net) Received: from localhost (localhost.localdomain [127.0.0.1]) by mailgate1b.savvis.net (Postfix) with ESMTP id 5AC073C04B; Fri, 3 Jun 2005 12:18:40 -0500 (CDT) Received: from mailgate1b.savvis.net ([127.0.0.1]) by localhost (mailgate1b.savvis.net [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 11061-01-23; Fri, 3 Jun 2005 12:18:40 -0500 (CDT) Received: from out002.email.savvis.net (out002.apptix.savvis.net [216.91.32.45]) by mailgate1b.savvis.net (Postfix) with ESMTP id 2E4EC3BE25; Fri, 3 Jun 2005 12:18:40 -0500 (CDT) Received: from s228130hz1ew171.apptix-01.savvis.net ([10.146.4.29]) by out002.email.savvis.net with Microsoft SMTPSVC(6.0.3790.211); Fri, 3 Jun 2005 12:18:33 -0500 Received: from [10.254.186.111] ([66.35.239.94]) by s228130hz1ew171.apptix-01.savvis.net with Microsoft SMTPSVC(6.0.3790.211); Fri, 3 Jun 2005 12:18:24 -0500 Message-ID: <42A090DE.8060002@savvis.net> Date: Fri, 03 Jun 2005 10:18:22 -0700 From: Maksim Yevmenkin User-Agent: Mozilla Thunderbird 1.0.2 (X11/20050404) X-Accept-Language: en-us, en MIME-Version: 1.0 To: Norbert Koch References: <000001c5683f$8c7c1e60$4801a8c0@ws-ew-3.W2KDEMIG> In-Reply-To: <000001c5683f$8c7c1e60$4801a8c0@ws-ew-3.W2KDEMIG> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-OriginalArrivalTime: 03 Jun 2005 17:18:24.0268 (UTC) FILETIME=[3F9314C0:01C56860] X-Virus-Scanned: amavisd-new at savvis.net Cc: "Freebsd-Hackers@Freebsd. Org" Subject: Re: synchronization question about /sys/dev/vkbd/vkbd.c X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 03 Jun 2005 17:18:41 -0000 Norbert, > When looking at /sys/dev/vkbd/vkbd.c I found > one thing, that I do not understand. > > There are three places, where a flag TASK is used: > > 1. in vkbd_dev_close(): > > while(state->ks_flag & TASK) VKBD_SLEEP (...); > > 2. in vkbd_dev_write() > > VKBD_LOCK (); > ... > if (!(state->ks_flags & TASK) && task_enqueue(...)) > state->ks_flags |= TASK; > ... > VKBD_UNLOCK (); > > 3. in vkbd_dev_intr() > > ... > /* call intr */ > ... > VKBD_LOCK(); > state->ks_flags &= ~TASK; > wakeup(...); > VKBD_UNLOCK(); > > As I understand: > vkbd_dev_write() writes data into its queue > and wants vkbd_dev_intr() to process the queue. vkbd_dev_intr() is a "interrupt handler". the real keyboard would generate interrupt when keys are pressed/released. vkbd(4) does not have real keyboard. instead, as soon as vkbd_dev_write() puts scancodes into the queue it schedules vkbd_dev_intr() task (to emulate keyboard interrupt). the TASK flag is used to indicate the fact that "intrrupt" is pending and vkbd(4) does not need to schedule one. > My question is: > Is it not possible, that vkbd_dev_intr() could be > interrupted at any position before the VKBD_LOCK() > and then vkbd_dev_write() called? in theory it is possible. > If yes, how should vkbd_dev_write() know, that it should > call task_enqueue(), as TASK is still set? well, i guess it is possible to miss interrupt in this case. also, the scancodes are not lost, they will be processed on next write. i suspect that the vkbd_dev_intr() should be interrupted exactly in between (*kbdsw[kbd->kb_index]->intr)(kbd, NULL); and VKBD_LOCK(state); this is because most/all of intr() keyboard methods have something like while (check_char) { read_char() ... } > Why not always call task_enqueue() unconditionally here > and leave TASK only to synchronize the close call? yes, that could be done. it is also possible to have a callout going few times a second to check if there is a scancodes in the queue and schedule vkbd_dev_intr(). funny that atkbd(4) and ukbd(4) have just this. thanks, max