summaryrefslogtreecommitdiff
path: root/src/libs6rc
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2017-11-04 13:19:12 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2017-11-04 13:19:12 +0000
commitc681d62a23a8b4ca2ecf0d6291a208ca323f0171 (patch)
treed69aed5c6dbab88ca8f781d6a345f0725a1d695e /src/libs6rc
parentbc64800b5399e3dabaf1e7d7bc13b14a2dc4bf42 (diff)
downloads6-rc-c681d62a23a8b4ca2ecf0d6291a208ca323f0171.tar.xz
Implement funnels. Needs testing.
Diffstat (limited to 'src/libs6rc')
-rw-r--r--src/libs6rc/s6rc_db_check_pipelines.c68
-rw-r--r--src/libs6rc/s6rc_db_read.c19
-rw-r--r--src/libs6rc/s6rc_db_read_sizes.c6
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) ;