diff --git a/src/klib/klist.h b/src/klib/klist.h deleted file mode 100644 index 4274c53919..0000000000 --- a/src/klib/klist.h +++ /dev/null @@ -1,144 +0,0 @@ -/* The MIT License - - Copyright (c) 2008-2009, by Attractive Chaos - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -#ifndef _AC_KLIST_H -#define _AC_KLIST_H - -#include -#include - -#include "nvim/func_attr.h" -#include "nvim/memory.h" - -#define KMEMPOOL_INIT(name, kmptype_t, kmpfree_f) \ - typedef struct { \ - size_t cnt, n, max; \ - kmptype_t **buf; \ - } kmp_##name##_t; \ - static inline kmp_##name##_t *kmp_init_##name(void) { \ - return (kmp_##name##_t *)xcalloc(1, sizeof(kmp_##name##_t)); \ - } \ - static inline void kmp_destroy_##name(kmp_##name##_t *mp) \ - REAL_FATTR_UNUSED; \ - static inline void kmp_destroy_##name(kmp_##name##_t *mp) { \ - size_t k; \ - for (k = 0; k < mp->n; k++) { \ - kmpfree_f(mp->buf[k]); XFREE_CLEAR(mp->buf[k]); \ - } \ - XFREE_CLEAR(mp->buf); XFREE_CLEAR(mp); \ - } \ - static inline kmptype_t *kmp_alloc_##name(kmp_##name##_t *mp) { \ - mp->cnt++; \ - if (mp->n == 0) { \ - return (kmptype_t *)xcalloc(1, sizeof(kmptype_t)); \ - } \ - return mp->buf[--mp->n]; \ - } \ - static inline void kmp_free_##name(kmp_##name##_t *mp, kmptype_t *p) { \ - mp->cnt--; \ - if (mp->n == mp->max) { \ - mp->max = mp->max ? (mp->max << 1) : 16; \ - mp->buf = (kmptype_t **)xrealloc(mp->buf, sizeof(kmptype_t *) * mp->max); \ - } \ - mp->buf[mp->n++] = p; \ - } - -#define kmempool_t(name) kmp_##name##_t -#define kmp_init(name) kmp_init_##name() -#define kmp_destroy(name, mp) kmp_destroy_##name(mp) -#define kmp_alloc(name, mp) kmp_alloc_##name(mp) -#define kmp_free(name, mp, p) kmp_free_##name(mp, p) - -#define KLIST_INIT(name, kltype_t, kmpfree_t) \ - struct __kl1_##name { \ - kltype_t data; \ - struct __kl1_##name *next; \ - }; \ - typedef struct __kl1_##name kl1_##name; \ - KMEMPOOL_INIT(name, kl1_##name, kmpfree_t) \ - typedef struct { \ - kl1_##name *head, *tail; \ - kmp_##name##_t *mp; \ - size_t size; \ - } kl_##name##_t; \ - static inline kl_##name##_t *kl_init_##name(void) { \ - kl_##name##_t *kl = (kl_##name##_t *)xcalloc(1, sizeof(kl_##name##_t)); \ - kl->mp = kmp_init(name); \ - kl->head = kl->tail = kmp_alloc(name, kl->mp); \ - kl->head->next = 0; \ - return kl; \ - } \ - static inline void kl_destroy_##name(kl_##name##_t *kl) \ - REAL_FATTR_UNUSED; \ - static inline void kl_destroy_##name(kl_##name##_t *kl) { \ - kl1_##name *p; \ - for (p = kl->head; p != kl->tail; p = p->next) { \ - kmp_free(name, kl->mp, p); \ - } \ - kmp_free(name, kl->mp, p); \ - kmp_destroy(name, kl->mp); \ - XFREE_CLEAR(kl); \ - } \ - static inline void kl_push_##name(kl_##name##_t *kl, kltype_t d) { \ - kl1_##name *q, *p = kmp_alloc(name, kl->mp); \ - q = kl->tail; p->next = 0; kl->tail->next = p; kl->tail = p; \ - kl->size++; \ - q->data = d; \ - } \ - static inline kltype_t kl_shift_at_##name(kl_##name##_t *kl, \ - kl1_##name **n) { \ - assert((*n)->next); \ - kl1_##name *p; \ - kl->size--; \ - p = *n; \ - *n = (*n)->next; \ - if (p == kl->head) { \ - kl->head = *n; \ - } \ - kltype_t d = p->data; \ - kmp_free(name, kl->mp, p); \ - return d; \ - } - -#define kliter_t(name) kl1_##name -#define klist_t(name) kl_##name##_t -#define kl_val(iter) ((iter)->data) -#define kl_next(iter) ((iter)->next) -#define kl_begin(kl) ((kl)->head) -#define kl_end(kl) ((kl)->tail) - -#define kl_init(name) kl_init_##name() -#define kl_destroy(name, kl) kl_destroy_##name(kl) -#define kl_push(name, kl, d) kl_push_##name(kl, d) -#define kl_shift_at(name, kl, node) kl_shift_at_##name(kl, node) -#define kl_shift(name, kl) kl_shift_at(name, kl, &kl->head) -#define kl_empty(kl) ((kl)->size == 0) -// Iteration macros. It's ok to modify the list while iterating as long as a -// `break` statement is executed before the next iteration. -#define kl_iter(name, kl, p) kl_iter_at(name, kl, p, NULL) -#define kl_iter_at(name, kl, p, h) \ - for (kl1_##name **p = h ? h : &kl->head; *p != kl->tail; p = &(*p)->next) - -#endif diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index e1ebcecbd6..15d993cc62 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -20,7 +20,7 @@ void loop_init(Loop *loop, void *data) loop->recursive = 0; loop->closing = false; loop->uv.data = loop; - loop->children = kl_init(WatcherPtr); + kv_init(loop->children); loop->events = multiqueue_new_parent(loop_on_put, loop); loop->fast_events = multiqueue_new_child(loop->events); loop->thread_events = multiqueue_new_parent(NULL, NULL); @@ -187,7 +187,7 @@ bool loop_close(Loop *loop, bool wait) multiqueue_free(loop->fast_events); multiqueue_free(loop->thread_events); multiqueue_free(loop->events); - kl_destroy(WatcherPtr, loop->children); + kv_destroy(loop->children); return rv; } diff --git a/src/nvim/event/loop.h b/src/nvim/event/loop.h index b86e83de3c..563b254a0b 100644 --- a/src/nvim/event/loop.h +++ b/src/nvim/event/loop.h @@ -3,15 +3,10 @@ #include #include -#include "klib/klist.h" +#include "klib/kvec.h" #include "nvim/event/defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" // IWYU pragma: keep -typedef void *WatcherPtr; - -#define NOOP(x) -KLIST_INIT(WatcherPtr, WatcherPtr, NOOP) - struct loop { uv_loop_t uv; MultiQueue *events; @@ -27,7 +22,7 @@ struct loop { MultiQueue *fast_events; // used by process/job-control subsystem - klist_t(WatcherPtr) *children; + kvec_t(Proc *) children; uv_signal_t children_watcher; uv_timer_t children_kill_timer; diff --git a/src/nvim/event/proc.c b/src/nvim/event/proc.c index 808bf794f0..5ae3bd8c2d 100644 --- a/src/nvim/event/proc.c +++ b/src/nvim/event/proc.c @@ -3,7 +3,6 @@ #include #include -#include "klib/klist.h" #include "nvim/event/libuv_proc.h" #include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" @@ -123,7 +122,7 @@ int proc_spawn(Proc *proc, bool in, bool out, bool err) proc->internal_exit_cb = on_proc_exit; proc->internal_close_cb = decref; proc->refcount++; - kl_push(WatcherPtr, proc->loop->children, proc); + kv_push(proc->loop->children, proc); DLOG("new: pid=%d exepath=[%s]", proc->pid, proc_get_exepath(proc)); return 0; } @@ -131,8 +130,8 @@ int proc_spawn(Proc *proc, bool in, bool out, bool err) void proc_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL { proc_is_tearing_down = true; - kl_iter(WatcherPtr, loop->children, current) { - Proc *proc = (*current)->data; + for (size_t i = 0; i < kv_size(loop->children); i++) { + Proc *proc = kv_A(loop->children, i); if (proc->detach || proc->type == kProcTypePty) { // Close handles to process without killing it. CREATE_EVENT(loop->events, proc_close_handles, proc); @@ -143,7 +142,7 @@ void proc_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL // Wait until all children exit and all close events are processed. LOOP_PROCESS_EVENTS_UNTIL(loop, loop->events, -1, - kl_empty(loop->children) && multiqueue_empty(loop->events)); + kv_size(loop->children) == 0 && multiqueue_empty(loop->events)); pty_proc_teardown(loop); } @@ -254,8 +253,8 @@ static void children_kill_cb(uv_timer_t *handle) { Loop *loop = handle->loop->data; - kl_iter(WatcherPtr, loop->children, current) { - Proc *proc = (*current)->data; + for (size_t i = 0; i < kv_size(loop->children); i++) { + Proc *proc = kv_A(loop->children, i); bool exited = (proc->status >= 0); if (exited || !proc->stopped_time) { continue; @@ -294,15 +293,19 @@ static void decref(Proc *proc) } Loop *loop = proc->loop; - kliter_t(WatcherPtr) **node = NULL; - kl_iter(WatcherPtr, loop->children, current) { - if ((*current)->data == proc) { - node = current; + size_t i; + for (i = 0; i < kv_size(loop->children); i++) { + Proc *current = kv_A(loop->children, i); + if (current == proc) { break; } } - assert(node); - kl_shift_at(WatcherPtr, loop->children, node); + assert(i < kv_size(loop->children)); // element found + if (i < kv_size(loop->children) - 1) { + memmove(&kv_A(loop->children, i), &kv_A(loop->children, i + 1), + sizeof(&kv_A(loop->children, i)) * (kv_size(loop->children) - (i + 1))); + } + kv_size(loop->children)--; CREATE_EVENT(proc->events, proc_close_event, proc); } diff --git a/src/nvim/os/pty_proc_unix.c b/src/nvim/os/pty_proc_unix.c index e629b328fd..3bca065d2d 100644 --- a/src/nvim/os/pty_proc_unix.c +++ b/src/nvim/os/pty_proc_unix.c @@ -30,7 +30,6 @@ #endif #include "auto/config.h" -#include "klib/klist.h" #include "nvim/eval/typval.h" #include "nvim/event/defs.h" #include "nvim/event/loop.h" @@ -387,8 +386,8 @@ static void chld_handler(uv_signal_t *handle, int signum) Loop *loop = handle->loop->data; - kl_iter(WatcherPtr, loop->children, current) { - Proc *proc = (*current)->data; + for (size_t i = 0; i < kv_size(loop->children); i++) { + Proc *proc = kv_A(loop->children, i); do { pid = waitpid(proc->pid, &stat, WNOHANG); } while (pid < 0 && errno == EINTR);