Skip to content

Commit c8e10ee

Browse files
committed
Make bulk_free() go faster
1 parent 6245732 commit c8e10ee

File tree

13 files changed

+54
-36
lines changed

13 files changed

+54
-36
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ __pycache__
1515
/tool/emacs/*.elc
1616
/perf.data
1717
/perf.data.old
18+
/qemu*core

libc/cosmo.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ int cosmo_futex_wake(_COSMO_ATOMIC(int) *, int, char);
2525
int cosmo_futex_wait(_COSMO_ATOMIC(int) *, int, char, int,
2626
const struct timespec *);
2727

28-
errno_t cosmo_stack_alloc(size_t *, size_t *, void **) libcesque;
29-
errno_t cosmo_stack_free(void *, size_t, size_t) libcesque;
28+
errno_t cosmo_stack_alloc(unsigned *, unsigned *, void **) libcesque;
29+
errno_t cosmo_stack_free(void *, unsigned, unsigned) libcesque;
3030
void cosmo_stack_clear(void) libcesque;
3131
void cosmo_stack_setmaxstacks(int) libcesque;
3232
int cosmo_stack_getmaxstacks(void) libcesque;

libc/intrin/stack.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@
4242
struct CosmoStack {
4343
struct Dll elem;
4444
void *stackaddr;
45-
size_t stacksize;
46-
size_t guardsize;
45+
unsigned stacksize;
46+
unsigned guardsize;
4747
};
4848

4949
struct CosmoStacks {
@@ -215,13 +215,13 @@ void cosmo_stack_setmaxstacks(int maxstacks) {
215215
* This function returns 0 on success, or an errno on error. See the
216216
* documentation of mmap() for a list possible errors that may occur.
217217
*/
218-
errno_t cosmo_stack_alloc(size_t *inout_stacksize, //
219-
size_t *inout_guardsize, //
218+
errno_t cosmo_stack_alloc(unsigned *inout_stacksize, //
219+
unsigned *inout_guardsize, //
220220
void **out_addr) {
221221

222222
// validate arguments
223-
size_t stacksize = *inout_stacksize;
224-
size_t guardsize = *inout_guardsize;
223+
unsigned stacksize = *inout_stacksize;
224+
unsigned guardsize = *inout_guardsize;
225225
stacksize = (stacksize + __gransize - 1) & -__gransize;
226226
guardsize = (guardsize + __pagesize - 1) & -__pagesize;
227227
if (guardsize + __pagesize > stacksize)
@@ -283,7 +283,8 @@ static void cosmo_stack_setup(void) {
283283
* variable is never clobbered. You can only dependably count on this to
284284
* return an error on failure when you say `cosmo_stack_setmaxstacks(0)`
285285
*/
286-
errno_t cosmo_stack_free(void *stackaddr, size_t stacksize, size_t guardsize) {
286+
errno_t cosmo_stack_free(void *stackaddr, unsigned stacksize,
287+
unsigned guardsize) {
287288
stacksize = (stacksize + __gransize - 1) & -__gransize;
288289
guardsize = (guardsize + __pagesize - 1) & -__pagesize;
289290
if (guardsize + __pagesize > stacksize)

libc/thread/mapstack.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
*/
3636
void *NewCosmoStack(void) {
3737
void *stackaddr;
38-
size_t stacksize = GetStackSize();
39-
size_t guardsize = GetGuardSize();
38+
unsigned stacksize = GetStackSize();
39+
unsigned guardsize = GetGuardSize();
4040
errno_t err = cosmo_stack_alloc(&stacksize, &guardsize, &stackaddr);
4141
if (!err)
4242
return stackaddr;

libc/thread/posixthread.internal.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ struct PosixThread {
7878
atomic_int ptid; // transitions 0 → tid
7979
atomic_int pt_refs; // prevents decimation
8080
void *(*pt_start)(void *); // creation callback
81-
void *pt_arg; // start's parameter
82-
void *pt_rc; // start's return value
81+
void *pt_val; // start param / return val
8382
char *pt_tls; // bottom of tls allocation
8483
struct CosmoTib *tib; // middle of tls allocation
8584
struct Dll list; // list of threads
@@ -105,7 +104,6 @@ int _pthread_tid(struct PosixThread *) libcesque;
105104
intptr_t _pthread_syshand(struct PosixThread *) libcesque;
106105
long _pthread_cancel_ack(void) libcesque;
107106
void _pthread_decimate(void) libcesque;
108-
void _pthread_free(struct PosixThread *) libcesque;
109107
void _pthread_lock(void) libcesque;
110108
void _pthread_onfork_child(void) libcesque;
111109
void _pthread_onfork_parent(void) libcesque;

libc/thread/pthread_atfork.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,13 @@ static void _pthread_onfork(int i, const char *op) {
6363
}
6464

6565
void _pthread_onfork_prepare(void) {
66+
pthread_mutex_lock(&_atforks.lock);
6667
_pthread_onfork(0, "prepare");
6768
}
6869

6970
void _pthread_onfork_parent(void) {
7071
_pthread_onfork(1, "parent");
72+
pthread_mutex_unlock(&_atforks.lock);
7173
}
7274

7375
void _pthread_onfork_child(void) {

libc/thread/pthread_create.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ __static_yoink("_pthread_onfork_prepare");
6767
__static_yoink("_pthread_onfork_parent");
6868
__static_yoink("_pthread_onfork_child");
6969

70-
void _pthread_free(struct PosixThread *pt) {
70+
static void _pthread_free(struct PosixThread *pt) {
7171

7272
// thread must be removed from _pthread_list before calling
7373
unassert(dll_is_alone(&pt->list) && &pt->list != _pthread_list);
@@ -93,10 +93,13 @@ void _pthread_free(struct PosixThread *pt) {
9393
}
9494

9595
// free heap memory associated with thread
96-
if (pt->pt_flags & PT_OWNSIGALTSTACK)
97-
free(pt->pt_attr.__sigaltstackaddr);
98-
free(pt->pt_tls);
99-
free(pt);
96+
bulk_free(
97+
(void *[]){
98+
pt->pt_flags & PT_OWNSIGALTSTACK ? pt->pt_attr.__sigaltstackaddr : 0,
99+
pt->pt_tls,
100+
pt,
101+
},
102+
3);
100103
}
101104

102105
void _pthread_decimate(void) {
@@ -137,7 +140,6 @@ void _pthread_decimate(void) {
137140
}
138141

139142
static int PosixThread(void *arg, int tid) {
140-
void *rc;
141143
struct PosixThread *pt = arg;
142144

143145
// setup scheduling
@@ -167,11 +169,11 @@ static int PosixThread(void *arg, int tid) {
167169
} else {
168170
sys_sigprocmask(SIG_SETMASK, &pt->pt_attr.__sigmask, 0);
169171
}
170-
rc = pt->pt_start(pt->pt_arg);
172+
void *ret = pt->pt_start(pt->pt_val);
171173
// ensure pthread_cleanup_pop(), and pthread_exit() popped cleanup
172174
unassert(!pt->pt_cleanup);
173175
// calling pthread_exit() will either jump back here, or call exit
174-
pthread_exit(rc);
176+
pthread_exit(ret);
175177
}
176178

177179
// avoid signal handler being triggered after we trash our own stack
@@ -196,7 +198,7 @@ static errno_t pthread_create_impl(pthread_t *thread,
196198
dll_init(&pt->list);
197199
pt->pt_locale = &__global_locale;
198200
pt->pt_start = start_routine;
199-
pt->pt_arg = arg;
201+
pt->pt_val = arg;
200202

201203
// create thread local storage memory
202204
if (!(pt->pt_tls = _mktls(&pt->tib))) {

libc/thread/pthread_exit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ wontreturn void pthread_exit(void *rc) {
8888

8989
// set state
9090
pt->pt_flags |= PT_NOCANCEL | PT_EXITING;
91-
pt->pt_rc = rc;
91+
pt->pt_val = rc;
9292

9393
// free resources
9494
__cxa_thread_finalize();

libc/thread/pthread_timedjoin_np.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ errno_t pthread_timedjoin_np(pthread_t thread, void **value_ptr,
139139
memory_order_release);
140140
_pthread_zombify(pt);
141141
if (value_ptr)
142-
*value_ptr = pt->pt_rc;
142+
*value_ptr = pt->pt_val;
143143
}
144144

145145
_pthread_unref(pt);

libc/thread/thread.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ typedef struct pthread_attr_s {
130130
int __contentionscope;
131131
int __sigaltstacksize;
132132
uint64_t __sigmask;
133-
size_t __guardsize;
134-
size_t __stacksize;
133+
unsigned __guardsize;
134+
unsigned __stacksize;
135135
void *__stackaddr;
136136
void *__sigaltstackaddr;
137137
} pthread_attr_t;

0 commit comments

Comments
 (0)