1 #include "threadimpl.h"
6 #define MIN(a,b) ((a) < (b) ? (a) : (b))
7 #define MAX(a,b) ((a) > (b) ? (a) : (b))
25 static struct fd_entry fd_entry1 = { .fd -1 };
26 static struct fd_entry *fd_table = nil;
27 static spinlock_t fd_table_lock = { 0, 0, nil, 0 };
28 static spinlock_t mlock = { 0, 0, nil, 0 };
29 static spinlock_t dl_lock = { 0, 0, nil, 0 };
32 _thread_malloc_lock(void)
38 _thread_malloc_unlock(void)
44 _thread_malloc_init(void)
49 * Must set errno on failure because the return value
50 * of _thread_fd_entry is propagated back to the caller
51 * of the thread-wrapped libc function.
53 static struct fd_entry *
54 _thread_fd_lookup(int fd)
60 if(fd >= FDTBL_MAXSIZE) {
66 * There are currently only a few libc functions using
67 * _thread_fd_*, which are rarely called by P9P programs.
68 * So the contention for these locks is very small and so
69 * far have usually been limited to a single fd. So
70 * rather than malloc the fd_table everytime we just use
71 * a single fd_entry until a lock request for another fd
75 if(fd_entry1.fd == -1) {
78 } else if(fd_entry1.fd == fd)
81 cursize = MAX(fd_entry1.fd, 16);
82 fd_table = malloc(cursize*sizeof(fd_table[0]));
87 memset(fd_table, 0, cursize*sizeof(fd_table[0]));
88 fd_table[fd_entry1.fd] = fd_entry1;
91 newsize = MIN(cursize*2, FDTBL_MAXSIZE);
92 t = realloc(fd_table, newsize*sizeof(fd_table[0]));
99 memset(fd_table, 0, cursize*sizeof(fd_table[0]));
102 return &fd_table[fd];
106 * Mutiple readers just share the lock by incrementing the read count.
107 * Writers must obtain an exclusive lock.
110 _thread_fd_lock(int fd, int type, struct timespec *time)
112 struct fd_entry *fde;
115 _spinlock(&fd_table_lock);
116 fde = _thread_fd_lookup(fd);
120 if(type == FD_READ) {
121 if(fde->rc++ >= 1 && fde->wc == 0) {
122 _spinunlock(&fd_table_lock);
127 _spinunlock(&fd_table_lock);
129 /* handle recursion */
130 id = proc()->osprocid;
142 _thread_fd_unlock(int fd, int type)
144 struct fd_entry *fde;
147 fde = _thread_fd_lookup(fd);
149 fprint(2, "_thread_fd_unlock: fd %d not in table!\n", fd);
153 if(type == FD_READ && --fde->rc >= 1)
158 id = proc()->osprocid;
159 if(id == fde->id && fde->ref > 0) {
168 _thread_dl_lock(int t)
171 _spinunlock(&dl_lock);
180 dlctl(nil, DL_SETTHREADLCK, _thread_dl_lock);
181 signal(SIGUSR2, sigusr2handler);