Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
ccan
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mirror
ccan
Commits
dc251c89
Commit
dc251c89
authored
Jul 08, 2009
by
Rusty Russell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
First attempt at transactions & traverse (deadlocks still).
parent
2885bab4
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
114 additions
and
11 deletions
+114
-11
ccan/tdb/tools/replay_trace.c
ccan/tdb/tools/replay_trace.c
+114
-11
No files found.
ccan/tdb/tools/replay_trace.c
View file @
dc251c89
...
...
@@ -19,7 +19,10 @@
/* Avoid mod by zero */
static
unsigned
int
total_keys
=
1
;
/* #define DEBUG_DEPS 1 */
#define DEBUG_DEPS 1
/* Traversals block transactions in the current implementation. */
#define TRAVERSALS_TAKE_TRANSACTION_LOCK 1
struct
pipe
{
int
fd
[
2
];
...
...
@@ -123,15 +126,21 @@ struct op {
TDB_DATA
key
;
TDB_DATA
data
;
int
ret
;
/* Who is waiting for us? */
struct
list_head
post
;
/* How many are we waiting for? */
unsigned
int
pre
;
/* If I'm part of a group (traverse/transaction) where is
* start? (Otherwise, 0) */
unsigned
int
group_start
;
union
{
int
flag
;
/* open and store */
struct
traverse
*
trav
;
/* traverse start */
TDB_DATA
post_append
;
/* append */
unsigned
int
transaction_end
;
/* transaction start */
};
};
...
...
@@ -180,6 +189,7 @@ static void add_op(const char *filename, struct op **op, unsigned int i,
new
->
serial
=
serial
;
new
->
pre
=
0
;
new
->
ret
=
0
;
new
->
group_start
=
0
;
}
static
void
op_add_nothing
(
const
char
*
filename
,
...
...
@@ -278,6 +288,44 @@ static void op_add_traverse(const char *filename,
op
[
op_num
].
trav
=
NULL
;
}
static
void
op_add_transaction
(
const
char
*
filename
,
struct
op
op
[],
unsigned
int
op_num
,
char
*
words
[])
{
if
(
words
[
2
])
fail
(
filename
,
op_num
+
1
,
"Expect no arguments"
);
op
[
op_num
].
key
=
tdb_null
;
op
[
op_num
].
transaction_end
=
0
;
}
static
void
op_analyze_transaction
(
const
char
*
filename
,
struct
op
op
[],
unsigned
int
op_num
,
char
*
words
[])
{
int
i
,
start
;
op
[
op_num
].
key
=
tdb_null
;
if
(
words
[
2
])
fail
(
filename
,
op_num
+
1
,
"Expect no arguments"
);
for
(
i
=
op_num
-
1
;
i
>=
0
;
i
--
)
{
if
(
op
[
i
].
op
==
OP_TDB_TRANSACTION_START
&&
!
op
[
i
].
transaction_end
)
break
;
}
if
(
i
<
0
)
fail
(
filename
,
op_num
+
1
,
"no transaction start found"
);
start
=
i
;
op
[
start
].
transaction_end
=
op_num
;
/* This rolls in nested transactions. I think that's right. */
for
(
i
++
;
i
<=
op_num
;
i
++
)
op
[
i
].
group_start
=
start
;
}
struct
traverse_hash
{
TDB_DATA
key
;
unsigned
int
index
;
...
...
@@ -325,7 +373,7 @@ static void op_analyze_traverse(const char *filename,
struct
op
op
[],
unsigned
int
op_num
,
char
*
words
[])
{
int
i
;
int
i
,
start
;
struct
traverse
*
trav
=
talloc
(
op
,
struct
traverse
);
op
[
op_num
].
key
=
tdb_null
;
...
...
@@ -354,14 +402,18 @@ static void op_analyze_traverse(const char *filename,
if
(
i
<
0
)
fail
(
filename
,
op_num
+
1
,
"no traversal start found"
);
op
[
i
].
trav
=
trav
;
start
=
i
;
op
[
start
].
trav
=
trav
;
for
(
i
=
start
;
i
<=
op_num
;
i
++
)
op
[
i
].
group_start
=
start
;
if
(
is_trivial_traverse
(
op
+
i
,
op_num
-
i
))
{
/* Fill in a plentiful hash table. */
op
[
i
].
trav
->
hash
=
talloc_zero_array
(
op
[
i
].
trav
,
struct
traverse_hash
,
trav
->
num
*
2
);
for
(;
i
<
op_num
;
i
++
)
{
op
[
start
].
trav
->
hash
=
talloc_zero_array
(
op
[
i
].
trav
,
struct
traverse_hash
,
trav
->
num
*
2
);
for
(
i
=
start
;
i
<
op_num
;
i
++
)
{
unsigned
int
h
;
if
(
op
[
i
].
op
!=
OP_TDB_TRAVERSE
)
continue
;
...
...
@@ -500,18 +552,23 @@ static void do_pre(const char *filename, int pre_fd,
#if DEBUG_DEPS
printf
(
"%s:%u:waiting for pre
\n
"
,
filename
,
i
+
1
);
fflush
(
stdout
);
#endif
if
(
read
(
pre_fd
,
&
opnum
,
sizeof
(
opnum
))
!=
sizeof
(
opnum
))
errx
(
1
,
"Reading from pipe"
);
#if DEBUG_DEPS
printf
(
"%s:%u:got pre %u
\n
"
,
filename
,
i
+
1
,
opnum
);
printf
(
"%s:%u:got pre %u (%u)
\n
"
,
filename
,
i
+
1
,
opnum
+
1
,
op
[
opnum
].
pre
);
fflush
(
stdout
);
#endif
/* This could be any op, not just this one. */
if
(
op
[
opnum
].
pre
==
0
)
errx
(
1
,
"Got
unexpected
notification for op line %u"
,
errx
(
1
,
"Got
extra
notification for op line %u"
,
opnum
+
1
);
if
(
opnum
<
i
)
errx
(
1
,
"%s:%u: got late notification for line %u"
,
filename
,
i
+
1
,
opnum
+
1
);
op
[
opnum
].
pre
--
;
}
}
...
...
@@ -523,7 +580,7 @@ static void do_post(const char *filename, const struct op op[], unsigned int i)
list_for_each
(
&
op
[
i
].
post
,
dep
,
list
)
{
#if DEBUG_DEPS
printf
(
"%s:%u:sending %u to file %u
\n
"
,
filename
,
i
+
1
,
dep
->
op
,
dep
->
file
);
dep
->
op
+
1
,
dep
->
file
);
#endif
if
(
write
(
pipes
[
dep
->
file
].
fd
[
1
],
&
dep
->
op
,
sizeof
(
dep
->
op
))
!=
sizeof
(
dep
->
op
))
...
...
@@ -821,6 +878,43 @@ static void add_dependency(void *ctx,
unsigned
int
satisfies_opnum
)
{
struct
depend
*
post
;
unsigned
int
needs_start
,
sat_start
;
needs_start
=
op
[
needs_file
][
needs_opnum
].
group_start
;
sat_start
=
op
[
satisfies_file
][
satisfies_opnum
].
group_start
;
/* If needs is in a transaction, we need it before start. */
if
(
needs_start
)
{
switch
(
op
[
needs_file
][
needs_start
].
op
)
{
case
OP_TDB_TRANSACTION_START
:
#if TRAVERSALS_TAKE_TRANSACTION_LOCK
case
OP_TDB_TRAVERSE_START
:
case
OP_TDB_TRAVERSE_READ_START
:
#endif
needs_opnum
=
needs_start
;
#ifdef DEBUG_DEPS
printf
(
" -> Back to %u
\n
"
,
needs_start
+
1
);
fflush
(
stdout
);
#endif
break
;
default:
break
;
}
}
/* If satisfies is in a transaction, we wait until after commit. */
/* FIXME: If transaction is cancelled, don't need dependency. */
if
(
sat_start
)
{
if
(
op
[
satisfies_file
][
sat_start
].
op
==
OP_TDB_TRANSACTION_START
)
{
satisfies_opnum
=
op
[
satisfies_file
][
sat_start
].
transaction_end
;
#ifdef DEBUG_DEPS
printf
(
" -> Depends on %u
\n
"
,
satisfies_opnum
+
1
);
fflush
(
stdout
);
#endif
}
}
post
=
talloc
(
ctx
,
struct
depend
);
post
->
file
=
needs_file
;
...
...
@@ -828,6 +922,14 @@ static void add_dependency(void *ctx,
list_add
(
&
op
[
satisfies_file
][
satisfies_opnum
].
post
,
&
post
->
list
);
op
[
needs_file
][
needs_opnum
].
pre
++
;
#ifdef DEBUG_DEPS
if
(
op
[
needs_file
][
needs_opnum
].
pre
>
1
)
{
printf
(
" (File %u opnum %u hash %u needs)
\n
"
,
needs_file
,
needs_opnum
+
1
,
op
[
needs_file
][
needs_opnum
].
pre
);
fflush
(
stdout
);
}
#endif
}
static
void
derive_dependencies
(
char
*
filename
[],
...
...
@@ -855,6 +957,7 @@ static void derive_dependencies(char *filename[],
hash
[
i
].
user
[
j
].
op_num
+
1
,
filename
[
hash
[
i
].
user
[
j
-
1
].
file
],
hash
[
i
].
user
[
j
-
1
].
op_num
+
1
);
fflush
(
stdout
);
#endif
add_dependency
(
hash
,
op
,
hash
[
i
].
user
[
j
].
file
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment