Skip to content

Commit

Permalink
posix: initialize rwlocks, prefer plain mutexes where applicable
Browse files Browse the repository at this point in the history
fixes crashes on macos with ineffectual rwlocks causing memory corruption.
  • Loading branch information
qwx9 committed Jan 24, 2025
1 parent 984d879 commit e2a0868
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 62 deletions.
12 changes: 7 additions & 5 deletions cmd/awkext.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ struct Tab{
};
static tabmap *map;
static Tab *tabs;
static RWLock buflock, tablock;
static RWLock tablock;
static QLock buflock;

/* FIXME: can replace with awk array and lookup */
int
Expand Down Expand Up @@ -329,10 +330,10 @@ fnloadbatch(void)
{
Val *v, *vs, *ve;

wlock(&buflock);
qlock(&buflock);
vs = valbuf;
valbuf = nil;
wunlock(&buflock);
qunlock(&buflock);
for(v=vs, ve=v+dylen(v); v<ve; v++)
set(v->tab, v->type, v->id, v->val);
dyfree(vs);
Expand All @@ -345,9 +346,9 @@ pushval(int tab, int type, ioff id, V val)
Val v;

v = (Val){tab, type, id, val};
wlock(&buflock);
qlock(&buflock);
dypush(valbuf, v);
wunlock(&buflock);
qunlock(&buflock);
if(dylen(valbuf) >= 64*1024){
pushcmd("loadbatch()");
flushcmd();
Expand Down Expand Up @@ -613,6 +614,7 @@ initext(void)
[TCL] = {"CL", "nodecolor", 1},
}, *pp;

initrwlock(&tablock);
map = tab_init();
for(pp=sptags; pp<sptags+nelem(sptags); pp++){
i = mktab(pp->name, pp->nodeidx);
Expand Down
18 changes: 9 additions & 9 deletions cmd/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
#include "cmd.h"

static File *cmdfs;
RWLock cmdlock;
static QLock cmdlock;

void
killcmd(void)
{
wlock(&cmdlock);
qlock(&cmdlock);
freefs(cmdfs);
cmdfs = nil;
wunlock(&cmdlock);
qunlock(&cmdlock);
close(outfd[1]);
outfd[1] = -1;
close(infd[1]);
Expand All @@ -26,13 +26,13 @@ killcmd(void)
void
flushcmd(void)
{
wlock(&cmdlock);
qlock(&cmdlock);
if(cmdfs == nil){
wunlock(&cmdlock);
qunlock(&cmdlock);
return;
}
flushfs(cmdfs);
wunlock(&cmdlock);
qunlock(&cmdlock);
}

static void
Expand All @@ -42,13 +42,13 @@ sendcmd(char *cmd)

n = strlen(cmd);
DPRINT(Debugcmd, "> [%d][%s]", n, cmd);
wlock(&cmdlock);
qlock(&cmdlock);
if(cmdfs == nil){
wunlock(&cmdlock);
qunlock(&cmdlock);
return;
}
writefs(cmdfs, cmd, n);
wunlock(&cmdlock);
qunlock(&cmdlock);
}

void
Expand Down
17 changes: 9 additions & 8 deletions fs/em.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ struct EM{
int ref;
char flags;
int infd;
RWLock l;
QLock l;
Bank **banks;
Page *cur;
};
static int swapfd = -1;
static Bank **banks;
static RWLock elock;
static QLock elock;
static EM **etab, *emstrbuf;
static Page pused = {.lleft = &pused, .lright = &pused};
static uvlong poolsz = Poolsz;
Expand Down Expand Up @@ -112,7 +112,7 @@ cleanup(void *)
if(swapfd < 0)
return;
wlock(&elock);
qlock(&elock);
close(swapfd);
swapfd = -1;
for(em=etab; em<etab+dylen(etab); em++){
Expand All @@ -121,7 +121,7 @@ cleanup(void *)
free(*em);
}
dyfree(etab);
wunlock(&elock);
qunlock(&elock);
}
*/

Expand All @@ -142,12 +142,12 @@ GETPAGE(EM *em, ssize off)
bank = emalloc(sizeof *bank);
bank->paddr = dylen(banks) << Ashift;
bank->em = em;
wlock(&elock);
qlock(&elock);
dypush(banks, bank);
wunlock(&elock);
wlock(&em->l);
qunlock(&elock);
qlock(&em->l);
dyinsert(em->banks, i, bank);
wunlock(&em->l);
qunlock(&em->l);
new = 1;
}else if((p = bank->pt[PAGE(off)]) == nil)
new = 1;
Expand Down Expand Up @@ -241,6 +241,7 @@ feedpages(void)
pl = emalloc(n * sizeof *pl);
memreallyfree -= n;
for(p=pl, pe=p+n; p<pe; p++){
initrwlock(&p->l);
p->lright = p + 1;
p->lleft = p - 1;
}
Expand Down
28 changes: 0 additions & 28 deletions graph/graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ Node *nodes;
ioff *edges;
Super *supers;

