Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/broadcom Improve locking and kcondvar usage.



details:   https://anonhg.NetBSD.org/src/rev/b2534517b795
branches:  trunk
changeset: 329075:b2534517b795
user:      skrll <skrll%NetBSD.org@localhost>
date:      Mon May 05 08:13:31 2014 +0000

description:
Improve locking and kcondvar usage.

The "interrupt" lock doesn't need to be a spin mutex as the vchi
completions we're synchronising with are done in thread context.

Don't share the interrupt lock for the msg_sync done synchronisation.

diffstat:

 sys/arch/arm/broadcom/bcm2835_vcaudio.c |  49 +++++++++++++++++++-------------
 1 files changed, 29 insertions(+), 20 deletions(-)

diffs (156 lines):

diff -r 2b98086907a4 -r b2534517b795 sys/arch/arm/broadcom/bcm2835_vcaudio.c
--- a/sys/arch/arm/broadcom/bcm2835_vcaudio.c   Mon May 05 05:55:21 2014 +0000
+++ b/sys/arch/arm/broadcom/bcm2835_vcaudio.c   Mon May 05 08:13:31 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bcm2835_vcaudio.c,v 1.2 2013/04/14 15:11:52 skrll Exp $ */
+/* $NetBSD: bcm2835_vcaudio.c,v 1.3 2014/05/05 08:13:31 skrll Exp $ */
 
 /*-
  * Copyright (c) 2013 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bcm2835_vcaudio.c,v 1.2 2013/04/14 15:11:52 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bcm2835_vcaudio.c,v 1.3 2014/05/05 08:13:31 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -78,7 +78,9 @@
 
        kmutex_t                        sc_lock;
        kmutex_t                        sc_intr_lock;
-       kcondvar_t                      sc_cv;
+
+       kmutex_t                        sc_msglock;
+       kcondvar_t                      sc_msgcv;
 
        struct audio_format             sc_format;
        struct audio_encoding_set       *sc_encodings;
@@ -93,6 +95,7 @@
        void                            *sc_pend;
        int                             sc_pblksize;
 
+       bool                            sc_msgdone;
        int                             sc_success;
 
        VCHI_INSTANCE_T                 sc_instance;
@@ -180,8 +183,10 @@
 
        sc->sc_dev = self;
        mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
-       mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
-       cv_init(&sc->sc_cv, "vcaudiocv");
+       mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_NONE);
+       mutex_init(&sc->sc_msglock, MUTEX_DEFAULT, IPL_NONE);
+       cv_init(&sc->sc_msgcv, "vcaudiocv");
+       sc->sc_success = -1;
        error = workqueue_create(&sc->sc_wq, "vcaudiowq", vcaudio_worker,
            sc, PRI_BIO, IPL_SCHED, WQ_MPSAFE);
        if (error) {
@@ -330,15 +335,17 @@
 
        switch (msg.type) {
        case VC_AUDIO_MSG_TYPE_RESULT:
-               mutex_enter(&sc->sc_intr_lock);
+               mutex_enter(&sc->sc_msglock);
                sc->sc_success = msg.u.result.success;
-               cv_broadcast(&sc->sc_cv);
-               mutex_exit(&sc->sc_intr_lock);
+               sc->sc_msgdone = true;
+               cv_broadcast(&sc->sc_msgcv);
+               mutex_exit(&sc->sc_msglock);
                break;
        case VC_AUDIO_MSG_TYPE_COMPLETE:
                intr = msg.u.complete.callback;
                intrarg = msg.u.complete.cookie;
                if (intr && intrarg) {
+                       mutex_enter(&sc->sc_intr_lock);
                        if (msg.u.complete.count > 0 && msg.u.complete.count <= sc->sc_pblksize) {
                                sc->sc_pbytes += msg.u.complete.count;
                        } else {
@@ -348,11 +355,10 @@
                        }
                        if (sc->sc_pbytes >= sc->sc_pblksize) {
                                sc->sc_pbytes -= sc->sc_pblksize;
-                               mutex_enter(&sc->sc_intr_lock);
                                intr(intrarg);
-                               mutex_exit(&sc->sc_intr_lock);
                                workqueue_enqueue(sc->sc_wq, (struct work *)&sc->sc_work, NULL);
                        }
+                       mutex_exit(&sc->sc_intr_lock);
                }
                break;
        default:
@@ -373,10 +379,11 @@
        mutex_enter(&sc->sc_intr_lock);
        intr = sc->sc_pint;
        intrarg = sc->sc_pintarg;
-       mutex_exit(&sc->sc_intr_lock);
 
-       if (intr == NULL || intrarg == NULL)
+       if (intr == NULL || intrarg == NULL) {
+               mutex_exit(&sc->sc_intr_lock);
                return;
+       }
 
        vchi_service_use(sc->sc_service);
 
@@ -423,7 +430,6 @@
                    VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL);
                if (error) {
                        printf("%s: failed to write (%d)\n", __func__, error);
-                       mutex_exit(&sc->sc_intr_lock);
                        goto done;
                }
        } else {
@@ -442,7 +448,6 @@
            VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL);
        if (error) {
                printf("%s: failed to write (%d)\n", __func__, error);
-               mutex_exit(&sc->sc_intr_lock);
                goto done;
        }
 
@@ -467,6 +472,7 @@
                sc->sc_ppos = 0;
 
 done:
+       mutex_exit(&sc->sc_intr_lock);
        vchi_service_release(sc->sc_service);
 }
 
@@ -475,24 +481,27 @@
 {
        int error = 0;
 
-       mutex_enter(&sc->sc_intr_lock);
+       mutex_enter(&sc->sc_msglock);
+
        sc->sc_success = -1;
+       sc->sc_msgdone = false;
+
        error = vchi_msg_queue(sc->sc_service, msg, msglen,
            VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL);
        if (error) {
                printf("%s: failed to queue message (%d)\n", __func__, error);
                goto done;
        }
-       while (sc->sc_success == -1) {
-               error = cv_wait_sig(&sc->sc_cv, &sc->sc_intr_lock);
+
+       while (!sc->sc_msgdone) {
+               error = cv_wait_sig(&sc->sc_msgcv, &sc->sc_msglock);
                if (error)
                        break;
        }
-       if (sc->sc_success > 0)
+       if (sc->sc_success != 0)
                error = EIO;
-
 done:
-       mutex_exit(&sc->sc_intr_lock);
+       mutex_exit(&sc->sc_msglock);
 
        return error;
 }



Home | Main Index | Thread Index | Old Index