URI: 
       tdevdraw: use global drawlk instead of per-client - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 587933c16132d880a06ff99bd087e64a3a04975e
   DIR parent 94d381ec9d579e5336f3817b68cf4d1a8a7333db
  HTML Author: Russ Cox <rsc@swtch.com>
       Date:   Sat, 25 Jan 2020 14:33:20 -0500
       
       devdraw: use global drawlk instead of per-client
       
       Setting up for a real window system.
       
       Diffstat:
         M src/cmd/devdraw/devdraw.c           |      26 ++++++++++++++------------
         M src/cmd/devdraw/devdraw.h           |       5 +++--
         M src/cmd/devdraw/mac-screen.m        |       7 +++----
       
       3 files changed, 20 insertions(+), 18 deletions(-)
       ---
   DIR diff --git a/src/cmd/devdraw/devdraw.c b/src/cmd/devdraw/devdraw.c
       t@@ -14,6 +14,8 @@
        #include <drawfcall.h>
        #include "devdraw.h"
        
       +QLock        drawlk;
       +
        static        int                drawuninstall(Client*, int);
        static        Memimage*        drawinstall(Client*, int, Memimage*, DScreen*);
        static        void                drawfreedimage(Client*, DImage*);
       t@@ -47,14 +49,14 @@ gfx_replacescreenimage(Client *c, Memimage *m)
                 */
                Memimage *om;
        
       -        qlock(&c->drawlk);
       +        qlock(&drawlk);
                om = c->screenimage;
                c->screenimage = m;
                m->screenref = 1;
                if(om && --om->screenref == 0){
                        _freememimage(om);
                }
       -        qunlock(&c->drawlk);
       +        qunlock(&drawlk);
                gfx_mouseresized(c);
        }
        
       t@@ -142,9 +144,9 @@ addflush(Client *c, Rectangle r)
                        // and gfx thread might be blocked on drawlk trying to install a new screen
                        // during a resize.
                        rpc_gfxdrawunlock();
       -                qunlock(&c->drawlk);
       +                qunlock(&drawlk);
                        c->impl->rpc_flush(c, fr);
       -                qlock(&c->drawlk);
       +                qlock(&drawlk);
                        rpc_gfxdrawlock();
                }
        }
       t@@ -187,9 +189,9 @@ drawflush(Client *c)
                        // and gfx thread might be blocked on drawlk trying to install a new screen
                        // during a resize.
                        rpc_gfxdrawunlock();
       -                qunlock(&c->drawlk);
       +                qunlock(&drawlk);
                        c->impl->rpc_flush(c, r);
       -                qlock(&c->drawlk);
       +                qlock(&drawlk);
                        rpc_gfxdrawlock();
                }
        }
       t@@ -614,7 +616,7 @@ drawcoord(uchar *p, uchar *maxp, int oldx, int *newx)
        int
        draw_dataread(Client *cl, void *a, int n)
        {
       -        qlock(&cl->drawlk);
       +        qlock(&drawlk);
                if(cl->readdata == nil){
                        werrstr("no draw data");
                        goto err;
       t@@ -627,11 +629,11 @@ draw_dataread(Client *cl, void *a, int n)
                memmove(a, cl->readdata, cl->nreaddata);
                free(cl->readdata);
                cl->readdata = nil;
       -        qunlock(&cl->drawlk);
       +        qunlock(&drawlk);
                return n;
        
        err:
       -        qunlock(&cl->drawlk);
       +        qunlock(&drawlk);
                return -1;
        }
        
       t@@ -656,7 +658,7 @@ draw_datawrite(Client *client, void *v, int n)
                Refreshfn reffn;
                Refx *refx;
        
       -        qlock(&client->drawlk);
       +        qlock(&drawlk);
                rpc_gfxdrawlock();
                a = v;
                m = 0;
       t@@ -1431,7 +1433,7 @@ draw_datawrite(Client *client, void *v, int n)
                        }
                }
                rpc_gfxdrawunlock();
       -        qunlock(&client->drawlk);
       +        qunlock(&drawlk);
                return oldn - n;
        
        Enodrawimage:
       t@@ -1502,6 +1504,6 @@ Ebadarg:
        error:
                werrstr("%s", err);
                rpc_gfxdrawunlock();
       -        qunlock(&client->drawlk);
       +        qunlock(&drawlk);
                return -1;
        }
   DIR diff --git a/src/cmd/devdraw/devdraw.h b/src/cmd/devdraw/devdraw.h
       t@@ -56,6 +56,8 @@ struct ClientImpl
                void (*rpc_flush)(Client*, Rectangle);
        };
        
       +extern QLock drawlk;
       +
        struct Client
        {
                int                rfd;
       t@@ -69,10 +71,9 @@ struct Client
        
                char*        wsysid;
        
       -        // drawlk protects the draw data structures.
       +        // drawlk protects the draw data structures for all clients.
                // It can be acquired by an RPC thread or a graphics thread
                // but must not be held on one thread while waiting for the other.
       -        QLock        drawlk;
                /*Ref                r;*/
                DImage*                dimage[NHASH];
                CScreen*        cscreen;
   DIR diff --git a/src/cmd/devdraw/mac-screen.m b/src/cmd/devdraw/mac-screen.m
       t@@ -39,7 +39,6 @@ static uint msec(void);
        
        static void        rpc_resizeimg(Client*);
        static void        rpc_resizewindow(Client*, Rectangle);
       -static void        rpc_serve(Client*);
        static void        rpc_setcursor(Client*, Cursor*, Cursor2*);
        static void        rpc_setlabel(Client*, char*);
        static void        rpc_setmouse(Client*, Point);
       t@@ -496,17 +495,17 @@ rpc_flush(Client *client, Rectangle r)
                        if(!rectclip(&r, Rect(0, 0, self.dlayer.texture.width, self.dlayer.texture.height)) || !rectclip(&r, self.img->r))
                                return;
        
       -                // self.client->drawlk protects the pixel data in self.img.
       +                // drawlk protects the pixel data in self.img.
                        // In addition to avoiding a technical data race,
                        // the lock avoids drawing partial updates, which makes
                        // animations like sweeping windows much less flickery.
       -                qlock(&self.client->drawlk);
       +                qlock(&drawlk);
                        [self.dlayer.texture
                                replaceRegion:MTLRegionMake2D(r.min.x, r.min.y, Dx(r), Dy(r))
                                mipmapLevel:0
                                withBytes:byteaddr(self.img, Pt(r.min.x, r.min.y))
                                bytesPerRow:self.img->width*sizeof(u32int)];
       -                qunlock(&self.client->drawlk);
       +                qunlock(&drawlk);
        
                        NSRect nr = NSMakeRect(r.min.x, r.min.y, Dx(r), Dy(r));
                        dispatch_time_t time;