diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2017-11-04 13:19:12 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2017-11-04 13:19:12 +0000 |
commit | c681d62a23a8b4ca2ecf0d6291a208ca323f0171 (patch) | |
tree | d69aed5c6dbab88ca8f781d6a345f0725a1d695e /src/libs6rc | |
parent | bc64800b5399e3dabaf1e7d7bc13b14a2dc4bf42 (diff) | |
download | s6-rc-c681d62a23a8b4ca2ecf0d6291a208ca323f0171.tar.xz |
Implement funnels. Needs testing.
Diffstat (limited to 'src/libs6rc')
-rw-r--r-- | src/libs6rc/s6rc_db_check_pipelines.c | 68 | ||||
-rw-r--r-- | src/libs6rc/s6rc_db_read.c | 19 | ||||
-rw-r--r-- | src/libs6rc/s6rc_db_read_sizes.c | 6 |
3 files changed, 56 insertions, 37 deletions
diff --git a/src/libs6rc/s6rc_db_check_pipelines.c b/src/libs6rc/s6rc_db_check_pipelines.c index d3d1bd9..68121e2 100644 --- a/src/libs6rc/s6rc_db_check_pipelines.c +++ b/src/libs6rc/s6rc_db_check_pipelines.c @@ -2,46 +2,60 @@ #include <string.h> #include <stdint.h> -#include <skalibs/bitarray.h> +#include <skalibs/diuint32.h> #include <s6-rc/s6rc-db.h> +struct recinfo_s +{ + s6rc_db_t const *db ; + unsigned char *mark ; +} ; + +static uint32_t check_prod_rec (struct recinfo_s *recinfo, uint32_t n) +{ + uint32_t i = 0 ; + if (recinfo->mark[n] & 3) return n ; + recinfo->mark[n] |= 1 ; + for (; i < recinfo->db->services[n].x.longrun.nproducers ; i++) + { + uint32_t j = recinfo->db->producers[recinfo->db->services[n].x.longrun.producers + i] ; + if (j >= recinfo->db->nlong) return (recinfo->mark[n] |= 4, n) ; + if (recinfo->db->services[j].x.longrun.consumer != n) return (recinfo->mark[j] |= 4, j) ; + j = check_prod_rec(recinfo, j) ; + if (j < recinfo->db->nlong) return j ; + } + recinfo->mark[n] |= 2 ; + return recinfo->db->nlong ; +} + int s6rc_db_check_pipelines (s6rc_db_t const *db, diuint32 *problem) { uint32_t i = db->nlong ; - unsigned char black[bitarray_div8(db->nlong)] ; - memset(black, 0, bitarray_div8(db->nlong)) ; - while (i--) if (!bitarray_peek(black, i)) + unsigned char mark[db->nlong] ; + struct recinfo_s recinfo = { .db = db, .mark = mark } ; + memset(mark, 0, db->nlong) ; + while (i--) { - uint32_t j = i ; - uint32_t start ; - for (;;) + if (db->services[i].x.longrun.consumer >= db->nlong && db->services[i].x.longrun.nproducers) { - uint32_t k = db->services[j].x.longrun.pipeline[0] ; - if (k >= db->nlong) break ; - if (k == i || bitarray_peek(black, k)) + uint32_t j = check_prod_rec(&recinfo, i) ; + if (j < db->nlong) { problem->left = i ; - problem->right = k ; - return 1 + (k == i) ; + problem->right = j ; + return mark[j] & 4 ? 3 : mark[j] & 2 ? 2 : 1 ; } - j = k ; } - start = j ; - j = i ; - for (;;) + } + i = db->nlong ; + while (i--) + { + if (!mark[i] && db->services[i].x.longrun.nproducers) { - uint32_t k = db->services[j].x.longrun.pipeline[1] ; - if (k >= db->nlong) break ; - if (k == i || bitarray_peek(black, k)) - { - problem->left = i ; - problem->right = k ; - return 1 + (k == i) ; - } - j = k ; + problem->left = db->services[i].x.longrun.consumer ; + problem->right = i ; + return 1 ; } - for (j = start ; j > db->nlong ; j = db->services[j].x.longrun.pipeline[1]) - bitarray_set(black, j) ; } return 0 ; } diff --git a/src/libs6rc/s6rc_db_read.c b/src/libs6rc/s6rc_db_read.c index b3f9aed..717382f 100644 --- a/src/libs6rc/s6rc_db_read.c +++ b/src/libs6rc/s6rc_db_read.c @@ -11,7 +11,7 @@ #ifdef DEBUG #include <skalibs/lolstdio.h> -#define DBG(...) do { bprintf(buffer_2, "debug: ") ; bprintf(buffer_2, __VA_ARGS__) ; bprintf(buffer_2, "\n") ; buffer_flush(buffer_2) ; } while(0) +#define DBG(...) LOLDEBUG(__VA_ARGS__) #else #define DBG(...) #endif @@ -33,19 +33,19 @@ static inline int s6rc_db_check_valid_strings (char const *string, size_t string return 1 ; } -static inline int s6rc_db_read_deps (buffer *b, unsigned int max, uint32_t *deps, unsigned int ndeps) +static inline int s6rc_db_read_uints (buffer *b, unsigned int max, uint32_t *p, unsigned int n) { uint32_t x ; - ndeps <<= 1 ; - while (ndeps--) + while (n--) { if (!s6rc_db_read_uint32(b, &x)) return -1 ; if (x >= max) return 0 ; - *deps++ = x ; + *p++ = x ; } return 1 ; } + static inline int s6rc_db_read_services (buffer *b, s6rc_db_t *db) { unsigned int n = db->nshort + db->nlong ; @@ -89,8 +89,9 @@ static inline int s6rc_db_read_services (buffer *b, s6rc_db_t *db) #endif if (i < db->nlong) { - if (!s6rc_db_read_uint32(b, &sv->x.longrun.pipeline[0])) return -1 ; - if (!s6rc_db_read_uint32(b, &sv->x.longrun.pipeline[1])) return -1 ; + if (!s6rc_db_read_uint32(b, &sv->x.longrun.consumer)) return -1 ; + if (!s6rc_db_read_uint32(b, &sv->x.longrun.nproducers)) return -1 ; + if (!s6rc_db_read_uint32(b, &sv->x.longrun.producers)) return -1 ; } else { @@ -141,7 +142,9 @@ static inline int s6rc_db_read_buffer (buffer *b, s6rc_db_t *db) { int r = s6rc_db_read_string(b, db->string, db->stringlen) ; if (r < 1) return r ; - r = s6rc_db_read_deps(b, db->nshort + db->nlong, db->deps, db->ndeps) ; + r = s6rc_db_read_uints(b, db->nshort + db->nlong, db->deps, db->ndeps << 1) ; + if (r < 1) return r ; + r = s6rc_db_read_uints(b, db->nlong, db->producers, db->nproducers) ; if (r < 1) return r ; r = s6rc_db_read_services(b, db) ; if (r < 1) return r ; diff --git a/src/libs6rc/s6rc_db_read_sizes.c b/src/libs6rc/s6rc_db_read_sizes.c index c091ede..433af2e 100644 --- a/src/libs6rc/s6rc_db_read_sizes.c +++ b/src/libs6rc/s6rc_db_read_sizes.c @@ -20,16 +20,18 @@ static inline int s6rc_db_read_sizes_buffer (buffer *b, s6rc_db_t *db) db->nargvs = x ; if (!s6rc_db_read_uint32(b, &x)) return 0 ; db->ndeps = x ; + if (!s6rc_db_read_uint32(b, &x)) return 0 ; + db->nproducers = x ; return 1 ; } int s6rc_db_read_sizes (int fdcompiled, s6rc_db_t *db) { - char buf[64] ; + char buf[24] ; buffer b ; int fd = open_readatb(fdcompiled, "n") ; if (fd < 0) return 0 ; - buffer_init(&b, &buffer_read, fd, buf, 64) ; + buffer_init(&b, &buffer_read, fd, buf, 24) ; if (!s6rc_db_read_sizes_buffer(&b, db)) { fd_close(fd) ; |