Skip to content

Commit 5b6e13b

Browse files
committed
Multimaster first sign of life
1 parent cbdf8bb commit 5b6e13b

File tree

3 files changed

+202
-0
lines changed

3 files changed

+202
-0
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#ifndef DDD_H
2+
3+
#include <stdbool.h>
4+
#include "transaction.h"
5+
6+
typedef struct Node {
7+
struct Node* collision;
8+
struct Edge* edges; /* local subgraph */
9+
nodeid_t node_id;
10+
} Node;
11+
12+
typedef struct Edge {
13+
L2List node; /* node of list of outgoing eedges */
14+
struct Edge* next; /* list of edges of local subgraph */
15+
struct Vertex* dst;
16+
struct Vertex* src;
17+
} Edge;
18+
19+
typedef struct Vertex
20+
{
21+
L2List outgoingEdges;
22+
struct Vertex* next;
23+
xid_t xid;
24+
int nIncomingEdges;
25+
int visited;
26+
int deadlock_duration;
27+
} Vertex;
28+
29+
typedef struct Graph
30+
{
31+
Vertex* hashtable[MAX_TRANSACTIONS];
32+
Edge* freeEdges;
33+
Vertex* freeVertexes;
34+
int marker;
35+
int min_deadlock_duration;
36+
} Graph;
37+
38+
typedef struct Cluster
39+
{
40+
Node* hashtable[MAX_STREAMS];
41+
} Cluster;
42+
43+
extern void initGraph(Graph* graph);
44+
extern void addSubgraph(Graph* graph, nodeid_t node_id, xid_t* xids, int n_xids);
45+
extern bool detectDeadLock(Graph* graph, xid_t root);
46+
47+
#endif

contrib/multimaster/dtmd/src/ddd.c

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
#include <stddef.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
#include "ddd.h"
5+
6+
static bool recursiveTraverseGraph(Vertex* root, Vertex* v, int marker);
7+
8+
static Cluster cluster;
9+
10+
void initGraph(Graph* graph)
11+
{
12+
memset(graph->hashtable, 0, sizeof(graph->hashtable));
13+
graph->freeEdges = NULL;
14+
graph->freeVertexes = NULL;
15+
graph->marker = 0;
16+
}
17+
18+
static inline Edge* newEdge(Graph* graph)
19+
{
20+
Edge* edge = graph->freeEdges;
21+
if (edge == NULL) {
22+
edge = (Edge*)malloc(sizeof(Edge));
23+
} else {
24+
graph->freeEdges = edge->next;
25+
}
26+
return edge;
27+
}
28+
29+
static inline void freeVertex(Graph* graph, Vertex* vertex)
30+
{
31+
int h = vertex->xid % MAX_TRANSACTIONS;
32+
Vertex** vpp = &graph->hashtable[h];
33+
while (*vpp != vertex) {
34+
vpp = &(*vpp)->next;
35+
}
36+
*vpp = vertex->next;
37+
vertex->next = graph->freeVertexes;
38+
graph->freeVertexes = vertex;
39+
40+
}
41+
42+
static inline void freeEdge(Graph* graph, Edge* edge)
43+
{
44+
edge->next = graph->freeEdges;
45+
graph->freeEdges = edge;
46+
}
47+
48+
static inline Vertex* newVertex(Graph* graph)
49+
{
50+
Vertex* v = graph->freeVertexes;
51+
if (v == NULL) {
52+
v = (Vertex*)malloc(sizeof(Vertex));
53+
} else {
54+
graph->freeVertexes = v->next;
55+
}
56+
return v;
57+
}
58+
59+
static inline Vertex* findVertex(Graph* graph, xid_t xid)
60+
{
61+
xid_t h = xid % MAX_TRANSACTIONS;
62+
Vertex* v;
63+
for (v = graph->hashtable[h]; v != NULL; v = v->next) {
64+
if (v->xid == xid) {
65+
return v;
66+
}
67+
}
68+
v = newVertex(graph);
69+
l2_list_init(&v->outgoingEdges);
70+
v->xid = xid;
71+
v->nIncomingEdges = 0;
72+
v->next = graph->hashtable[h];
73+
graph->hashtable[h] = v;
74+
return v;
75+
}
76+
77+
static inline Node* findNode(Cluster* cluster, nodeid_t node_id)
78+
{
79+
size_t h = node_id % MAX_STREAMS;
80+
Node* node;
81+
for (node = cluster->hashtable[h]; node != NULL; node = node->collision) {
82+
if (node->node_id == node_id) {
83+
return node;
84+
}
85+
}
86+
node = (Node*)malloc(sizeof(Node));
87+
node->node_id = node_id;
88+
node->edges = NULL;
89+
node->collision = cluster->hashtable[h];
90+
cluster->hashtable[h] = node;
91+
return node;
92+
}
93+
94+
void addSubgraph(Graph* graph, nodeid_t node_id, xid_t* xids, int n_xids)
95+
{
96+
xid_t *last = xids + n_xids;
97+
Edge *e, *next, *edges = NULL;
98+
Node* node = findNode(&cluster, node_id);
99+
while (xids != last) {
100+
Vertex* src = findVertex(graph, *xids++);
101+
xid_t xid;
102+
while ((xid = *xids++) != 0) {
103+
Vertex* dst = findVertex(graph, xid);
104+
e = newEdge(graph);
105+
dst->nIncomingEdges += 1;
106+
e->dst = dst;
107+
e->src = src;
108+
e->next = edges;
109+
edges = e;
110+
l2_list_link(&src->outgoingEdges, &e->node);
111+
}
112+
}
113+
for (e = node->edges; e != NULL; e = next) {
114+
next = e->next;
115+
l2_list_unlink(&e->node);
116+
if (--e->dst->nIncomingEdges == 0 && l2_list_is_empty(&e->dst->outgoingEdges)) {
117+
freeVertex(graph, e->dst);
118+
}
119+
if (e->src->nIncomingEdges == 0 && l2_list_is_empty(&e->src->outgoingEdges)) {
120+
freeVertex(graph, e->src);
121+
}
122+
freeEdge(graph, e);
123+
}
124+
node->edges = edges;
125+
}
126+
127+
static bool recursiveTraverseGraph(Vertex* root, Vertex* v, int marker)
128+
{
129+
L2List* l;
130+
Edge* e;
131+
v->visited = marker;
132+
for (l = v->outgoingEdges.next; l != &v->outgoingEdges; l = e->node.next) {
133+
e = (Edge*)l;
134+
if (e->dst == root) {
135+
return true;
136+
} else if (e->dst->visited != marker && recursiveTraverseGraph(root, e->dst, marker)) { /* loop */
137+
return true;
138+
}
139+
}
140+
return false;
141+
}
142+
143+
bool detectDeadLock(Graph* graph, xid_t root)
144+
{
145+
Vertex* v;
146+
for (v = graph->hashtable[root % MAX_TRANSACTIONS]; v != NULL; v = v->next) {
147+
if (v->xid == root) {
148+
if (recursiveTraverseGraph(v, v, ++graph->marker)) {
149+
return true;
150+
}
151+
break;
152+
}
153+
}
154+
return false;
155+
}

contrib/multimaster/sockhub/sockhub

34 KB
Binary file not shown.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy