Skip to content

Commit

Permalink
solution to lab1
Browse files Browse the repository at this point in the history
  • Loading branch information
zhf committed Nov 22, 2012
1 parent 018fdad commit f916d3b
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 14 deletions.
6 changes: 3 additions & 3 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ rsm_tester: $(patsubst %.cc,%.o,$(rsm_tester)) rpc/librpc.a
fuse.o: fuse.cc
$(CXX) -c $(CXXFLAGS) $(FUSEFLAGS) $(MACFLAGS) $<

# mklab.inc is needed by 6.824 staff only. Just ignore it.
# mklab.inc is needed by staff only. Just ignore it.
-include mklab.inc

-include *.d
Expand All @@ -128,10 +128,10 @@ clean:
rm $(clean_files) -rf

handin_ignore=$(clean_files) core* *log
handin_file=$(shell whoami)-lab$(LAB).tgz
handin_file=$(shell whoami)-lab$(LAB)-112037xxxx.tgz
labdir=$(shell basename $(PWD))
handin:
@if test -f stop.sh; then ./stop.sh > /dev/null 2>&1 | echo ""; fi
@bash -c "cd ../; tar -X <(tr ' ' '\n' < <(echo '$(handin_ignore)')) -czvf $(handin_file) $(labdir); mv $(handin_file) $(labdir); cd $(labdir)"
@echo Please email $(handin_file) to [email protected]
@echo Please change the name of $(handin_file) and email it to [email protected]
@echo Thanks!
8 changes: 8 additions & 0 deletions lock_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,18 @@ lock_client::stat(lock_protocol::lockid_t lid)
lock_protocol::status
lock_client::acquire(lock_protocol::lockid_t lid)
{
int r;
lock_protocol::status ret = cl->call(lock_protocol::acquire, cl->id(), lid, r);
VERIFY (ret == lock_protocol::OK);
return r;
}

lock_protocol::status
lock_client::release(lock_protocol::lockid_t lid)
{
int r;
lock_protocol::status ret = cl->call(lock_protocol::release, cl->id(), lid, r);
VERIFY (ret == lock_protocol::OK);
return r;
}

57 changes: 57 additions & 0 deletions lock_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
lock_server::lock_server():
nacquire (0)
{
VERIFY(pthread_mutex_init(&mutex, NULL) == 0);
}

lock_protocol::status
Expand All @@ -17,7 +18,63 @@ lock_server::stat(int clt, lock_protocol::lockid_t lid, int &r)
lock_protocol::status ret = lock_protocol::OK;
printf("stat request from clt %d\n", clt);
r = nacquire;

if(locks.find(lid) != locks.end())
r = locks[lid];
return ret;
}

lock_protocol::status
lock_server::acquire(int clt, lock_protocol::lockid_t lid, int &r)
{
lock_protocol::status ret = lock_protocol::OK;
printf("acqure request from clt %d\n", clt);
r = nacquire;

VERIFY(pthread_mutex_lock(&mutex) == 0);

if(locks.find(lid) == locks.end())
{
locks[lid] = clt;
// set variable condition
if(conds.find(lid) == conds.end())
{
pthread_cond_t *p_cond = new pthread_cond_t();
pthread_cond_init(p_cond, NULL);
conds[lid] = p_cond;
}
}
else
{
// TODO wait for the lock to be free
while(locks[lid])
pthread_cond_wait(conds[lid], &mutex);

locks[lid] = clt;
}

r = clt;
VERIFY(pthread_mutex_unlock(&mutex) == 0);
return ret;
}

lock_protocol::status
lock_server::release(int clt, lock_protocol::lockid_t lid, int &r)
{
lock_protocol::status ret = lock_protocol::OK;
printf("release request from clt %d\n", clt);
r = nacquire;

VERIFY(pthread_mutex_lock(&mutex) == 0);

if(locks.find(lid) != locks.end())
locks.erase(lid);

if(conds.find(lid) != conds.end())
pthread_cond_signal(conds[lid]);


VERIFY(pthread_mutex_unlock(&mutex) == 0);
r = clt;
return ret;
}
19 changes: 11 additions & 8 deletions lock_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,29 @@
#define lock_server_h

#include <string>
#include <map>
#include <queue>
#include "lock_protocol.h"
#include "lock_client.h"
#include "rpc.h"
#include <pthread.h>

class lock_server {

protected:
int nacquire;
std::map<lock_protocol::lockid_t, int> locks;
std::map<lock_protocol::lockid_t, pthread_cond_t* > conds;
pthread_mutex_t mutex;


public:
lock_server();
~lock_server() {};
lock_protocol::status stat(int clt, lock_protocol::lockid_t lid, int &);
lock_protocol::status stat(int clt, lock_protocol::lockid_t lid, int &);
lock_protocol::status acquire(int clt, lock_protocol::lockid_t lid, int &);
lock_protocol::status release(int clt, lock_protocol::lockid_t lid, int &);

};

#endif







3 changes: 3 additions & 0 deletions lock_smain.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ main(int argc, char *argv[])
lock_server ls;
rpcs server(atoi(argv[1]), count);
server.reg(lock_protocol::stat, &ls, &lock_server::stat);
server.reg(lock_protocol::acquire, &ls, &lock_server::acquire);
server.reg(lock_protocol::release, &ls, &lock_server::release);

#endif


Expand Down
48 changes: 45 additions & 3 deletions rpc/rpc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -627,8 +627,8 @@ rpcs::dispatch(djob_t *j)
}
break;
case INPROGRESS: // server is working on this request
break;
case DONE: // duplicate and we still have the response
break;
case DONE: // duplicate and we still have the responsei
c->send(b1, sz1);
break;
case FORGOTTEN: // very old request and we don't have the response anymore
Expand Down Expand Up @@ -661,8 +661,44 @@ rpcs::checkduplicate_and_update(unsigned int clt_nonce, unsigned int xid,
unsigned int xid_rep, char **b, int *sz)
{
ScopedLock rwl(&reply_window_m_);

// You fill this in for Lab 1.
if(max_rep[clt_nonce] < xid_rep)
max_rep[clt_nonce] = xid_rep;
std::list<reply_t>::iterator it = reply_window_[clt_nonce].begin();

int find = 0;
while(it != reply_window_[clt_nonce].end())
{
if((*it).xid == xid)
{
if((*it).cb_present)
{
find = 1;
*b = (*it).buf;
*sz = (*it).sz;
}
else
find = 2;
++it;
}
else if((*it).xid <= xid_rep)
{
free((*it).buf);
it = reply_window_[clt_nonce].erase(it);
}
else
++it;
}

if(find == 1)
return DONE;
else if(find == 2)
return INPROGRESS;
else if(xid <= max_rep[clt_nonce])
return FORGOTTEN;

reply_t reply(xid);
reply_window_[clt_nonce].push_back(reply);
return NEW;
}

Expand All @@ -677,6 +713,12 @@ rpcs::add_reply(unsigned int clt_nonce, unsigned int xid,
{
ScopedLock rwl(&reply_window_m_);
// You fill this in for Lab 1.
reply_t reply(xid);
reply.cb_present = true;
reply.buf = b;
reply.sz = sz;

reply_window_[clt_nonce].push_back(reply);
}

void
Expand Down
1 change: 1 addition & 0 deletions rpc/rpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ class rpcs : public chanmgr {
// per client that that client hasn't acknowledged receiving yet.
// indexed by client nonce.
std::map<unsigned int, std::list<reply_t> > reply_window_;
std::map<unsigned int, unsigned int> max_rep;

void free_reply_window(void);
void add_reply(unsigned int clt_nonce, unsigned int xid, char *b, int sz);
Expand Down

0 comments on commit f916d3b

Please sign in to comment.