CS multi-threaded and locking.
authorDavid Zhu <yuzhu@cs.berkeley.edu>
Tue, 29 Jul 2014 05:12:42 +0000 (22:12 -0700)
committerDavid Zhu <yuzhu@cs.berkeley.edu>
Sun, 3 Aug 2014 06:55:28 +0000 (23:55 -0700)
Note this is a basic version. Locking is not optimal and uses large
locks over large areas. Fine grained locking should improve the
performance of the CS server significantly. Holding off further
optimization if we are going to write it in GO.

tests/cs.c

index db7135b..29001d4 100644 (file)
@@ -94,8 +94,7 @@ struct Job
        pthread_t thread;
 };
 
-//spinlock_t   joblock;
-int joblock;
+spinpdrlock_t joblock;
 Job    *joblist;
 
 Mlist  *mlist;
@@ -141,8 +140,8 @@ void        cleanmf(Mfile*);
 
 extern void    paralloc(void);
 
-spinlock_t     dblock;         /* mutex on database operations */
-spinlock_t     netlock;        /* mutex for netinit() */
+spinpdrlock_t  dblock;         /* mutex on database operations */
+spinpdrlock_t  netlock;        /* mutex for netinit() */
 
 char   *logfile = "cs";
 char   *paranoiafile = "cs.paranoia";
@@ -188,7 +187,7 @@ Network network[] = {
        { 0 },
 };
 
-spinlock_t ipifclock;
+spinpdrlock_t ipifclock;
 struct ipifc *ipifcs;
 
 char   eaddr[16];              /* ascii ethernet address */
@@ -250,6 +249,10 @@ main(int argc, char *argv[])
        char ext[Maxpath], servefile[Maxpath];
        argv0 = argv[0];
        justsetname = 0;
+  spin_pdr_init(&joblock);
+  spin_pdr_init(&dblock);
+  //spin_pdr_init(&netlock);
+  spin_pdr_init(&ipifclock);
        setnetmtpt(mntpt, sizeof(mntpt), NULL);
        ext[0] = 0;
        argc--, argv++;
@@ -398,12 +401,11 @@ newjob(void)
        if (! job){
                error(1, 0, "%s: %r","job calloc");
        }
-#warning "fix lock"
-//     //lock(&joblock);
+  spin_pdr_lock(&joblock);
        job->next = joblist;
        joblist = job;
        job->request.tag = -1;
-//     //unlock(&joblock);
+  spin_pdr_unlock(&joblock);
        return job;
 }
 
@@ -412,7 +414,7 @@ freejob(Job *job)
 {
        Job **l;
 return;
-       //lock(&joblock);
+  spin_pdr_lock(&joblock);
        for(l = &joblist; *l; l = &(*l)->next){
                if((*l) == job){
                        *l = job->next;
@@ -420,7 +422,7 @@ return;
                        break;
                }
        }
-       //unlock(&joblock);
+  spin_pdr_unlock(&joblock);
 }
 
 void
@@ -428,21 +430,21 @@ flushjob(int tag)
 {
        Job *job;
 
-       //lock(&joblock);
+  spin_pdr_lock(&joblock);
        for(job = joblist; job; job = job->next){
                if(job->request.tag == tag && job->request.type != Tflush){
                        job->flushed = 1;
                        break;
                }
        }
-       //unlock(&joblock);
+  spin_pdr_unlock(&joblock);
 }
 
 void *job_thread(void* arg)
 {
        Mfile *mf;
        Job *job = arg;
-       //lock(&dblock);
+       spin_pdr_lock(&dblock);
        mf = newfid(job->request.fid);
 
        if(debug)
@@ -491,7 +493,7 @@ void *job_thread(void* arg)
                rwstat(job, mf);
                break;
        }
-       //unlock(&dblock);
+       spin_pdr_unlock(&dblock);
 
        freejob(job);
 
@@ -508,7 +510,7 @@ io(void)
 
        uint8_t mdata[IOHDRSZ + Maxfdata];
        Job *job;
-
+  // TODO: Creating threads right now makes no difference, because of big locks!
        /*
         * each request is handled via a thread. Somewhat less efficient than the old
         * cs but way cleaner. 
@@ -528,14 +530,10 @@ io(void)
                /* stash the thread in the job so we can join them all
                 * later if we want to.
                 */
-#if 0
                if (pthread_create(&job->thread, NULL, &job_thread, job)) {
                        error(1, 0, "%s: %r","Failed to create job");
                        continue;
                }
-#endif
-       job_thread(job);
-
 
        }
 }
@@ -960,11 +958,11 @@ sendmsg(Job *job, char *err)
                fprintf(stderr,  "CS:sendmsg convS2M of %F returns 0", &job->reply);
                abort();
        }
-       //lock(&joblock);
+       spin_pdr_lock(&joblock);
        if(job->flushed == 0)
                if(write(mfd[1], mdata, n)!=n)
                        error(1, 0, "%s: %r","mount write");
-       //unlock(&joblock);
+       spin_pdr_unlock(&joblock);
        if(debug)
                fprintf(stderr,  "CS:%F %d", &job->reply, n);
 }
@@ -1448,7 +1446,7 @@ iplookup(Network *np, char *host, char *serv, int nolookup)
        /*
         * reorder according to our interfaces
         */
-       //lock(&ipifclock);
+       spin_pdr_lock(&ipifclock);
        for(ifc = ipifcs; ifc != NULL; ifc = ifc->next){
                for(lifc = ifc->lifc; lifc != NULL; lifc = lifc->next){
                        maskip(lifc->ip, lifc->mask, net);
@@ -1459,13 +1457,13 @@ iplookup(Network *np, char *host, char *serv, int nolookup)
                                maskip(ip, lifc->mask, tnet);
                                if(memcmp(net, tnet, IPaddrlen) == 0){
                                        t = reorder(t, nt);
-                                       //unlock(&ipifclock);
+                                       spin_pdr_unlock(&ipifclock);
                                        return t;
                                }
                        }
                }
        }
-       //unlock(&ipifclock);
+       spin_pdr_unlock(&ipifclock);
 
        return t;
 }
@@ -1604,8 +1602,8 @@ dnsiplookup(char *host, struct ndbs *s)
 {
        char buf[Maxreply];
        struct ndbtuple *t;
-
-       //unlock(&dblock);
+  // XXX: really?
+       spin_pdr_unlock(&dblock);
 
        /* save the name */
        snprintf(buf, sizeof(buf), "%s", host);
@@ -1628,7 +1626,7 @@ dnsiplookup(char *host, struct ndbs *s)
                        werrstr("temporary problem: %s", buf);
        }
 
-       //lock(&dblock);
+       spin_pdr_lock(&dblock);
        return t;
 }