diff --git a/repos/libports/src/lib/libc/readv_writev.cc b/repos/libports/src/lib/libc/readv_writev.cc index 7555062bd..e03c7b598 100644 --- a/repos/libports/src/lib/libc/readv_writev.cc +++ b/repos/libports/src/lib/libc/readv_writev.cc @@ -23,9 +23,6 @@ #include -static Genode::Lock rw_lock; - - struct Read { ssize_t operator()(int fd, void *buf, size_t count) @@ -44,10 +41,17 @@ struct Write }; +static Genode::Lock &rw_lock() +{ + static Genode::Lock rw_lock; + return rw_lock; +} + + template static ssize_t readv_writev_impl(Rw_func rw_func, int fd, const struct iovec *iov, int iovcnt) { - Genode::Lock_guard rw_lock_guard(rw_lock); + Genode::Lock_guard rw_lock_guard(rw_lock()); char *v; ssize_t bytes_transfered_total = 0; diff --git a/repos/libports/src/lib/libc/rwlock.cc b/repos/libports/src/lib/libc/rwlock.cc index a1ac4ca2e..a7cb96238 100644 --- a/repos/libports/src/lib/libc/rwlock.cc +++ b/repos/libports/src/lib/libc/rwlock.cc @@ -24,9 +24,6 @@ #include -static Libc::Allocator object_alloc; - - /* * A reader-preferring implementation of a readers-writer lock as described * in Michael Raynal, "Concurrent Programming: Algorithms, Principles, and @@ -105,7 +102,8 @@ extern "C" { try { Genode::Lock::Guard g(rwlock_init_lock); - *rwlock = new (object_alloc) struct pthread_rwlock(); + Libc::Allocator alloc { }; + *rwlock = new (alloc) struct pthread_rwlock(); return 0; } catch (...) { return ENOMEM; } } @@ -117,7 +115,8 @@ extern "C" { int pthread_rwlock_destroy(pthread_rwlock_t *rwlock) { - destroy(object_alloc, *rwlock); + Libc::Allocator alloc { }; + destroy(alloc, *rwlock); return 0; } @@ -154,7 +153,8 @@ extern "C" { int pthread_rwlockattr_init(pthread_rwlockattr_t *attr) { - *attr = new (object_alloc) struct pthread_rwlockattr(); + Libc::Allocator alloc { }; + *attr = new (alloc) struct pthread_rwlockattr(); return 0; } @@ -175,7 +175,8 @@ extern "C" { int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr) { - destroy(object_alloc, *attr); + Libc::Allocator alloc { }; + destroy(alloc, *attr); return 0; } diff --git a/repos/libports/src/lib/libc/select.cc b/repos/libports/src/lib/libc/select.cc index 84abffc5b..4d82fd9d0 100644 --- a/repos/libports/src/lib/libc/select.cc +++ b/repos/libports/src/lib/libc/select.cc @@ -69,7 +69,7 @@ struct Libc::Select_cb_list struct Guard : Genode::Lock::Guard { -Select_cb_list *l; + Select_cb_list *l; Guard(Select_cb_list &list) : Genode::Lock::Guard(list._mutex), l(&list) { } }; @@ -110,7 +110,11 @@ Select_cb_list *l; }; /** The global list of tasks waiting for select */ -static Libc::Select_cb_list select_cb_list; +static Libc::Select_cb_list &select_cb_list() +{ + static Libc::Select_cb_list inst; + return inst; +} /** @@ -183,7 +187,7 @@ static void select_notify() /* check for each waiting select() function if one of its fds is ready now * and if so, wake all up */ - select_cb_list.for_each([&] (Libc::Select_cb &scb) { + select_cb_list().for_each([&] (Libc::Select_cb &scb) { scb.nready = selscan(scb.nfds, &scb.readfds, &scb.writefds, &scb.exceptfds, &tmp_readfds, &tmp_writefds, &tmp_exceptfds); @@ -236,7 +240,7 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, * We use the guard directly to atomically check if any descripor is * ready, but insert into select-callback list otherwise. */ - Libc::Select_cb_list::Guard guard(select_cb_list); + Libc::Select_cb_list::Guard guard(select_cb_list()); int const nready = selscan(nfds, &in_readfds, &in_writefds, &in_exceptfds, @@ -254,7 +258,7 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, select_cb.construct(nfds, in_readfds, in_writefds, in_exceptfds); - select_cb_list.unsynchronized_insert(&(*select_cb)); + select_cb_list().unsynchronized_insert(&(*select_cb)); } struct Timeout @@ -283,7 +287,7 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, while (!timeout.expired() && select_cb->nready == 0) timeout.duration = Libc::suspend(check, timeout.duration); - select_cb_list.remove(&(*select_cb)); + select_cb_list().remove(&(*select_cb)); if (timeout.expired()) return 0; @@ -352,14 +356,14 @@ int Libc::Select_handler_base::select(int nfds, fd_set &readfds, /* remove potentially enqueued callback from list */ if (_select_cb->constructed()) - select_cb_list.remove(&(**_select_cb)); + select_cb_list().remove(&(**_select_cb)); { /* * We use the guard directly to atomically check is any descripor is * ready, and insert into select-callback list otherwise. */ - Libc::Select_cb_list::Guard guard(select_cb_list); + Libc::Select_cb_list::Guard guard(select_cb_list()); int const nready = selscan(nfds, &in_readfds, &in_writefds, &in_exceptfds, @@ -373,7 +377,7 @@ int Libc::Select_handler_base::select(int nfds, fd_set &readfds, _select_cb->construct(nfds, in_readfds, in_writefds, in_exceptfds); - select_cb_list.unsynchronized_insert(&(**_select_cb)); + select_cb_list().unsynchronized_insert(&(**_select_cb)); } Libc::schedule_select(this); @@ -388,7 +392,7 @@ void Libc::Select_handler_base::dispatch_select() if (select_cb->nready == 0) return; - select_cb_list.remove(&(*select_cb)); + select_cb_list().remove(&(*select_cb)); Libc::schedule_select(nullptr); select_ready(select_cb->nready, select_cb->readfds, diff --git a/repos/libports/src/lib/libc/semaphore.cc b/repos/libports/src/lib/libc/semaphore.cc index a2ef3c8f0..4c8726a25 100644 --- a/repos/libports/src/lib/libc/semaphore.cc +++ b/repos/libports/src/lib/libc/semaphore.cc @@ -20,8 +20,6 @@ using namespace Genode; -static Libc::Allocator object_alloc; - extern "C" { /* @@ -43,7 +41,8 @@ extern "C" { int sem_destroy(sem_t *sem) { - destroy(object_alloc, *sem); + Libc::Allocator alloc { }; + destroy(alloc, *sem); return 0; } @@ -57,7 +56,8 @@ extern "C" { int sem_init(sem_t *sem, int pshared, unsigned int value) { - *sem = new (object_alloc) struct sem(value); + Libc::Allocator alloc { }; + *sem = new (alloc) struct sem(value); return 0; } diff --git a/repos/libports/src/lib/libc/socket_fs_plugin.cc b/repos/libports/src/lib/libc/socket_fs_plugin.cc index 6464d30a3..b8fcfdf2c 100644 --- a/repos/libports/src/lib/libc/socket_fs_plugin.cc +++ b/repos/libports/src/lib/libc/socket_fs_plugin.cc @@ -54,8 +54,6 @@ namespace Libc { namespace Socket_fs { - Libc::Allocator global_allocator; - using Libc::Errno; struct Absolute_path : Vfs::Absolute_path @@ -542,7 +540,8 @@ extern "C" int socket_fs_accept(int libc_fd, sockaddr *addr, socklen_t *addrlen) Socket_fs::Context *accept_context; try { - accept_context = new (&global_allocator) + Libc::Allocator alloc { }; + accept_context = new (alloc) Socket_fs::Context(listen_context->proto(), handle_fd); } catch (New_socket_failed) { return Errno(EACCES); } @@ -962,7 +961,8 @@ extern "C" int socket_fs_socket(int domain, int type, int protocol) Genode::error("failed to open new socket at ", path); return Errno(EACCES); } - context = new (&global_allocator) + Libc::Allocator alloc { }; + context = new (alloc) Socket_fs::Context(proto, handle_fd); } catch (New_socket_failed) { return Errno(EACCES); } @@ -1004,9 +1004,10 @@ extern "C" int getifaddrs(struct ifaddrs **ifap) static sockaddr_in address; static sockaddr_in netmask { 0 }; static sockaddr_in broadcast { 0 }; + static char name[1] { }; static ifaddrs ifaddr { - .ifa_name = "", + .ifa_name = name, .ifa_flags = IFF_UP, .ifa_addr = (sockaddr*)&address, .ifa_netmask = (sockaddr*)&netmask, @@ -1188,7 +1189,8 @@ int Socket_fs::Plugin::close(Libc::File_descriptor *fd) Socket_fs::Context *context = dynamic_cast(fd->context); if (!context) return Errno(EBADF); - Genode::destroy(&global_allocator, context); + Libc::Allocator alloc { }; + Genode::destroy(alloc, context); Libc::file_descriptor_allocator()->free(fd); /* diff --git a/repos/libports/src/lib/libc/thread.cc b/repos/libports/src/lib/libc/thread.cc index c569e4275..918c50ef1 100644 --- a/repos/libports/src/lib/libc/thread.cc +++ b/repos/libports/src/lib/libc/thread.cc @@ -29,14 +29,17 @@ using namespace Genode; -static Libc::Allocator object_alloc; - - static Env *_env_ptr; /* solely needed to spawn the timeout thread for the timed semaphore */ +static Thread *_main_thread_ptr; -void Libc::init_pthread_support(Genode::Env &env) { _env_ptr = &env; } + +void Libc::init_pthread_support(Genode::Env &env) +{ + _env_ptr = &env; + _main_thread_ptr = Thread::myself(); +} static Libc::Timeout_entrypoint &_global_timeout_ep() @@ -50,19 +53,6 @@ static Libc::Timeout_entrypoint &_global_timeout_ep() } -/* - * We initialize the main-thread pointer in a constructor depending on the - * assumption that libpthread is loaded on application startup by ldso. During - * this stage only the main thread is executed. - */ -static __attribute__((constructor)) Thread * main_thread() -{ - static Thread *thread = Thread::myself(); - - return thread; -} - - /* * pthread */ @@ -172,7 +162,8 @@ extern "C" { { thread->join(retval); - destroy(object_alloc, thread); + Libc::Allocator alloc { }; + destroy(alloc, thread); return 0; } @@ -183,7 +174,8 @@ extern "C" { if (!attr) return EINVAL; - *attr = new (object_alloc) pthread_attr; + Libc::Allocator alloc { }; + *attr = new (alloc) pthread_attr; return 0; } @@ -194,7 +186,8 @@ extern "C" { if (!attr || !*attr) return EINVAL; - destroy(object_alloc, *attr); + Libc::Allocator alloc { }; + destroy(alloc, *attr); *attr = 0; return 0; @@ -218,7 +211,7 @@ extern "C" { /* special non-POSIX function (for example used in libresolv) */ int _pthread_main_np(void) { - return (Thread::myself() == main_thread()); + return (Thread::myself() == _main_thread_ptr); } @@ -251,7 +244,8 @@ extern "C" { * of the pthread object would also destruct the 'Thread' of the main * thread. */ - static pthread *main = new (object_alloc) pthread(*Thread::myself()); + Libc::Allocator alloc { }; + static pthread *main = new (alloc) pthread(*Thread::myself()); return main; } @@ -498,7 +492,8 @@ extern "C" { if (!attr) return EINVAL; - *attr = new (object_alloc) pthread_mutex_attr; + Libc::Allocator alloc { }; + *attr = new (alloc) pthread_mutex_attr; return 0; } @@ -509,7 +504,8 @@ extern "C" { if (!attr || !*attr) return EINVAL; - destroy(object_alloc, *attr); + Libc::Allocator alloc { }; + destroy(alloc, *attr); *attr = 0; return 0; @@ -533,7 +529,8 @@ extern "C" { if (!mutex) return EINVAL; - *mutex = new (object_alloc) pthread_mutex(attr); + Libc::Allocator alloc { }; + *mutex = new (alloc) pthread_mutex(attr); return 0; } @@ -544,7 +541,8 @@ extern "C" { if ((!mutex) || (*mutex == PTHREAD_MUTEX_INITIALIZER)) return EINVAL; - destroy(object_alloc, *mutex); + Libc::Allocator alloc { }; + destroy(alloc, *mutex); *mutex = PTHREAD_MUTEX_INITIALIZER; return 0; @@ -655,7 +653,8 @@ extern "C" { try { Genode::Lock::Guard g(cond_init_lock); - *cond = new (object_alloc) pthread_cond; + Libc::Allocator alloc { }; + *cond = new (alloc) pthread_cond; return 0; } catch (...) { return ENOMEM; } } @@ -673,7 +672,8 @@ extern "C" { if (!cond || !*cond) return EINVAL; - destroy(object_alloc, *cond); + Libc::Allocator alloc { }; + destroy(alloc, *cond); *cond = 0; return 0; @@ -838,24 +838,42 @@ extern "C" { }; - static Lock key_list_lock; - List key_list[PTHREAD_KEYS_MAX]; + static Lock &key_list_lock() + { + static Lock inst { }; + return inst; + } + + + struct Keys + { + List key[PTHREAD_KEYS_MAX]; + }; + + + static Keys &keys() + { + static Keys inst { }; + return inst; + } + int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)) { if (!key) return EINVAL; - Lock_guard key_list_lock_guard(key_list_lock); + Lock_guard key_list_lock_guard(key_list_lock()); for (int k = 0; k < PTHREAD_KEYS_MAX; k++) { /* * Find an empty key slot and insert an element for the current * thread to mark the key slot as used. */ - if (!key_list[k].first()) { - Key_element *key_element = new (object_alloc) Key_element(Thread::myself(), 0); - key_list[k].insert(key_element); + if (!keys().key[k].first()) { + Libc::Allocator alloc { }; + Key_element *key_element = new (alloc) Key_element(Thread::myself(), 0); + keys().key[k].insert(key_element); *key = k; return 0; } @@ -867,14 +885,15 @@ extern "C" { int pthread_key_delete(pthread_key_t key) { - if (key < 0 || key >= PTHREAD_KEYS_MAX || !key_list[key].first()) + if (key < 0 || key >= PTHREAD_KEYS_MAX || !keys().key[key].first()) return EINVAL; - Lock_guard key_list_lock_guard(key_list_lock); + Lock_guard key_list_lock_guard(key_list_lock()); - while (Key_element * element = key_list[key].first()) { - key_list[key].remove(element); - destroy(object_alloc, element); + while (Key_element * element = keys().key[key].first()) { + keys().key[key].remove(element); + Libc::Allocator alloc { }; + destroy(alloc, element); } return 0; @@ -888,9 +907,9 @@ extern "C" { void *myself = Thread::myself(); - Lock_guard key_list_lock_guard(key_list_lock); + Lock_guard key_list_lock_guard(key_list_lock()); - for (Key_element *key_element = key_list[key].first(); key_element; + for (Key_element *key_element = keys().key[key].first(); key_element; key_element = key_element->next()) if (key_element->thread_base == myself) { key_element->value = value; @@ -898,8 +917,9 @@ extern "C" { } /* key element does not exist yet - create a new one */ - Key_element *key_element = new (object_alloc) Key_element(Thread::myself(), value); - key_list[key].insert(key_element); + Libc::Allocator alloc { }; + Key_element *key_element = new (alloc) Key_element(Thread::myself(), value); + keys().key[key].insert(key_element); return 0; } @@ -911,9 +931,9 @@ extern "C" { void *myself = Thread::myself(); - Lock_guard key_list_lock_guard(key_list_lock); + Lock_guard key_list_lock_guard(key_list_lock()); - for (Key_element *key_element = key_list[key].first(); key_element; + for (Key_element *key_element = keys().key[key].first(); key_element; key_element = key_element->next()) if (key_element->thread_base == myself) return (void*)(key_element->value); @@ -929,7 +949,8 @@ extern "C" { return EINTR; if (!once->mutex) { - pthread_mutex_t p = new (object_alloc) pthread_mutex(0); + Libc::Allocator alloc { }; + pthread_mutex_t p = new (alloc) pthread_mutex(0); /* be paranoid */ if (!p) return EINTR; @@ -948,7 +969,7 @@ extern "C" { * free our mutex since it is not used. */ if (p) - destroy(object_alloc, p); + destroy(alloc, p); } once->mutex->lock(); diff --git a/repos/libports/src/lib/libc/thread_create.cc b/repos/libports/src/lib/libc/thread_create.cc index 7f54e8d29..d6b0ba065 100644 --- a/repos/libports/src/lib/libc/thread_create.cc +++ b/repos/libports/src/lib/libc/thread_create.cc @@ -21,37 +21,36 @@ #include -static Libc::Allocator object_alloc; - - int Libc::pthread_create(pthread_t *thread, void *(*start_routine) (void *), void *arg, size_t stack_size, char const * name, Genode::Cpu_session * cpu, Genode::Affinity::Location location) { - pthread_t thread_obj = new (object_alloc) - pthread(start_routine, arg, - stack_size, name, cpu, location); - if (!thread_obj) - return EAGAIN; + Libc::Allocator alloc { }; + pthread_t thread_obj = new (alloc) + pthread(start_routine, arg, + stack_size, name, cpu, location); + if (!thread_obj) + return EAGAIN; - *thread = thread_obj; + *thread = thread_obj; - thread_obj->start(); + thread_obj->start(); - return 0; + return 0; } int Libc::pthread_create(pthread_t *thread, Genode::Thread &t) { - pthread_t thread_obj = new (object_alloc) pthread(t); + Libc::Allocator alloc { }; + pthread_t thread_obj = new (alloc) pthread(t); - if (!thread_obj) - return EAGAIN; + if (!thread_obj) + return EAGAIN; - *thread = thread_obj; - return 0; + *thread = thread_obj; + return 0; }