summaryrefslogtreecommitdiff
path: root/src/libs6rc/s6rc_db_check_pipelines.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs6rc/s6rc_db_check_pipelines.c')
-rw-r--r--src/libs6rc/s6rc_db_check_pipelines.c68
1 files changed, 41 insertions, 27 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 ;
}