static RWLock *locks;

void
setattr(int type, ioff id, V val)
{
Expand Down Expand Up @@ -102,42 +100,16 @@ str2idx(char *s)
return id;
}

void
lockgraph(Graph *g, int w)
{
RWLock *l;

l = locks + (g - graphs);
if(w)
wlock(l);
else
rlock(l);
}

void
unlockgraph(Graph *g, int w)
{
RWLock *l;

l = locks + (g - graphs);
if(w)
wunlock(l);
else
runlock(l);
}

Graph *
initgraph(int type)
{
int n;
Graph g = {0}, *gp;
RWLock l = {0};

n = dylen(graphs);
g.type = type;
g.nfirst = dylen(nodes);
dypush(graphs, g);
dypush(locks, l);
gp = graphs + n;
return gp;
}
2 changes: 0 additions & 2 deletions graph/graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,4 @@ ioff newnode(Graph*, char*);
ioff newedge(Graph*, ioff, ioff, int, int, char*, ushort*);
void explode(ioff);
ioff str2idx(char*);
void lockgraph(Graph*, int);
void unlockgraph(Graph*, int);
Graph* initgraph(int);
7 changes: 7 additions & 0 deletions posix/threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ killthread(Thread *th)
pthread_cancel(th->p);
}

void
initrwlock(RWLock *l)
{
if(pthread_rwlock_init(l, NULL) != 0)
sysfatal("pthread_rwlock_init: %s", error());
}

Channel *
chancreate(int elsize, int nel)
{
Expand Down
51 changes: 46 additions & 5 deletions posix/threads.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

extern int mainstacksize;

typedef pthread_rwlock_t RWLock;
typedef struct chan_t Channel;

Channel* chancreate(int, int);
Expand All @@ -16,7 +15,49 @@ ulong nbrecvul(Channel*);
void* nbrecvp(Channel*);
#define sendp chan_send

#define rlock pthread_rwlock_rdlock
#define runlock pthread_rwlock_unlock
#define wlock pthread_rwlock_wrlock
#define wunlock pthread_rwlock_unlock
typedef pthread_mutex_t QLock;
typedef pthread_rwlock_t RWLock;

void initrwlock(RWLock*);

static inline void
rlock(RWLock *l)
{
if(pthread_rwlock_rdlock(l) != 0)
sysfatal("pthread_rwlock_rdlock: %s", error());
}

static inline void
wlock(RWLock *l)
{
if(pthread_rwlock_wrlock(l) != 0)
sysfatal("pthread_rwlock_wrlock: %s", error());
}

static inline void
wunlock(RWLock *l)
{
if(pthread_rwlock_unlock(l) != 0)
sysfatal("pthread_rwlock_unlock: %s", error());
}

static inline void
runlock(RWLock *l)
{
if(pthread_rwlock_unlock(l) != 0)
sysfatal("pthread_rwlock_unlock: %s", error());
}

static inline void
qlock(QLock *l)
{
if(pthread_mutex_lock(l) != 0)
sysfatal("pthread_mutex_lock: %s", error());
}

static inline void
qunlock(QLock *l)
{
if(pthread_mutex_unlock(l) != 0)
sysfatal("pthread_mutex_unlock: %s", error());
}
10 changes: 5 additions & 5 deletions util/print.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ char logbuf[8192], lastmsg[3][64], iserrmsg[3];
int nlog, logsz;

static char *lp = logbuf;
static RWLock llock;
static QLock llock;

static inline void
writelog(char *s, int iserr)
Expand Down Expand Up @@ -49,19 +49,19 @@ writelog(char *s, int iserr)
void
logmsg(char *s)
{
wlock(&llock);
qlock(&llock);
writelog(s, 0);
wunlock(&llock);
qunlock(&llock);
if(!onscreen)
warn("%s", s);
}

void
logerr(char *s)
{
wlock(&llock);
qlock(&llock);
writelog(s, 1);
wunlock(&llock);
qunlock(&llock);
warn("%s", s);
}

Expand Down

0 comments on commit e2a0868

Please sign in to comment.