Commit 61f58ff9 authored by David Gibson's avatar David Gibson

Merge Makefile rewrite into master

# Conflicts:
#	.travis.yml
#	Makefile
#	Makefile-ccan
parents 68c74ffd 9dbf8b3f
...@@ -8,7 +8,11 @@ compiler: ...@@ -8,7 +8,11 @@ compiler:
addons: addons:
apt: apt:
packages: packages:
- libjudy-dev libvorbis-dev libportaudio-dev libtalloc-dev - libjudy-dev
- libvorbis-dev
- libportaudio-dev
- libtalloc-dev
script: script:
- make -j2 -k check quiet=1 - make -j2 -k quiet=1
- make -k check quiet=1
...@@ -11,6 +11,7 @@ WARN_CFLAGS := -Wall -Wstrict-prototypes -Wold-style-definition -Wundef \ ...@@ -11,6 +11,7 @@ WARN_CFLAGS := -Wall -Wstrict-prototypes -Wold-style-definition -Wundef \
-Wmissing-prototypes -Wmissing-declarations -Wpointer-arith -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wpointer-arith -Wwrite-strings
DEP_CFLAGS = -MMD -MP -MF$(@:%=%.d) -MT$@ DEP_CFLAGS = -MMD -MP -MF$(@:%=%.d) -MT$@
CCAN_CFLAGS := -g3 -ggdb $(WARN_CFLAGS) -DCCAN_STR_DEBUG=1 -I. $(CFLAGS) CCAN_CFLAGS := -g3 -ggdb $(WARN_CFLAGS) -DCCAN_STR_DEBUG=1 -I. $(CFLAGS)
CFLAGS_FORCE_C_SOURCE := -x c
# Anything with an _info file is a module ... # Anything with an _info file is a module ...
INFO_SRCS := $(wildcard ccan/*/_info ccan/*/*/_info) INFO_SRCS := $(wildcard ccan/*/_info ccan/*/*/_info)
...@@ -32,7 +33,7 @@ DEPS := $(OBJS:%=%.d) ...@@ -32,7 +33,7 @@ DEPS := $(OBJS:%=%.d)
# _info files are compiled into executables and don't need dependencies # _info files are compiled into executables and don't need dependencies
%info : %_info config.h %info : %_info config.h
$(PRE)$(CC) $(CCAN_CFLAGS) -I. -o $@ -x c $< $(PRE)$(CC) $(CCAN_CFLAGS) -I. -o $@ $(CFLAGS_FORCE_C_SOURCE) $<
# config.h is built by configurator which has no ccan dependencies # config.h is built by configurator which has no ccan dependencies
CONFIGURATOR := tools/configurator/configurator CONFIGURATOR := tools/configurator/configurator
......
# AppVeyor CI Configuration
#
# Current build status can be viewed at
# https://ci.appveyor.com/project/dgibson/ccan
#
# To build test a fork of this repository using AppVeyor:
# 1. Visit appveyor.com and create a free account.
# 2. On the Projects tab, select "New Project" then the project hosting site.
# 3. Grant OAuth permissions to your project git host.
# 4. Select the repository for your project fork.
# 5. Review build results and push updates until the desired result is reached.
version: 0.0.{build}
platform:
- x86
- amd64
build_script:
# Reset %PATH% to avoid msys/cygwin DLL conflicts which cause
# *** fatal error - cygheap base mismatch detected
- set PATH=C:\Windows\System32;C:\Windows;C:\Windows\System32\Wbem;C:\msys64\usr\bin
# Set environment variables for chosen compiler
- "\"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\vcvarsall.bat\" %Platform%"
# Ensure config.h can be generated.
# Note: Dash options avoid POSIX path conversion by msys
- "make config.h CC=cl CCAN_CFLAGS=\"-nologo -Zi -FS -W4 -wd4200 -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS\" CFLAGS_FORCE_C_SOURCE=-TC OUTPUT_OPTION=-Fo:$@ DEPGEN= LD=link SHELL=bash"
# FIXME: Work in progress. Disabled due to unfixed compile errors.
# FIXME: -j%NUMBER_OF_PROCESSORS% won't work without DEPGEN for config.h
# It may be possible to generate .d from cl using /showIncludes
# See https://stackoverflow.com/q/37685069
#- "make tools CC=cl CCAN_CFLAGS=\"-nologo -Zi -FS -W4 -wd4200 -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS\" CFLAGS_FORCE_C_SOURCE=-TC OUTPUT_OPTION=-Fo:$@ DEPGEN= LD=link SHELL=bash"
#- "make -k CC=cl CCAN_CFLAGS=\"-nologo -Zi -FS -W4 -wd4200 -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS\" CFLAGS_FORCE_C_SOURCE=-TC OUTPUT_OPTION=-Fo:$@ DEPGEN= LD=link SHELL=bash"
test_script:
# FIXME: Work in progress. Disabled due to unfixed compile errors.
#- "make -k check CC=cl CCAN_CFLAGS=\"-nologo -Zi -FS -W4 -wd4200 -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS\" CFLAGS_FORCE_C_SOURCE=-TC OUTPUT_OPTION=-Fo:$@ DEPGEN= LD=link SHELL=bash"
...@@ -165,6 +165,12 @@ struct aga_node { ...@@ -165,6 +165,12 @@ struct aga_node {
bool complete; bool complete;
struct lpq_link pqlink; struct lpq_link pqlink;
} dijkstra; } dijkstra;
struct {
aga_icost_t distance;
struct aga_node *prev;
const void *prevedge;
struct aga_node *list;
} bellman_ford;
} u; } u;
}; };
...@@ -177,6 +183,11 @@ struct aga_graph { ...@@ -177,6 +183,11 @@ struct aga_graph {
aga_edge_info_fn edge_info; aga_edge_info_fn edge_info;
union { union {
LPQ(struct aga_node, u.dijkstra.pqlink) dijkstra; LPQ(struct aga_node, u.dijkstra.pqlink) dijkstra;
struct {
struct aga_node *nodelist;
int nnodes;
int npasses;
} bellman_ford;
} state; } state;
}; };
...@@ -347,7 +358,7 @@ struct aga_node *aga_bfs_explore(struct aga_graph *g, struct aga_node *n); ...@@ -347,7 +358,7 @@ struct aga_node *aga_bfs_explore(struct aga_graph *g, struct aga_node *n);
* *
* Performs a breadth first search. The block following this macro is * Performs a breadth first search. The block following this macro is
* executed with @_n set first to @_start, then to each node reachable * executed with @_n set first to @_start, then to each node reachable
* from @_start in depth first search order. * from @_start in breadth-first search order.
* *
* aga_bfs_start() must be called before this macro is used. * aga_bfs_start() must be called before this macro is used.
*/ */
...@@ -416,15 +427,74 @@ bool aga_dijkstra_path(struct aga_graph *g, struct aga_node *dest, ...@@ -416,15 +427,74 @@ bool aga_dijkstra_path(struct aga_graph *g, struct aga_node *dest,
struct aga_node **prev, const void **prevedge); struct aga_node **prev, const void **prevedge);
/** /**
* aga_dijkstra_all_paths - Find shortest paths to all reachable nodes * aga_dijkstra_complete - Find shortest paths to all reachable nodes
* @g: graph * @g: graph
* *
* Finds shortest paths from the source node (specified in * Finds shortest paths from the source node (specified in
* aga_dijkstra_start()) to all other reachable nodes in @g. No * aga_dijkstra_start()) to all other reachable nodes in @g. No
* results are returned directly, but between calling * results are returned directly, but between calling
* aga_dijkstra_all_paths() and aga_finish, aga_dijkstra_path() is * aga_dijkstra_all_paths() and aga_finish(), aga_dijkstra_path() is
* guaranteed to complete in O(1) time for all destinations. * guaranteed to complete in O(1) time for all destinations.
*/ */
void aga_dijkstra_all_paths(struct aga_graph *g); void aga_dijkstra_complete(struct aga_graph *g);
/*
* Bellman-Ford algorithm
*/
/**
* aga_bellman_ford_start - Start Bellman-Ford algorithm
* @g: graph
* @source: source node
*
* Start's the Bellman-Ford algorithm on @g to find shortest paths
* from node @source, to other nodes in @g.
*/
int aga_bellman_ford_start(struct aga_graph *g, struct aga_node *source);
/**
* aga_bellman_ford_path - Find the shortest path to a node
* @g: graph
* @dest: destination node
* @prev: Second last node in the path *output)
* @prevedge: Last edge in the path
*
* Finds the shortest path from the source node (specified in
* aga_bellman_ford_start() to @dest using Bellman_Ford's algorithm.
*
* If no path exists, return false.
*
* If a path does exist, returns true. Additionally if @total_cost is
* non-NULL, store the total cost of the path in *@total_cost, if
* @prev is non-NULL, store the node in the path immediately before
* @dest in *@prev and if @prevedge is non-NULL stores the edge which
* leads from *@prev to @dest in *@prevedge.
*
* If @dest is the same as source, 0 will be stored in @cost, and NULL
* will be stored in *@prev and *@prevedge.
*
* The full path from source to @dest can be determined by repeatedly
* calling aga_bellman_ford_path() on *@prev.
*
* NOTE: Bellman_Ford's algorithm will not work correctly on a graph
* which contains a cycle with (total) negative cost. If aga detects
* this case, it will set aga_error() to AGA_ERR_NEGATIVE_COST.
*/
bool aga_bellman_ford_path(struct aga_graph *g, struct aga_node *dest,
aga_icost_t *total_cost,
struct aga_node **prev, const void **prevedge);
/**
* aga_bellman_ford_complete - Run Bellman-Ford algorithm to completion
* @g: graph
*
* Finds shortest paths from the source node (specified in
* aga_bellman_ford_start()) to all other reachable nodes in @g. No
* results are returned directly, but between calling
* aga_bellman_ford_complete() and aga_finish(),
* aga_bellman_ford_path() is guaranteed to complete in O(1) time for
* all destinations.
*/
void aga_bellman_ford_complete(struct aga_graph *g);
#endif /* CCAN_AGA_H */ #endif /* CCAN_AGA_H */
/* Licensed under LGPLv2+ - see LICENSE file for details */
#include "config.h"
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
#include <ccan/build_assert/build_assert.h>
#include <ccan/check_type/check_type.h>
#include <ccan/order/order.h>
#include <ccan/aga/aga.h>
#include "private.h"
/*
* The Bellman-Ford algorithm
*/
static bool candidate_path(struct aga_graph *g, struct aga_node *node,
aga_icost_t distance,
struct aga_node *prev, const void *prevedge)
{
if (aga_update_node(g, node)) {
/* New node, treat as having infinite distance */
node->u.bellman_ford.distance = distance;
node->u.bellman_ford.prev = prev;
node->u.bellman_ford.prevedge = prevedge;
node->u.bellman_ford.list = g->state.bellman_ford.nodelist;
g->state.bellman_ford.nodelist = node;
g->state.bellman_ford.nnodes++;
return true;
} else if (distance < node->u.bellman_ford.distance) {
node->u.bellman_ford.distance = distance;
node->u.bellman_ford.prev = prev;
node->u.bellman_ford.prevedge = prevedge;
}
return false;
}
int aga_bellman_ford_start(struct aga_graph *g, struct aga_node *source)
{
int rc;
/* Make sure we're actually using the right ordering for
* aga_icost_t */
BUILD_ASSERT(check_types_match(long, aga_icost_t) == 0);
rc = aga_start(g);
if (rc < 0)
return rc;
g->state.bellman_ford.nodelist = NULL;
g->state.bellman_ford.nnodes = 0;
g->state.bellman_ford.npasses = 0;
candidate_path(g, source, 0, NULL, NULL);
return 0;
}
static bool aga_bellman_ford_step(struct aga_graph *g)
{
struct aga_node *n;
const void *e;
struct aga_edge_info ei;
int err;
bool newnode = false;
if (!aga_check_state(g))
return false;
for (n = g->state.bellman_ford.nodelist;
n; n = n->u.bellman_ford.list) {
aga_for_each_edge_info(e, ei, err, g, n) {
aga_icost_t dist = n->u.bellman_ford.distance
+ ei.icost;
newnode = newnode || candidate_path(g, ei.to, dist, n, e);
}
if (err) {
aga_fail(g, err);
return false;
}
}
g->state.bellman_ford.npasses++;
return newnode || (g->state.bellman_ford.npasses
< g->state.bellman_ford.nnodes);
}
void aga_bellman_ford_complete(struct aga_graph *g)
{
struct aga_node *n;
const void *e;
struct aga_edge_info ei;
int err;
if (!aga_check_state(g))
return;
while (aga_bellman_ford_step(g))
;
/* Check for negative cycles */
for (n = g->state.bellman_ford.nodelist;
n; n = n->u.bellman_ford.list) {
aga_for_each_edge_info(e, ei, err, g, n) {
if ((n->u.bellman_ford.distance + ei.icost)
< ei.to->u.bellman_ford.distance) {
aga_fail(g, AGA_ERR_NEGATIVE_COST);
return;
}
}
if (err) {
aga_fail(g, err);
return;
}
}
}
bool aga_bellman_ford_path(struct aga_graph *g, struct aga_node *node,
aga_icost_t *total_cost,
struct aga_node **prev, const void **prevedge)
{
aga_bellman_ford_complete(g);
if (!aga_check_state(g))
return false;
if (aga_node_needs_update(g, node))
return false;
if (total_cost)
*total_cost = node->u.bellman_ford.distance;
if (prev)
*prev = node->u.bellman_ford.prev;
if (prevedge)
*prevedge = node->u.bellman_ford.prevedge;
return true;
}
...@@ -114,7 +114,7 @@ bool aga_dijkstra_path(struct aga_graph *g, struct aga_node *node, ...@@ -114,7 +114,7 @@ bool aga_dijkstra_path(struct aga_graph *g, struct aga_node *node,
return true; return true;
} }
void aga_dijkstra_all_paths(struct aga_graph *g) void aga_dijkstra_complete(struct aga_graph *g)
{ {
if (!aga_check_state(g)) if (!aga_check_state(g))
return; return;
......
...@@ -63,8 +63,9 @@ int main(void) ...@@ -63,8 +63,9 @@ int main(void)
struct traversal1_graph t1g; struct traversal1_graph t1g;
struct shortcut1_graph s1g; struct shortcut1_graph s1g;
struct shortcut2_graph s2g; struct shortcut2_graph s2g;
struct negacycle_graph ng;
plan_tests(2 + 7 + 35 + 30 + 30 + 42 + 9 + 30 + 9 + 9); plan_tests(2 + 7 + 35 + 30 + 30 + 42 + 9 + 30 + 9 + 9 + 9);
trivial_graph_init(&tg); trivial_graph_init(&tg);
test_adjacency("trivial", &tg.sg, trivial_adjacency); test_adjacency("trivial", &tg.sg, trivial_adjacency);
...@@ -99,5 +100,8 @@ int main(void) ...@@ -99,5 +100,8 @@ int main(void)
shortcut2_graph_init(&s2g); shortcut2_graph_init(&s2g);
test_adjacency("shortcut2 graph", &s2g.sg, shortcut2_adjacency); test_adjacency("shortcut2 graph", &s2g.sg, shortcut2_adjacency);
negacycle_graph_init(&ng);
test_adjacency("negacycle graph", &ng.sg, negacycle_adjacency);
return exit_status(); return exit_status();
} }
#include "config.h"
#include <stddef.h>
#include <assert.h>
#include <stdlib.h>
#include <ccan/tap/tap.h>
#include <ccan/array_size/array_size.h>
#include <ccan/aga/aga.h>
#include "simple-graph.h"
static void test_trivial(void)
{
struct trivial_graph tg;
aga_icost_t cost;
struct aga_node *node;
const void *edge;
trivial_graph_init(&tg);
ok1(aga_bellman_ford_start(&tg.sg.g, &tg.sg.nodes[1]) == 0);
ok1(aga_bellman_ford_path(&tg.sg.g, &tg.sg.nodes[1], &cost, &node, &edge));
ok1(cost == 0);
ok1(node == NULL);
ok1(edge == NULL);
aga_finish(&tg.sg.g);
}
static void test_parallel(void)
{
struct parallel_graph pg;
aga_icost_t cost;
struct aga_node *node;
const void *edge;
parallel_graph_init(&pg, 3, 0);
ok1(aga_bellman_ford_start(&pg.sg.g, &pg.sg.nodes[1]) == 0);
ok1(aga_bellman_ford_path(&pg.sg.g, &pg.sg.nodes[1], &cost, NULL, NULL));
ok1(cost == 0);
ok1(aga_bellman_ford_path(&pg.sg.g, &pg.sg.nodes[2], &cost, &node, NULL));
ok1(cost == 2);
ok1(node == &pg.sg.nodes[1]);
aga_finish(&pg.sg.g);
ok1(aga_bellman_ford_start(&pg.sg.g, &pg.sg.nodes[2]) == 0);
ok1(aga_bellman_ford_path(&pg.sg.g, &pg.sg.nodes[2], &cost, NULL, NULL));
ok1(cost == 0);
ok1(!aga_bellman_ford_path(&pg.sg.g, &pg.sg.nodes[1], NULL, NULL, NULL));
aga_finish(&pg.sg.g);
parallel_graph_init(&pg, 3, 2);
ok1(aga_bellman_ford_start(&pg.sg.g, &pg.sg.nodes[1]) == 0);
ok1(aga_bellman_ford_path(&pg.sg.g, &pg.sg.nodes[2], &cost, &node, &edge));
ok1(cost == 1);
ok1(node == &pg.sg.nodes[1]);
ok1(ptr2int(edge) == 2);
aga_finish(&pg.sg.g);
}
#define FULL_LEN 4
static void test_full(void)
{
struct full_graph fg;
int i, j;
full_graph_init(&fg, FULL_LEN);
for (i = 1; i <= FULL_LEN; i++) {
ok1(aga_bellman_ford_start(&fg.sg.g, &fg.sg.nodes[i]) == 0);
for (j = 1; j <= FULL_LEN; j++) {
aga_icost_t cost;
struct aga_node *node;
const void *edge;
ok1(aga_bellman_ford_path(&fg.sg.g, &fg.sg.nodes[j],
&cost, &node, &edge));
if (i == j) {
ok1(cost == 0);
ok1(node == NULL);
ok1(edge == NULL);
} else {
ok1(cost == 1);
ok1(node == &fg.sg.nodes[i]);
ok1(edge == &fg.sg.nodes[j]);
}
}
aga_finish(&fg.sg.g);
}
}
#define CHAIN_LEN 8
static void test_chain(void)
{
struct chain_graph cg;
int i, j;
chain_graph_init(&cg, CHAIN_LEN);
for (i = 1; i <= CHAIN_LEN; i++) {
ok1(aga_bellman_ford_start(&cg.fg.sg.g, &cg.fg.sg.nodes[i]) == 0);
for (j = 1; j <= CHAIN_LEN; j++) {
aga_icost_t cost;
ok1(aga_bellman_ford_path(&cg.fg.sg.g, &cg.fg.sg.nodes[j],
&cost, NULL, NULL));
ok1(cost == labs(i - j));
}
aga_finish(&cg.fg.sg.g);
}
}
static void test_error(void)
{
struct error_graph eg;
aga_icost_t cost;
error_graph_init(&eg);
ok1(aga_bellman_ford_start(&eg.sg.g, &eg.sg.nodes[1]) == 0);
ok1(aga_bellman_ford_path(&eg.sg.g, &eg.sg.nodes[1], &cost, NULL, NULL));
ok1(cost == 0);
ok1(aga_bellman_ford_path(&eg.sg.g, &eg.sg.nodes[2], &cost, NULL, NULL));
ok1(cost == 1);
ok1(!aga_bellman_ford_path(&eg.sg.g, &eg.sg.nodes[3], &cost, NULL, NULL));
ok1(!aga_bellman_ford_path(&eg.sg.g, &eg.sg.nodes[4], &cost, NULL, NULL));
aga_finish(&eg.sg.g);
ok1(aga_bellman_ford_start(&eg.sg.g, &eg.sg.nodes[3]) == 0);
aga_bellman_ford_complete(&eg.sg.g);
ok1(!aga_bellman_ford_path(&eg.sg.g, &eg.sg.nodes[4], &cost, NULL, NULL));
ok1(aga_error(&eg.sg.g) == -1);
aga_finish(&eg.sg.g);
}
static void test_traversal1(void)
{
struct traversal1_graph t1g;
aga_icost_t cost;
/* This is mostly about testing we correctly handle
* non-reachable nodes */
traversal1_graph_init(&t1g);
ok1(aga_bellman_ford_start(&t1g.sg.g, &t1g.sg.nodes[1]) == 0);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[1],
&cost, NULL, NULL));
ok1(cost == 0);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[2],
&cost, NULL, NULL));
ok1(cost == 1);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[3],
&cost, NULL, NULL));
ok1(cost == 1);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[4],
&cost, NULL, NULL));
ok1(cost == 2);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[5],
&cost, NULL, NULL));
ok1(cost == 2);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[6],
&cost, NULL, NULL));
ok1(cost == 2);
ok1(!aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[7],
NULL, NULL, NULL));
ok1(!aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[8],
NULL, NULL, NULL));
ok1(!aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[9],
NULL, NULL, NULL));
aga_finish(&t1g.sg.g);
ok1(aga_bellman_ford_start(&t1g.sg.g, &t1g.sg.nodes[9]) == 0);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[9],
&cost, NULL, NULL));
ok1(cost == 0);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[8],
&cost, NULL, NULL));
ok1(cost == 1);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[7],
&cost, NULL, NULL));
ok1(cost == 1);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[6],
&cost, NULL, NULL));
ok1(cost == 2);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[5],
&cost, NULL, NULL));
ok1(cost == 2);
ok1(aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[4],
&cost, NULL, NULL));
ok1(cost == 2);
ok1(!aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[3],
NULL, NULL, NULL));
ok1(!aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[2],
NULL, NULL, NULL));
ok1(!aga_bellman_ford_path(&t1g.sg.g, &t1g.sg.nodes[1],
NULL, NULL, NULL));
aga_finish(&t1g.sg.g);
}
static void test_shortcut1(void)
{
struct shortcut1_graph s1g;
aga_icost_t cost;
struct aga_node *node;
shortcut1_graph_init(&s1g);
ok1(aga_bellman_ford_start(&s1g.sg.g, &s1g.sg.nodes[1]) == 0);
ok1(aga_bellman_ford_path(&s1g.sg.g, &s1g.sg.nodes[3],
&cost, &node, NULL));
ok1(cost == 2);
ok1(node == &s1g.sg.nodes[2]);
ok1(aga_bellman_ford_path(&s1g.sg.g, &s1g.sg.nodes[2],
&cost, &node, NULL));
ok1(cost == 1);
ok1(node == &s1g.sg.nodes[1]);
aga_finish(&s1g.sg.g);
}
static void test_shortcut2(void)
{
struct shortcut2_graph s2g;
aga_icost_t cost;
struct aga_node *node;
shortcut2_graph_init(&s2g);
ok1(aga_bellman_ford_start(&s2g.sg.g, &s2g.sg.nodes[1]) == 0);
ok1(aga_bellman_ford_path(&s2g.sg.g, &s2g.sg.nodes[3],
&cost, &node, NULL));
ok1(cost == 1);
ok1(node == &s2g.sg.nodes[2]);
ok1(aga_bellman_ford_path(&s2g.sg.g, &s2g.sg.nodes[2],
&cost, &node, NULL));
ok1(cost == 2);
ok1(node == &s2g.sg.nodes[1]);
aga_finish(&s2g.sg.g);
}
static void test_negacycle(void)
{
struct negacycle_graph ng;
negacycle_graph_init(&ng);
ok1(aga_bellman_ford_start(&ng.sg.g, &ng.sg.nodes[1]) == 0);
aga_bellman_ford_complete(&ng.sg.g);
ok1(aga_error(&ng.sg.g) == AGA_ERR_NEGATIVE_COST);
aga_finish(&ng.sg.g);
}
int main(void)
{
plan_tests(5 + 15
+ FULL_LEN * (1 + FULL_LEN * 4)
+ CHAIN_LEN * (1 + CHAIN_LEN * 2)
+ 10 + 32 + 7 + 7 + 2);
test_trivial();
test_parallel();
test_full();
test_chain();
test_error();
test_traversal1();
test_shortcut1();
test_shortcut2();
test_negacycle();
return exit_status();
}
...@@ -42,9 +42,10 @@ int main(void) ...@@ -42,9 +42,10 @@ int main(void)
struct grid_graph gg1, gg2; struct grid_graph gg1, gg2;
struct error_graph eg; struct error_graph eg;
struct traversal1_graph t1g; struct traversal1_graph t1g;
struct negacycle_graph ng;
struct aga_node *node; struct aga_node *node;
plan_tests(2 * 13 + 10 + 10); plan_tests(2 * 13 + 10 + 10 + 6);
trivial_graph_init(&tg); trivial_graph_init(&tg);
test_bfs(&tg.sg, 1, 1); test_bfs(&tg.sg, 1, 1);
...@@ -100,5 +101,10 @@ int main(void) ...@@ -100,5 +101,10 @@ int main(void)
test_bfs_partial(&t1g.sg, 1, 1, 2, 3); test_bfs_partial(&t1g.sg, 1, 1, 2, 3);
aga_finish(&t1g.sg.g); aga_finish(&t1g.sg.g);
negacycle_graph_init(&ng);
test_bfs(&ng.sg, 1, 1, 2, 3);
test_bfs(&ng.sg, 2, 2, 3, 1);
test_bfs(&ng.sg, 3, 3, 1, 2);
return exit_status(); return exit_status();
} }
...@@ -42,9 +42,10 @@ int main(void) ...@@ -42,9 +42,10 @@ int main(void)
struct grid_graph gg1, gg2; struct grid_graph gg1, gg2;
struct error_graph eg; struct error_graph eg;
struct traversal1_graph t1g; struct traversal1_graph t1g;
struct negacycle_graph ng;
struct aga_node *node; struct aga_node *node;
plan_tests(2 * 13 + 10 + 10); plan_tests(2 * 13 + 10 + 10 + 6);
trivial_graph_init(&tg); trivial_graph_init(&tg);
test_dfs(&tg.sg, 1, 1); test_dfs(&tg.sg, 1, 1);
...@@ -100,5 +101,10 @@ int main(void) ...@@ -100,5 +101,10 @@ int main(void)
test_dfs_partial(&t1g.sg, 1, 1, 2, 3); test_dfs_partial(&t1g.sg, 1, 1, 2, 3);
aga_finish(&t1g.sg.g); aga_finish(&t1g.sg.g);
negacycle_graph_init(&ng);
test_dfs(&ng.sg, 1, 1, 2, 3);
test_dfs(&ng.sg, 2, 2, 3, 1);
test_dfs(&ng.sg, 3, 3, 1, 2);
return exit_status(); return exit_status();
} }
...@@ -241,17 +241,29 @@ static void test_shortcut2(void) ...@@ -241,17 +241,29 @@ static void test_shortcut2(void)
shortcut2_graph_init(&s2g); shortcut2_graph_init(&s2g);
ok1(aga_dijkstra_start(&s2g.sg.g, &s2g.sg.nodes[1]) == 0); ok1(aga_dijkstra_start(&s2g.sg.g, &s2g.sg.nodes[1]) == 0);
aga_dijkstra_all_paths(&s2g.sg.g); aga_dijkstra_complete(&s2g.sg.g);
ok1(aga_error(&s2g.sg.g) == AGA_ERR_NEGATIVE_COST); ok1(aga_error(&s2g.sg.g) == AGA_ERR_NEGATIVE_COST);
aga_finish(&s2g.sg.g); aga_finish(&s2g.sg.g);
} }
static void test_negacycle(void)
{
struct negacycle_graph ng;
negacycle_graph_init(&ng);
ok1(aga_dijkstra_start(&ng.sg.g, &ng.sg.nodes[1]) == 0);
aga_dijkstra_complete(&ng.sg.g);
ok1(aga_error(&ng.sg.g) == AGA_ERR_NEGATIVE_COST);
aga_finish(&ng.sg.g);
}
int main(void) int main(void)
{ {
plan_tests(7 + 20 plan_tests(7 + 20
+ FULL_LEN * (1 + FULL_LEN*4) + FULL_LEN * (1 + FULL_LEN*4)
+ CHAIN_LEN * (1 + CHAIN_LEN*2) + CHAIN_LEN * (1 + CHAIN_LEN*2)
+ 12 + 32 + 7 + 2); + 12 + 32 + 7 + 2 + 2);
test_trivial(); test_trivial();
test_parallel(); test_parallel();
...@@ -261,6 +273,7 @@ int main(void) ...@@ -261,6 +273,7 @@ int main(void)
test_traversal1(); test_traversal1();
test_shortcut1(); test_shortcut1();
test_shortcut2(); test_shortcut2();
test_negacycle();
return exit_status(); return exit_status();
} }
#include "config.h"
#include <assert.h>
#include <ccan/container_of/container_of.h>
#include <ccan/ptrint/ptrint.h>
#include <ccan/aga/aga.h>
#include "simple-graph.h"
static ptrint_t *negacycle_first_edge(const struct aga_graph *g,
const struct aga_node *n)
{
return int2ptr(1);
}
static ptrint_t *negacycle_next_edge(const struct aga_graph *g,
const struct aga_node *n,
ptrint_t *e)
{
assert(ptr2int(e) == 1);
return NULL;
}
static int negacycle_edge_info(const struct aga_graph *g,
const struct aga_node *n,
ptrint_t *e, struct aga_edge_info *ei)
{
struct negacycle_graph *ng = container_of(g, struct negacycle_graph,
sg.g);
int ni = n - ng->sg.nodes;
assert(ptr2int(e) == 1);
ei->to = &ng->sg.nodes[(ni % 3) + 1];
if (ni == 3)
ei->icost = -3;
return 0;
}
void negacycle_graph_init(struct negacycle_graph *ng)
{
simple_graph_init(&ng->sg, negacycle_first_edge,
negacycle_next_edge,
negacycle_edge_info);
}
...@@ -256,4 +256,23 @@ static const struct adjacency_list shortcut2_adjacency[] = { ...@@ -256,4 +256,23 @@ static const struct adjacency_list shortcut2_adjacency[] = {
{}, {},
}; };
/* Negacycle graph
*
* A <---- (-3) ----- C
* \ ^
* (1)-> B -- (1)-/
*
* Graph with a negative length cycle, and so lacking well-defined shortest paths.
*/
struct negacycle_graph {
struct simple_graph sg;
};
void negacycle_graph_init(struct negacycle_graph *ng);
static const struct adjacency_list negacycle_adjacency[] = {
{1, {2}},
{2, {3}},
{3, {1}},
{},
};
#endif /* _TEST_GRAPHS_H */ #endif /* _TEST_GRAPHS_H */
...@@ -286,8 +286,53 @@ bool agar_dijkstra_path(struct agar_state *sr, const void *destr, ...@@ -286,8 +286,53 @@ bool agar_dijkstra_path(struct agar_state *sr, const void *destr,
return true; return true;
} }
void agar_dijkstra_all_paths(struct agar_state *sr) void agar_dijkstra_complete(struct agar_state *sr)
{ {
aga_dijkstra_all_paths(&sr->g); aga_dijkstra_complete(&sr->g);
} }
/*
* Bellman-Ford algorithm
*/
struct agar_state *agar_bellman_ford_new(void *ctx, struct agar_graph *gr,
const void *nr)
{
struct agar_state *sr = agar_new(ctx, gr);
if (aga_bellman_ford_start(&sr->g, nr_to_n(sr, nr)) < 0) {
tal_free(sr);
return NULL;
}
return sr;
}
bool agar_bellman_ford_path(struct agar_state *sr, const void *destr,
aga_icost_t *total_cost,
const void **prevr, const void **prevedge)
{
struct aga_node *dest = nr_to_n(sr, destr);
struct aga_node *prev;
if (!aga_bellman_ford_path(&sr->g, dest, total_cost, &prev, prevedge))
return false;
/*
* When destr is the same as the source node, there obviously
* isn't a previous node or edge. In that case aga sets them
* to NULL. But for agar, NULL could be a valid node
* references (particularly if using ptrint). So we don't
* have much choice here but to leave *prevr as undefined when
* destr is the source node. */
if (prevr && prev)
*prevr = n_to_nr(sr, prev);
return true;
}
void agar_bellman_ford_complete(struct agar_state *sr)
{
aga_bellman_ford_complete(&sr->g);
}
...@@ -84,6 +84,18 @@ bool agar_dijkstra_step(struct agar_state *sr, const void **nextr); ...@@ -84,6 +84,18 @@ bool agar_dijkstra_step(struct agar_state *sr, const void **nextr);
bool agar_dijkstra_path(struct agar_state *sr, const void *destr, bool agar_dijkstra_path(struct agar_state *sr, const void *destr,
aga_icost_t *total_cost, aga_icost_t *total_cost,
const void **prevr, const void **prevedge); const void **prevr, const void **prevedge);
void agar_dijkstra_all_paths(struct agar_state *sr); void agar_dijkstra_complete(struct agar_state *sr);
/*
* Bellman-Ford algorithm
*/
struct agar_state *agar_bellman_ford_new(void *ctx, struct agar_graph *gr,
const void *nr);
bool agar_bellman_ford_path(struct agar_state *sr, const void *destr,
aga_icost_t *total_cost,
const void **prevr, const void **prevedge);
void agar_bellman_ford_complete(struct agar_state *sr);
#endif /* CCAN_AGAR_H */ #endif /* CCAN_AGAR_H */
#include "config.h"
#include <stddef.h>
#include <assert.h>
#include <stdlib.h>
#include <ccan/tap/tap.h>
#include <ccan/tal/tal.h>
#include <ccan/array_size/array_size.h>
#include <ccan/agar/agar.h>
#include "simple-graphr.h"
static void test_trivial(void)
{
struct agar_state *sr;
aga_icost_t cost;
ok1(sr = agar_bellman_ford_new(NULL, &trivial_graphr.gr, int2ptr(1)));
ok1(agar_bellman_ford_path(sr, int2ptr(1), &cost, NULL, NULL));
ok1(cost == 0);
tal_free(sr);
}
static void test_parallel(void)
{
struct parallel_graphr pgr;
struct agar_state *sr;
aga_icost_t cost;
const void *node, *edge;
parallel_graphr_init(&pgr, 3, 0);
ok1(sr = agar_bellman_ford_new(NULL, &pgr.gr, int2ptr(1)));
ok1(agar_bellman_ford_path(sr, int2ptr(1), &cost, NULL, NULL));
ok1(cost == 0);
ok1(agar_bellman_ford_path(sr, int2ptr(2), &cost, &node, NULL));
ok1(cost == 2);
ok1(node == int2ptr(1));
tal_free(sr);
ok1(sr = agar_bellman_ford_new(NULL, &pgr.gr, int2ptr(2)));
ok1(agar_bellman_ford_path(sr, int2ptr(2), &cost, NULL, NULL));
ok1(cost == 0);
ok1(!agar_bellman_ford_path(sr, int2ptr(1), NULL, NULL, NULL));
tal_free(sr);
parallel_graphr_init(&pgr, 3, 2);
ok1(sr = agar_bellman_ford_new(NULL, &pgr.gr, int2ptr(1)));
ok1(agar_bellman_ford_path(sr, int2ptr(2), &cost, &node, &edge));
ok1(cost == 1);
ok1(ptr2int(node) == 1);
ok1(ptr2int(edge) == 2);
tal_free(sr);
}
#define FULL_LEN 4
static void test_full(void)
{
struct full_graphr fgr;
int i, j;
full_graphr_init(&fgr, FULL_LEN);
for (i = 1; i <= FULL_LEN; i++) {
struct agar_state *sr;
ok1(sr = agar_bellman_ford_new(NULL, &fgr.gr, int2ptr(i)));
for (j = 1; j <= FULL_LEN; j++) {
aga_icost_t cost;
const void *node, *edge;
ok1(agar_bellman_ford_path(sr, int2ptr(j),
&cost, &node, &edge));
if (i == j) {
ok1(cost == 0);
} else {
ok1(cost == 1);
ok1(node == int2ptr(i));
ok1(edge == int2ptr(j));
}
}
tal_free(sr);
}
}
#define CHAIN_LEN 8
static void test_chain(void)
{
struct chain_graphr cgr;
int i, j;
chain_graphr_init(&cgr, CHAIN_LEN);
for (i = 1; i <= CHAIN_LEN; i++) {
struct agar_state *sr;
ok1(sr = agar_bellman_ford_new(NULL, &cgr.fgr.gr, int2ptr(i)));
for (j = 1; j <= CHAIN_LEN; j++) {
aga_icost_t cost;
ok1(agar_bellman_ford_path(sr, int2ptr(j),
&cost, NULL, NULL));
ok1(cost == labs(i - j));
}
tal_free(sr);
}
}
static void test_error(void)
{
struct agar_state *sr;
aga_icost_t cost;
ok1(sr = agar_bellman_ford_new(NULL, &error_graphr.gr, int2ptr(1)));
ok1(agar_bellman_ford_path(sr, int2ptr(1), &cost, NULL, NULL));
ok1(cost == 0);
ok1(agar_bellman_ford_path(sr, int2ptr(2), &cost, NULL, NULL));
ok1(cost == 1);
ok1(!agar_bellman_ford_path(sr, int2ptr(3), &cost, NULL, NULL));
ok1(!agar_bellman_ford_path(sr, int2ptr(4), &cost, NULL, NULL));
tal_free(sr);
ok1(sr = agar_bellman_ford_new(NULL, &error_graphr.gr, int2ptr(3)));
agar_bellman_ford_complete(sr);
ok1(!agar_bellman_ford_path(sr, int2ptr(4), &cost, NULL, NULL));
ok1(agar_error(sr) == -1);
tal_free(sr);
}
static void test_traversal1(void)
{
struct agar_state *sr;
aga_icost_t cost;
/* This is mostly about testing we correctly handle
* non-reachable nodes */
ok1(sr = agar_bellman_ford_new(NULL, &traversal1_graphr.gr, int2ptr(1)));
ok1(agar_bellman_ford_path(sr, int2ptr(1),
&cost, NULL, NULL));
ok1(cost == 0);
ok1(agar_bellman_ford_path(sr, int2ptr(2),
&cost, NULL, NULL));
ok1(cost == 1);
ok1(agar_bellman_ford_path(sr, int2ptr(3),
&cost, NULL, NULL));
ok1(cost == 1);
ok1(agar_bellman_ford_path(sr, int2ptr(4),
&cost, NULL, NULL));
ok1(cost == 2);
ok1(agar_bellman_ford_path(sr, int2ptr(5),
&cost, NULL, NULL));
ok1(cost == 2);
ok1(agar_bellman_ford_path(sr, int2ptr(6),
&cost, NULL, NULL));
ok1(cost == 2);
ok1(!agar_bellman_ford_path(sr, int2ptr(7),
NULL, NULL, NULL));
ok1(!agar_bellman_ford_path(sr, int2ptr(8),
NULL, NULL, NULL));
ok1(!agar_bellman_ford_path(sr, int2ptr(9),
NULL, NULL, NULL));
tal_free(sr);
ok1(sr = agar_bellman_ford_new(NULL, &traversal1_graphr.gr, int2ptr(9)));
ok1(agar_bellman_ford_path(sr, int2ptr(9),
&cost, NULL, NULL));
ok1(cost == 0);
ok1(agar_bellman_ford_path(sr, int2ptr(8),
&cost, NULL, NULL));
ok1(cost == 1);
ok1(agar_bellman_ford_path(sr, int2ptr(7),
&cost, NULL, NULL));
ok1(cost == 1);
ok1(agar_bellman_ford_path(sr, int2ptr(6),
&cost, NULL, NULL));
ok1(cost == 2);
ok1(agar_bellman_ford_path(sr, int2ptr(5),
&cost, NULL, NULL));
ok1(cost == 2);
ok1(agar_bellman_ford_path(sr, int2ptr(4),
&cost, NULL, NULL));
ok1(cost == 2);
ok1(!agar_bellman_ford_path(sr, int2ptr(3),
NULL, NULL, NULL));
ok1(!agar_bellman_ford_path(sr, int2ptr(2),
NULL, NULL, NULL));
ok1(!agar_bellman_ford_path(sr, int2ptr(1),
NULL, NULL, NULL));
tal_free(sr);
}
static void test_shortcut1(void)
{
struct agar_state *sr;
aga_icost_t cost;
const void *node;
ok1(sr = agar_bellman_ford_new(NULL, &shortcut1_graphr.gr, int2ptr(1)));
ok1(agar_bellman_ford_path(sr, int2ptr(3), &cost, &node, NULL));
ok1(cost == 2);
ok1(node == int2ptr(2));
ok1(agar_bellman_ford_path(sr, int2ptr(2), &cost, &node, NULL));
ok1(cost == 1);
ok1(node == int2ptr(1));
tal_free(sr);
}
static void test_shortcut2(void)
{
struct agar_state *sr;
aga_icost_t cost;
const void *node;
ok1(sr = agar_bellman_ford_new(NULL, &shortcut2_graphr.gr, int2ptr(1)));
ok1(agar_bellman_ford_path(sr, int2ptr(3), &cost, &node, NULL));
ok1(cost == 1);
ok1(node == int2ptr(2));
ok1(agar_bellman_ford_path(sr, int2ptr(2), &cost, &node, NULL));
ok1(cost == 2);
ok1(node == int2ptr(1));
tal_free(sr);
}
static void test_negacycle(void)
{
struct agar_state *sr;
ok1(sr = agar_bellman_ford_new(NULL, &negacycle_graphr.gr, int2ptr(1)));
agar_bellman_ford_complete(sr);
ok1(agar_error(sr) == AGA_ERR_NEGATIVE_COST);
tal_free(sr);
}
int main(void)
{
plan_tests(3 + 15
+ FULL_LEN * (FULL_LEN*4 - 1)
+ CHAIN_LEN * (1 + CHAIN_LEN*2)
+ 10 + 32 + 7 + 7 + 2);
test_trivial();
test_parallel();
test_full();
test_chain();
test_error();
test_traversal1();
test_shortcut1();
test_shortcut2();
test_negacycle();
return exit_status();
}
...@@ -45,7 +45,7 @@ int main(void) ...@@ -45,7 +45,7 @@ int main(void)
struct agar_state *sr; struct agar_state *sr;
const void *nr; const void *nr;
plan_tests(2 * 13 + 12 + 10); plan_tests(2 * 13 + 12 + 10 + 6);
test_bfs(&trivial_graphr.gr, 1, 1); test_bfs(&trivial_graphr.gr, 1, 1);
...@@ -97,5 +97,9 @@ int main(void) ...@@ -97,5 +97,9 @@ int main(void)
test_bfs_partial(sr, 1, 1, 2, 3); test_bfs_partial(sr, 1, 1, 2, 3);
tal_free(sr); tal_free(sr);
test_bfs(&negacycle_graphr.gr, 1, 1, 2, 3);
test_bfs(&negacycle_graphr.gr, 2, 2, 3, 1);
test_bfs(&negacycle_graphr.gr, 3, 3, 1, 2);
return exit_status(); return exit_status();
} }
...@@ -45,7 +45,7 @@ int main(void) ...@@ -45,7 +45,7 @@ int main(void)
struct agar_state *sr; struct agar_state *sr;
const void *nr; const void *nr;
plan_tests(2 * 13 + 12 + 10); plan_tests(2 * 13 + 12 + 10 + 6);
test_dfs(&trivial_graphr.gr, 1, 1); test_dfs(&trivial_graphr.gr, 1, 1);
...@@ -97,5 +97,9 @@ int main(void) ...@@ -97,5 +97,9 @@ int main(void)
test_dfs_partial(sr, 1, 1, 2, 3); test_dfs_partial(sr, 1, 1, 2, 3);
tal_free(sr); tal_free(sr);
test_dfs(&negacycle_graphr.gr, 1, 1, 2, 3);
test_dfs(&negacycle_graphr.gr, 2, 2, 3, 1);
test_dfs(&negacycle_graphr.gr, 3, 3, 1, 2);
return exit_status(); return exit_status();
} }
...@@ -231,7 +231,17 @@ static void test_shortcut2(void) ...@@ -231,7 +231,17 @@ static void test_shortcut2(void)
struct agar_state *sr; struct agar_state *sr;
ok1(sr = agar_dijkstra_new(NULL, &shortcut2_graphr.gr, int2ptr(1))); ok1(sr = agar_dijkstra_new(NULL, &shortcut2_graphr.gr, int2ptr(1)));
agar_dijkstra_all_paths(sr); agar_dijkstra_complete(sr);
ok1(agar_error(sr) == AGA_ERR_NEGATIVE_COST);
tal_free(sr);
}
static void test_negacycle(void)
{
struct agar_state *sr;
ok1(sr = agar_dijkstra_new(NULL, &negacycle_graphr.gr, int2ptr(1)));
agar_dijkstra_complete(sr);
ok1(agar_error(sr) == AGA_ERR_NEGATIVE_COST); ok1(agar_error(sr) == AGA_ERR_NEGATIVE_COST);
tal_free(sr); tal_free(sr);
} }
...@@ -241,7 +251,7 @@ int main(void) ...@@ -241,7 +251,7 @@ int main(void)
plan_tests(6 + 23 plan_tests(6 + 23
+ FULL_LEN * (FULL_LEN*4 - 1) + FULL_LEN * (FULL_LEN*4 - 1)
+ CHAIN_LEN * (1 + CHAIN_LEN*2) + CHAIN_LEN * (1 + CHAIN_LEN*2)
+ 12 + 32 + 7 + 2); + 12 + 32 + 7 + 2 + 2);
test_trivial(); test_trivial();
test_parallel(); test_parallel();
...@@ -251,6 +261,7 @@ int main(void) ...@@ -251,6 +261,7 @@ int main(void)
test_traversal1(); test_traversal1();
test_shortcut1(); test_shortcut1();
test_shortcut2(); test_shortcut2();
test_negacycle();
return exit_status(); return exit_status();
} }
#include "config.h"
#include <assert.h>
#include <ccan/container_of/container_of.h>
#include <ccan/ptrint/ptrint.h>
#include <ccan/agar/agar.h>
#include "simple-graphr.h"
static const void *negacycle_first_edge_r(const struct agar_graph *gr,
const void *nr)
{
return int2ptr(1);
}
static const void *negacycle_next_edge_r(const struct agar_graph *gr,
const void *nr, const void *e)
{
assert(ptr2int(e) == 1);
return NULL;
}
static int negacycle_edge_info_r(const struct agar_graph *gr,
const void *nr, const void *e,
struct agar_edge_info *eir)
{
int ni = ptr2int(nr);
assert(ptr2int(e) == 1);
eir->to = int2ptr((ni % 3) + 1);
if (ni == 3)
eir->icost = -3;
return 0;
}
struct negacycle_graphr negacycle_graphr = {
AGAR_INIT_GRAPH(negacycle_first_edge_r,
negacycle_next_edge_r,
negacycle_edge_info_r),
};
...@@ -240,4 +240,23 @@ static const struct adjacency_listr shortcut2_adjacencyr[] = { ...@@ -240,4 +240,23 @@ static const struct adjacency_listr shortcut2_adjacencyr[] = {
{}, {},
}; };
/* Negacycle graph
*
* A <---- (-3) ----- C
* \ ^
* (1)-> B -- (1)-/
*
* Graph with a negative length cycle, and so lacking well-defined shortest paths.
*/
struct negacycle_graphr {
struct agar_graph gr;
};
extern struct negacycle_graphr negacycle_graphr;
static const struct adjacency_listr negacycle_adjacencyr[] = {
{1, {2}},
{2, {3}},
{3, {1}},
{},
};
#endif /* _SIMPLE_GRAPHR_H */ #endif /* _SIMPLE_GRAPHR_H */
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
* *
* // Output contains "ALIGNOF(char) == 1" * // Output contains "ALIGNOF(char) == 1"
* // Will also print out whether an onstack char array can hold a long. * // Will also print out whether an onstack char array can hold a long.
* int main(int argc, char *argv[]) * int main(void)
* { * {
* char arr[sizeof(int)]; * char arr[sizeof(int)];
* *
......
...@@ -24,7 +24,7 @@ struct lots_of_types ...@@ -24,7 +24,7 @@ struct lots_of_types
char c5; char c5;
}; };
int main(int argc, char *argv[]) int main(void)
{ {
struct lots_of_types lots_of_types, *lp = malloc(sizeof(*lp)); struct lots_of_types lots_of_types, *lp = malloc(sizeof(*lp));
char c; char c;
......
...@@ -18,7 +18,7 @@ int check_parameter(const struct foo *array) ...@@ -18,7 +18,7 @@ int check_parameter(const struct foo *array)
#endif #endif
} }
int main(int argc, char *argv[]) int main(void)
{ {
return check_parameter(NULL); return check_parameter(NULL);
} }
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
int main(int argc, char *argv[8]) int main(int argc, char *argv[8])
{ {
(void)argc;
(void)argv;
char array[100]; char array[100];
#ifdef FAIL #ifdef FAIL
return ARRAY_SIZE(argv) + ARRAY_SIZE(array); return ARRAY_SIZE(argv) + ARRAY_SIZE(array);
......
...@@ -16,7 +16,7 @@ static int array2_size = ARRAY_SIZE(array2); ...@@ -16,7 +16,7 @@ static int array2_size = ARRAY_SIZE(array2);
static int array3_size = ARRAY_SIZE(array3); static int array3_size = ARRAY_SIZE(array3);
static int array4_size = ARRAY_SIZE(array4); static int array4_size = ARRAY_SIZE(array4);
int main(int argc, char *argv[]) int main(void)
{ {
plan_tests(8); plan_tests(8);
ok1(array1_size == 1); ok1(array1_size == 1);
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
* int main(int argc, char *argv[]) * int main(int argc, char *argv[])
* { * {
* bool casefold = false; * bool casefold = false;
* unsigned int i; * int i;
* *
* if (argc < 2) { * if (argc < 2) {
* fprintf(stderr, "Usage: %s [-i] <list>...\n" * fprintf(stderr, "Usage: %s [-i] <list>...\n"
......
#include <ccan/asort/asort.h> #include <ccan/asort/asort.h>
#include <ccan/asort/asort.c> #include <ccan/asort/asort.c>
static int cmp(char *const *a, char *const *b, int *flag) static int cmp(char *const *a UNNEEDED, char *const *b UNNEEDED, int *flag UNNEEDED)
{ {
return 0; return 0;
} }
......
...@@ -11,7 +11,7 @@ void *autodata_get_section(void *start, void *stop, size_t *nump) ...@@ -11,7 +11,7 @@ void *autodata_get_section(void *start, void *stop, size_t *nump)
return start; return start;
} }
void autodata_free(void *table) void autodata_free(void *table UNNEEDED)
{ {
} }
#else #else
......
#include <ccan/build_assert/build_assert.h> #include <ccan/build_assert/build_assert.h>
int main(int argc, char *argv[]) int main(void)
{ {
#ifdef FAIL #ifdef FAIL
return BUILD_ASSERT_OR_ZERO(1 == 0); return BUILD_ASSERT_OR_ZERO(1 == 0);
......
#include <ccan/build_assert/build_assert.h> #include <ccan/build_assert/build_assert.h>
int main(int argc, char *argv[]) int main(void)
{ {
#ifdef FAIL #ifdef FAIL
BUILD_ASSERT(1 == 0); BUILD_ASSERT(1 == 0);
......
#include <ccan/build_assert/build_assert.h> #include <ccan/build_assert/build_assert.h>
int main(int argc, char *argv[]) int main(void)
{ {
BUILD_ASSERT(1 == 1); BUILD_ASSERT(1 == 1);
return 0; return 0;
......
#include <ccan/build_assert/build_assert.h> #include <ccan/build_assert/build_assert.h>
#include <ccan/tap/tap.h> #include <ccan/tap/tap.h>
int main(int argc, char *argv[]) int main(void)
{ {
plan_tests(1); plan_tests(1);
ok1(BUILD_ASSERT_OR_ZERO(1 == 1) == 0); ok1(BUILD_ASSERT_OR_ZERO(1 == 1) == 0);
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
* #include <ccan/cast/cast.h> * #include <ccan/cast/cast.h>
* #include <stdint.h> * #include <stdint.h>
* #include <stdio.h> * #include <stdio.h>
* #include <stdlib.h>
* *
* // Find char @orig in @str, if @repl, replace them. Return number. * // Find char @orig in @str, if @repl, replace them. Return number.
* static size_t find_chars(char *str, char orig, char repl) * static size_t find_chars(char *str, char orig, char repl)
...@@ -53,6 +54,9 @@ ...@@ -53,6 +54,9 @@
* { * {
* uint64_t hash; * uint64_t hash;
* *
* if (argc != 2) {
* fprintf(stderr, "Needs argument\n"); exit(1);
* }
* // find_chars wants a non-const string, but doesn't * // find_chars wants a non-const string, but doesn't
* // need it if repl == 0. * // need it if repl == 0.
* printf("%zu %c's in 'test string'\n", * printf("%zu %c's in 'test string'\n",
......
...@@ -6,7 +6,7 @@ struct char_struct { ...@@ -6,7 +6,7 @@ struct char_struct {
char c; char c;
}; };
int main(int argc, char *argv[]) int main(void)
{ {
char *uc; char *uc;
const const
......
...@@ -6,7 +6,7 @@ struct char_struct { ...@@ -6,7 +6,7 @@ struct char_struct {
char c; char c;
}; };
int main(int argc, char *argv[]) int main(void)
{ {
char **uc; char **uc;
const const
......
...@@ -6,7 +6,7 @@ struct char_struct { ...@@ -6,7 +6,7 @@ struct char_struct {
char c; char c;
}; };
int main(int argc, char *argv[]) int main(void)
{ {
char ***uc; char ***uc;
const const
......
#include <ccan/cast/cast.h> #include <ccan/cast/cast.h>
#include <stdlib.h> #include <stdlib.h>
int main(int argc, char *argv[]) int main(void)
{ {
unsigned char *uc; unsigned char *uc;
#ifdef FAIL #ifdef FAIL
......
...@@ -6,7 +6,7 @@ struct char_struct { ...@@ -6,7 +6,7 @@ struct char_struct {
char c; char c;
}; };
int main(int argc, char *argv[]) int main(void)
{ {
unsigned char *uc; unsigned char *uc;
#ifdef FAIL #ifdef FAIL
......
#include <ccan/cast/cast.h> #include <ccan/cast/cast.h>
#include <stdlib.h> #include <stdlib.h>
int main(int argc, char *argv[]) int main(void)
{ {
unsigned char *uc; unsigned char *uc;
#ifdef FAIL #ifdef FAIL
......
#include <ccan/cast/cast.h> #include <ccan/cast/cast.h>
#include <stdlib.h> #include <stdlib.h>
int main(int argc, char *argv[]) int main(void)
{ {
char *c; char *c;
#ifdef FAIL #ifdef FAIL
......
#include <ccan/cast/cast.h> #include <ccan/cast/cast.h>
#include <stdlib.h> #include <stdlib.h>
int main(int argc, char *argv[]) int main(void)
{ {
char *c; char *c;
#ifdef FAIL #ifdef FAIL
......
#include <ccan/cast/cast.h> #include <ccan/cast/cast.h>
#include <stdlib.h> #include <stdlib.h>
int main(int argc, char *argv[]) int main(void)
{ {
long c; long c;
#ifdef FAIL #ifdef FAIL
......
...@@ -6,5 +6,6 @@ static char *p = cast_const(char *, (const char *)"hello"); ...@@ -6,5 +6,6 @@ static char *p = cast_const(char *, (const char *)"hello");
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
(void)argc;
return p[0] == argv[0][0]; return p[0] == argv[0][0];
} }
...@@ -29,7 +29,8 @@ ...@@ -29,7 +29,8 @@
* { * {
* char *code, *problems; * char *code, *problems;
* struct cdump_definitions *defs; * struct cdump_definitions *defs;
* int i, j; * int i;
* size_t j;
* *
* // Read code from stdin. * // Read code from stdin.
* code = grab_file(NULL, NULL); * code = grab_file(NULL, NULL);
......
...@@ -213,7 +213,7 @@ static struct cdump_type *get_type(struct cdump_definitions *defs, ...@@ -213,7 +213,7 @@ static struct cdump_type *get_type(struct cdump_definitions *defs,
enum cdump_type_kind kind, enum cdump_type_kind kind,
const char *name) const char *name)
{ {
cdump_map_t *m; cdump_map_t *m = (void *)0x1L; /* Shouldn't be used */
struct cdump_type *t; struct cdump_type *t;
switch (kind) { switch (kind) {
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
(void)argc;
(void)argv;
#ifdef FAIL #ifdef FAIL
check_type(argc, char); check_type(argc, char);
#endif #endif
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
(void)argc;
(void)argv;
#ifdef FAIL #ifdef FAIL
#if HAVE_TYPEOF #if HAVE_TYPEOF
check_type(argc, unsigned int); check_type(argc, unsigned int);
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
unsigned char x = argc; unsigned char x = argc;
(void)argv;
#ifdef FAIL #ifdef FAIL
check_types_match(argc, x); check_types_match(argc, x);
#endif #endif
......
...@@ -5,6 +5,7 @@ int main(int argc, char *argv[]) ...@@ -5,6 +5,7 @@ int main(int argc, char *argv[])
{ {
int x = 0, y = 0; int x = 0, y = 0;
(void)argv;
plan_tests(9); plan_tests(9);
ok1(check_type(argc, int) == 0); ok1(check_type(argc, int) == 0);
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
* va_end(ap); * va_end(ap);
* } * }
* *
* int main(int argc, char *argv[]) * int main(int argc, char *argv[] UNNEEDED)
* { * {
* if (argc != 1) { * if (argc != 1) {
* logger(3, "Don't want %i arguments!\n", argc-1); * logger(3, "Don't want %i arguments!\n", argc-1);
......
...@@ -2,9 +2,11 @@ ...@@ -2,9 +2,11 @@
static void PRINTF_FMT(2,3) my_printf(int x, const char *fmt, ...) static void PRINTF_FMT(2,3) my_printf(int x, const char *fmt, ...)
{ {
(void)x;
(void)fmt;
} }
int main(int argc, char *argv[]) int main(void)
{ {
unsigned int i = 0; unsigned int i = 0;
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
(void)argc;
(void)argv;
plan_tests(2); plan_tests(2);
ok1(!IS_COMPILE_CONSTANT(argc)); ok1(!IS_COMPILE_CONSTANT(argc));
......
...@@ -26,17 +26,19 @@ ...@@ -26,17 +26,19 @@
* struct timer timer; * struct timer timer;
* }; * };
* *
* static void register_timer(struct timer *timer)
* {
* //...
* }
*
* static void my_timer_callback(struct timer *timer) * static void my_timer_callback(struct timer *timer)
* { * {
* struct info *info = container_of(timer, struct info, timer); * struct info *info = container_of(timer, struct info, timer);
* printf("my_stuff is %u\n", info->my_stuff); * printf("my_stuff is %u\n", info->my_stuff);
* } * }
* *
* static void register_timer(struct timer *timer)
* {
* (void)timer;
* (void)my_timer_callback;
* //...
* }
*
* int main(void) * int main(void)
* { * {
* struct info info = { .my_stuff = 1 }; * struct info info = { .my_stuff = 1 };
......
...@@ -6,7 +6,7 @@ struct foo { ...@@ -6,7 +6,7 @@ struct foo {
char b; char b;
}; };
int main(int argc, char *argv[]) int main(void)
{ {
struct foo foo = { .a = 1, .b = 2 }; struct foo foo = { .a = 1, .b = 2 };
int *intp = &foo.a; int *intp = &foo.a;
......
...@@ -6,7 +6,7 @@ struct foo { ...@@ -6,7 +6,7 @@ struct foo {
char b; char b;
}; };
int main(int argc, char *argv[]) int main(void)
{ {
struct foo foo = { .a = 1, .b = 2 }, *foop; struct foo foo = { .a = 1, .b = 2 }, *foop;
int *intp = &foo.a; int *intp = &foo.a;
......
...@@ -6,7 +6,7 @@ struct foo { ...@@ -6,7 +6,7 @@ struct foo {
char b; char b;
}; };
int main(int argc, char *argv[]) int main(void)
{ {
struct foo foo = { .a = 1, .b = 2 }, *foop; struct foo foo = { .a = 1, .b = 2 }, *foop;
int *intp = &foo.a; int *intp = &foo.a;
......
...@@ -6,7 +6,7 @@ struct foo { ...@@ -6,7 +6,7 @@ struct foo {
char b; char b;
}; };
int main(int argc, char *argv[]) int main(void)
{ {
struct foo foo = { .a = 1, .b = 2 }; struct foo foo = { .a = 1, .b = 2 };
int *intp = &foo.a; int *intp = &foo.a;
......
...@@ -237,7 +237,7 @@ cputype_t cpuid_get_cpu_type(void) ...@@ -237,7 +237,7 @@ cputype_t cpuid_get_cpu_type(void)
uint32_t i; uint32_t i;
get_cpuid(CPUID_VENDORID, &i, &u.bufu32[0], &u.bufu32[2], &u.bufu32[1]); get_cpuid(CPUID_VENDORID, &i, &u.bufu32[0], &u.bufu32[2], &u.bufu32[1]);
for (i = 0; i < sizeof(c_cpunames) / sizeof(c_cpunames); ++i) { for (i = 0; i < sizeof(c_cpunames) / sizeof(c_cpunames[0]); ++i) {
if (strncmp(c_cpunames[i], u.buf, 12) == 0) { if (strncmp(c_cpunames[i], u.buf, 12) == 0) {
cputype = (cputype_t)i; cputype = (cputype_t)i;
break; break;
......
...@@ -45,6 +45,7 @@ static void check_siphash24(struct siphash24_ctx *ctx) ...@@ -45,6 +45,7 @@ static void check_siphash24(struct siphash24_ctx *ctx)
static bool alignment_ok(const void *p, size_t n) static bool alignment_ok(const void *p, size_t n)
{ {
#if HAVE_UNALIGNED_ACCESS #if HAVE_UNALIGNED_ACCESS
(void)p; (void)n;
return true; return true;
#else #else
return ((size_t)p % n == 0); return ((size_t)p % n == 0);
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include <stddef.h> #include <stddef.h>
#include <ccan/tap/tap.h> #include <ccan/tap/tap.h>
int main(int argc, char *argv[]) int main(void)
{ {
union { union {
uint64_t u64; uint64_t u64;
......
...@@ -15,6 +15,7 @@ int main(int argc, char *argv[]) ...@@ -15,6 +15,7 @@ int main(int argc, char *argv[])
int pfd[2]; int pfd[2];
const char *base; const char *base;
(void)argc;
plan_tests(24); plan_tests(24);
err_set_progname(argv[0]); err_set_progname(argv[0]);
...@@ -27,7 +28,8 @@ int main(int argc, char *argv[]) ...@@ -27,7 +28,8 @@ int main(int argc, char *argv[])
base = argv[0]; base = argv[0];
/* Test err() in child */ /* Test err() in child */
pipe(pfd); if (pipe(pfd))
abort();
fflush(stdout); fflush(stdout);
if (fork()) { if (fork()) {
char buffer[BUFFER_MAX+1]; char buffer[BUFFER_MAX+1];
...@@ -59,7 +61,8 @@ int main(int argc, char *argv[]) ...@@ -59,7 +61,8 @@ int main(int argc, char *argv[])
} }
/* Test errx() in child */ /* Test errx() in child */
pipe(pfd); if (pipe(pfd))
abort();
fflush(stdout); fflush(stdout);
if (fork()) { if (fork()) {
char buffer[BUFFER_MAX+1]; char buffer[BUFFER_MAX+1];
...@@ -89,7 +92,8 @@ int main(int argc, char *argv[]) ...@@ -89,7 +92,8 @@ int main(int argc, char *argv[])
/* Test warn() in child */ /* Test warn() in child */
pipe(pfd); if (pipe(pfd))
abort();
fflush(stdout); fflush(stdout);
if (fork()) { if (fork()) {
char buffer[BUFFER_MAX+1]; char buffer[BUFFER_MAX+1];
...@@ -121,7 +125,8 @@ int main(int argc, char *argv[]) ...@@ -121,7 +125,8 @@ int main(int argc, char *argv[])
} }
/* Test warnx() in child */ /* Test warnx() in child */
pipe(pfd); if (pipe(pfd))
abort();
fflush(stdout); fflush(stdout);
if (fork()) { if (fork()) {
char buffer[BUFFER_MAX+1]; char buffer[BUFFER_MAX+1];
......
...@@ -44,7 +44,7 @@ static int count_iters(void) ...@@ -44,7 +44,7 @@ static int count_iters(void)
int main(void) int main(void)
{ {
int i, j, sum, max_iters; int i, j, sum, max_iters = 0 /* keep gcc happy */;
const char *istr, *jstr; const char *istr, *jstr;
plan_tests(13); plan_tests(13);
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
* // Wrapper for rehash function pointer. * // Wrapper for rehash function pointer.
* static size_t rehash(const void *e, void *unused) * static size_t rehash(const void *e, void *unused)
* { * {
* (void)unused;
* return hash_string(((struct name_to_digit *)e)->name); * return hash_string(((struct name_to_digit *)e)->name);
* } * }
* *
...@@ -64,7 +65,7 @@ ...@@ -64,7 +65,7 @@
* int main(int argc, char *argv[]) * int main(int argc, char *argv[])
* { * {
* struct htable ht; * struct htable ht;
* unsigned int i; * int i;
* unsigned long val; * unsigned long val;
* *
* if (argc < 2) * if (argc < 2)
...@@ -73,7 +74,7 @@ ...@@ -73,7 +74,7 @@
* *
* // Create and populate hash table. * // Create and populate hash table.
* htable_init(&ht, rehash, NULL); * htable_init(&ht, rehash, NULL);
* for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) * for (i = 0; i < (int)(sizeof(map)/sizeof(map[0])); i++)
* htable_add(&ht, hash_string(map[i].name), &map[i]); * htable_add(&ht, hash_string(map[i].name), &map[i]);
* *
* // Add any aliases to the hash table. * // Add any aliases to the hash table.
......
...@@ -35,6 +35,7 @@ struct htable { ...@@ -35,6 +35,7 @@ struct htable {
* // For simplicity's sake, say hash value is contents of elem. * // For simplicity's sake, say hash value is contents of elem.
* static size_t rehash(const void *elem, void *unused) * static size_t rehash(const void *elem, void *unused)
* { * {
* (void)unused;
* return *(size_t *)elem; * return *(size_t *)elem;
* } * }
* static struct htable ht = HTABLE_INITIALIZER(ht, rehash, NULL); * static struct htable ht = HTABLE_INITIALIZER(ht, rehash, NULL);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#define NUM_VALS 512 #define NUM_VALS 512
static size_t hash(const void *elem, void *unused) static size_t hash(const void *elem, void *unused UNNEEDED)
{ {
size_t h = *(uint64_t *)elem / 2; size_t h = *(uint64_t *)elem / 2;
return h; return h;
...@@ -17,7 +17,7 @@ static bool cmp(const void *candidate, void *ptr) ...@@ -17,7 +17,7 @@ static bool cmp(const void *candidate, void *ptr)
return *(const uint64_t *)candidate == *(const uint64_t *)ptr; return *(const uint64_t *)candidate == *(const uint64_t *)ptr;
} }
int main(int argc, char *argv[]) int main(void)
{ {
struct htable ht, ht2; struct htable ht, ht2;
uint64_t val[NUM_VALS], i; uint64_t val[NUM_VALS], i;
......
...@@ -8,13 +8,13 @@ ...@@ -8,13 +8,13 @@
/* We use the number divided by two as the hash (for lots of /* We use the number divided by two as the hash (for lots of
collisions). */ collisions). */
static size_t hash(const void *elem, void *unused) static size_t hash(const void *elem, void *unused UNNEEDED)
{ {
size_t h = *(uint64_t *)elem / 2; size_t h = *(uint64_t *)elem / 2;
return h; return h;
} }
int main(int argc, char *argv[]) int main(void)
{ {
struct htable ht; struct htable ht;
uint64_t val[NUM_VALS]; uint64_t val[NUM_VALS];
......
...@@ -88,7 +88,7 @@ static void del_vals(struct htable_obj *ht, ...@@ -88,7 +88,7 @@ static void del_vals(struct htable_obj *ht,
} }
static void del_vals_bykey(struct htable_obj *ht, static void del_vals_bykey(struct htable_obj *ht,
const struct obj val[], unsigned int num) const struct obj val[] UNNEEDED, unsigned int num)
{ {
unsigned int i; unsigned int i;
...@@ -112,7 +112,7 @@ static bool check_mask(struct htable *ht, const struct obj val[], unsigned num) ...@@ -112,7 +112,7 @@ static bool check_mask(struct htable *ht, const struct obj val[], unsigned num)
return true; return true;
} }
int main(int argc, char *argv[]) int main(void)
{ {
unsigned int i; unsigned int i;
struct htable_obj ht, ht2; struct htable_obj ht, ht2;
......
...@@ -83,7 +83,7 @@ static void del_vals(struct htable_obj *ht, ...@@ -83,7 +83,7 @@ static void del_vals(struct htable_obj *ht,
} }
static void del_vals_bykey(struct htable_obj *ht, static void del_vals_bykey(struct htable_obj *ht,
const struct obj val[], unsigned int num) const struct obj val[] UNNEEDED, unsigned int num)
{ {
unsigned int i; unsigned int i;
...@@ -107,7 +107,7 @@ static bool check_mask(struct htable *ht, const struct obj val[], unsigned num) ...@@ -107,7 +107,7 @@ static bool check_mask(struct htable *ht, const struct obj val[], unsigned num)
return true; return true;
} }
int main(int argc, char *argv[]) int main(void)
{ {
unsigned int i; unsigned int i;
struct htable_obj ht, ht2; struct htable_obj ht, ht2;
......
...@@ -8,7 +8,7 @@ struct data { ...@@ -8,7 +8,7 @@ struct data {
}; };
/* Hash is simply key itself. */ /* Hash is simply key itself. */
static size_t hash(const void *e, void *unused) static size_t hash(const void *e, void *unused UNNEEDED)
{ {
struct data *d = (struct data *)e; struct data *d = (struct data *)e;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
/* We use the number divided by two as the hash (for lots of /* We use the number divided by two as the hash (for lots of
collisions), plus set all the higher bits so we can detect if they collisions), plus set all the higher bits so we can detect if they
don't get masked out. */ don't get masked out. */
static size_t hash(const void *elem, void *unused) static size_t hash(const void *elem, void *unused UNNEEDED)
{ {
size_t h = *(uint64_t *)elem / 2; size_t h = *(uint64_t *)elem / 2;
h |= -1UL << NUM_BITS; h |= -1UL << NUM_BITS;
...@@ -95,7 +95,7 @@ static bool check_mask(struct htable *ht, uint64_t val[], unsigned num) ...@@ -95,7 +95,7 @@ static bool check_mask(struct htable *ht, uint64_t val[], unsigned num)
return true; return true;
} }
int main(int argc, char *argv[]) int main(void)
{ {
unsigned int i, weight; unsigned int i, weight;
uintptr_t perfect_bit; uintptr_t perfect_bit;
......
...@@ -19,7 +19,7 @@ static int test_ilog64(uint64_t _v){ ...@@ -19,7 +19,7 @@ static int test_ilog64(uint64_t _v){
#define NTRIALS (64) #define NTRIALS (64)
int main(int _argc,const char *_argv[]){ int main(void){
int i; int i;
int j; int j;
int (*il32)(uint32_t) = ilog32; int (*il32)(uint32_t) = ilog32;
......
...@@ -19,7 +19,7 @@ static int test_ilog64(uint64_t _v){ ...@@ -19,7 +19,7 @@ static int test_ilog64(uint64_t _v){
#define NTRIALS (64) #define NTRIALS (64)
int main(int _argc,const char *_argv[]){ int main(void){
int i; int i;
int j; int j;
/*This is how many tests you plan to run.*/ /*This is how many tests you plan to run.*/
......
...@@ -47,7 +47,8 @@ struct io_conn; ...@@ -47,7 +47,8 @@ struct io_conn;
* int fd[2]; * int fd[2];
* struct io_conn *conn; * struct io_conn *conn;
* *
* pipe(fd); * if (pipe(fd) != 0)
* exit(1);
* conn = io_new_conn(NULL, fd[0], conn_init, (const char *)"hi!"); * conn = io_new_conn(NULL, fd[0], conn_init, (const char *)"hi!");
* if (!conn) * if (!conn)
* exit(1); * exit(1);
...@@ -653,11 +654,11 @@ int io_conn_fd(const struct io_conn *conn); ...@@ -653,11 +654,11 @@ int io_conn_fd(const struct io_conn *conn);
* io_time_override - override the normal call for time. * io_time_override - override the normal call for time.
* @nowfn: the function to call. * @nowfn: the function to call.
* *
* io usually uses time_now() internally, but this forces it * io usually uses time_mono() internally, but this forces it
* to use your function (eg. for debugging). Returns the old * to use your function (eg. for debugging). Returns the old
* one. * one.
*/ */
struct timeabs (*io_time_override(struct timeabs (*now)(void)))(void); struct timemono (*io_time_override(struct timemono (*now)(void)))(void);
/** /**
* io_set_debug - set synchronous mode on a connection. * io_set_debug - set synchronous mode on a connection.
......
...@@ -16,11 +16,11 @@ static struct pollfd *pollfds = NULL; ...@@ -16,11 +16,11 @@ static struct pollfd *pollfds = NULL;
static struct fd **fds = NULL; static struct fd **fds = NULL;
static LIST_HEAD(closing); static LIST_HEAD(closing);
static LIST_HEAD(always); static LIST_HEAD(always);
static struct timeabs (*nowfn)(void) = time_now; static struct timemono (*nowfn)(void) = time_mono;
struct timeabs (*io_time_override(struct timeabs (*now)(void)))(void) struct timemono (*io_time_override(struct timemono (*now)(void)))(void)
{ {
struct timeabs (*old)(void) = nowfn; struct timemono (*old)(void) = nowfn;
nowfn = now; nowfn = now;
return old; return old;
} }
...@@ -262,7 +262,7 @@ void *io_loop(struct timers *timers, struct timer **expired) ...@@ -262,7 +262,7 @@ void *io_loop(struct timers *timers, struct timer **expired)
assert(num_waiting); assert(num_waiting);
if (timers) { if (timers) {
struct timeabs now, first; struct timemono now, first;
now = nowfn(); now = nowfn();
...@@ -274,7 +274,7 @@ void *io_loop(struct timers *timers, struct timer **expired) ...@@ -274,7 +274,7 @@ void *io_loop(struct timers *timers, struct timer **expired)
/* Now figure out how long to wait for the next one. */ /* Now figure out how long to wait for the next one. */
if (timer_earliest(timers, &first)) { if (timer_earliest(timers, &first)) {
uint64_t next; uint64_t next;
next = time_to_msec(time_between(first, now)); next = time_to_msec(timemono_between(first, now));
if (next < INT_MAX) if (next < INT_MAX)
ms_timeout = next; ms_timeout = next;
else else
......
...@@ -69,7 +69,7 @@ static int make_listen_fd(const char *port, struct addrinfo **info) ...@@ -69,7 +69,7 @@ static int make_listen_fd(const char *port, struct addrinfo **info)
int main(void) int main(void)
{ {
int state = 0; int state = 0;
struct addrinfo *addrinfo; struct addrinfo *addrinfo = NULL;
struct io_listener *l; struct io_listener *l;
int fd; int fd;
......
...@@ -71,7 +71,7 @@ static int make_listen_fd(const char *port, struct addrinfo **info) ...@@ -71,7 +71,7 @@ static int make_listen_fd(const char *port, struct addrinfo **info)
int main(void) int main(void)
{ {
struct data *d = malloc(sizeof(*d)); struct data *d = malloc(sizeof(*d));
struct addrinfo *addrinfo; struct addrinfo *addrinfo = NULL;
struct io_listener *l; struct io_listener *l;
int fd, status; int fd, status;
......
...@@ -47,8 +47,7 @@ static struct io_plan *init_conn(struct io_conn *conn, struct data *d) ...@@ -47,8 +47,7 @@ static struct io_plan *init_conn(struct io_conn *conn, struct data *d)
d->conn = conn; d->conn = conn;
io_set_finish(conn, finish_ok, d); io_set_finish(conn, finish_ok, d);
timer_add(&d->timers, &d->timer, timer_addrel(&d->timers, &d->timer, time_from_usec(d->timeout_usec));
timeabs_add(time_now(), time_from_usec(d->timeout_usec)));
return io_read(conn, d->buf, sizeof(d->buf), no_timeout, d); return io_read(conn, d->buf, sizeof(d->buf), no_timeout, d);
} }
...@@ -97,7 +96,7 @@ int main(void) ...@@ -97,7 +96,7 @@ int main(void)
plan_tests(21); plan_tests(21);
d->state = 0; d->state = 0;
d->timeout_usec = 100000; d->timeout_usec = 100000;
timers_init(&d->timers, time_now()); timers_init(&d->timers, time_mono());
timer_init(&d->timer); timer_init(&d->timer);
fd = make_listen_fd(PORT, &addrinfo); fd = make_listen_fd(PORT, &addrinfo);
ok1(fd >= 0); ok1(fd >= 0);
...@@ -131,7 +130,7 @@ int main(void) ...@@ -131,7 +130,7 @@ int main(void)
/* One element, d->timer. */ /* One element, d->timer. */
ok1(expired == &d->timer); ok1(expired == &d->timer);
ok1(!timers_expire(&d->timers, time_now())); ok1(!timers_expire(&d->timers, time_mono()));
ok1(d->state == 1); ok1(d->state == 1);
io_close(d->conn); io_close(d->conn);
......
...@@ -45,9 +45,9 @@ static int make_listen_fd(const char *port, struct addrinfo **info) ...@@ -45,9 +45,9 @@ static int make_listen_fd(const char *port, struct addrinfo **info)
return fd; return fd;
} }
static struct timeabs fake_time; static struct timemono fake_time;
static struct timeabs get_fake_time(void) static struct timemono get_fake_time(void)
{ {
return fake_time; return fake_time;
} }
...@@ -63,12 +63,12 @@ int main(void) ...@@ -63,12 +63,12 @@ int main(void)
/* This is how many tests you plan to run */ /* This is how many tests you plan to run */
plan_tests(7); plan_tests(7);
fake_time = time_now(); fake_time = time_mono();
timers_init(&timers, fake_time); timers_init(&timers, fake_time);
timer_init(&timer); timer_init(&timer);
timer_add(&timers, &timer, timer_addmono(&timers, &timer,
timeabs_add(fake_time, time_from_sec(1000))); timemono_add(fake_time, time_from_sec(1000)));
fd = make_listen_fd(PORT, &addrinfo); fd = make_listen_fd(PORT, &addrinfo);
freeaddrinfo(addrinfo); freeaddrinfo(addrinfo);
...@@ -77,12 +77,12 @@ int main(void) ...@@ -77,12 +77,12 @@ int main(void)
ok1(l); ok1(l);
fake_time.ts.tv_sec += 1000; fake_time.ts.tv_sec += 1000;
ok1(io_time_override(get_fake_time) == time_now); ok1(io_time_override(get_fake_time) == time_mono);
ok1(io_loop(&timers, &expired) == NULL); ok1(io_loop(&timers, &expired) == NULL);
ok1(expired == &timer); ok1(expired == &timer);
ok1(!timers_expire(&timers, fake_time)); ok1(!timers_expire(&timers, fake_time));
ok1(io_time_override(time_now) == get_fake_time); ok1(io_time_override(time_mono) == get_fake_time);
io_close_listener(l); io_close_listener(l);
timers_cleanup(&timers); timers_cleanup(&timers);
......
...@@ -134,7 +134,7 @@ static const uint32_t STATEVEC[ISAAC_SZ<<1]={ ...@@ -134,7 +134,7 @@ static const uint32_t STATEVEC[ISAAC_SZ<<1]={
0x46D95CA5, 0xC54CD95B, 0x9D855E89, 0x4BB5AF29 0x46D95CA5, 0xC54CD95B, 0x9D855E89, 0x4BB5AF29
}; };
int main(int _argc,const char *_argv[]){ int main(void){
isaac_ctx isaac; isaac_ctx isaac;
int i; int i;
int j; int j;
......
...@@ -262,7 +262,7 @@ static const uint64_t STATEVEC64[ISAAC64_SZ<<1]={ ...@@ -262,7 +262,7 @@ static const uint64_t STATEVEC64[ISAAC64_SZ<<1]={
0x1877B51E57A764D5ULL, 0x001F837CC7350524ULL 0x1877B51E57A764D5ULL, 0x001F837CC7350524ULL
}; };
int main(int _argc,const char *_argv[]){ int main(void){
isaac64_ctx isaac64; isaac64_ctx isaac64;
int i; int i;
int j; int j;
......
CFLAGS=-Wall -Werror -O3 -I../../.. CFLAGS=-Wall -Werror -O3 -I../../..
LDFLAGS=-lJudy LDLIBS=-lJudy
speed: speed.o speed: speed.o
speed.o: speed.c ../jmap.h ../jmap_type.h ../jmap.c speed.o: speed.c ../jmap.h
/* Simple speed tests for jmap. */ /* Simple speed tests for jmap. */
#include <ccan/jmap/jmap_type.h>
#include <ccan/jmap/jmap.c> #include <ccan/jmap/jmap.c>
#include <ccan/time/time.c>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h>
#include <unistd.h> #include <unistd.h>
#include <sys/time.h>
struct object { struct object {
/* Some contents. Doubles as consistency check. */ /* Some contents. Doubles as consistency check. */
struct object *self; struct object *self;
}; };
struct jmap_obj {
JMAP_MEMBERS(unsigned int, struct object *);
};
/* Nanoseconds per operation */ /* Nanoseconds per operation */
static size_t normalize(const struct timeval *start, static size_t normalize(const struct timeabs *start,
const struct timeval *stop, const struct timeabs *stop,
unsigned int num) unsigned int num)
{ {
struct timeval diff; return time_to_nsec(time_divide(time_between(*stop, *start), num));
timersub(stop, start, &diff);
/* Floating point is more accurate here. */
return (double)(diff.tv_sec * 1000000 + diff.tv_usec)
/ num * 1000;
} }
JMAP_DEFINE_UINTIDX_TYPE(struct object, obj);
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct object *objs; struct object *objs;
size_t i, j, num; unsigned int i, j;
struct timeval start, stop; size_t num;
struct timeabs start, stop;
struct jmap_obj *jmap; struct jmap_obj *jmap;
num = argv[1] ? atoi(argv[1]) : 1000000; num = argv[1] ? atoi(argv[1]) : 1000000;
...@@ -42,110 +37,110 @@ int main(int argc, char *argv[]) ...@@ -42,110 +37,110 @@ int main(int argc, char *argv[])
objs[i].self = &objs[i]; objs[i].self = &objs[i];
} }
jmap = jmap_obj_new(); jmap = jmap_new(struct jmap_obj);
printf("Initial insert: "); printf("Initial insert: ");
fflush(stdout); fflush(stdout);
gettimeofday(&start, NULL); start = time_now();
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
jmap_obj_add(jmap, i, objs[i].self); jmap_add(jmap, i, objs[i].self);
gettimeofday(&stop, NULL); stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num)); printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Initial lookup (match): "); printf("Initial lookup (match): ");
fflush(stdout); fflush(stdout);
gettimeofday(&start, NULL); start = time_now();
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
if (jmap_obj_get(jmap, i)->self != objs[i].self) if (jmap_get(jmap, i)->self != objs[i].self)
abort(); abort();
gettimeofday(&stop, NULL); stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num)); printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Initial lookup (miss): "); printf("Initial lookup (miss): ");
fflush(stdout); fflush(stdout);
gettimeofday(&start, NULL); start = time_now();
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
if (jmap_obj_get(jmap, i+num)) if (jmap_get(jmap, i+num))
abort(); abort();
gettimeofday(&stop, NULL); stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num)); printf(" %zu ns\n", normalize(&start, &stop, num));
/* Lookups in order are very cache-friendly for judy; try random */ /* Lookups in order are very cache-friendly for judy; try random */
printf("Initial lookup (random): "); printf("Initial lookup (random): ");
fflush(stdout); fflush(stdout);
gettimeofday(&start, NULL); start = time_now();
for (i = 0, j = 0; i < num; i++, j = (j + 10007) % num) for (i = 0, j = 0; i < num; i++, j = (j + 10007) % num)
if (jmap_obj_get(jmap, j)->self != &objs[j]) if (jmap_get(jmap, j)->self != &objs[j])
abort(); abort();
gettimeofday(&stop, NULL); stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num)); printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Initial delete all: "); printf("Initial delete all: ");
fflush(stdout); fflush(stdout);
gettimeofday(&start, NULL); start = time_now();
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
jmap_obj_del(jmap, i); jmap_del(jmap, i);
gettimeofday(&stop, NULL); stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num)); printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Initial re-inserting: "); printf("Initial re-inserting: ");
fflush(stdout); fflush(stdout);
gettimeofday(&start, NULL); start = time_now();
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
jmap_obj_add(jmap, i, objs[i].self); jmap_add(jmap, i, objs[i].self);
gettimeofday(&stop, NULL); stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num)); printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Deleting first half: "); printf("Deleting first half: ");
fflush(stdout); fflush(stdout);
gettimeofday(&start, NULL); start = time_now();
for (i = 0; i < num; i+=2) for (i = 0; i < num; i+=2)
jmap_obj_del(jmap, i); jmap_del(jmap, i);
gettimeofday(&stop, NULL); stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num)); printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Adding (a different) half: "); printf("Adding (a different) half: ");
fflush(stdout); fflush(stdout);
gettimeofday(&start, NULL); start = time_now();
for (i = 0; i < num; i+=2) for (i = 0; i < num; i+=2)
jmap_obj_add(jmap, num+i, objs[i].self); jmap_add(jmap, num+i, objs[i].self);
gettimeofday(&stop, NULL); stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num)); printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Lookup after half-change (match): "); printf("Lookup after half-change (match): ");
fflush(stdout); fflush(stdout);
gettimeofday(&start, NULL); start = time_now();
for (i = 1; i < num; i+=2) for (i = 1; i < num; i+=2)
if (jmap_obj_get(jmap, i)->self != objs[i].self) if (jmap_get(jmap, i)->self != objs[i].self)
abort(); abort();
for (i = 0; i < num; i+=2) for (i = 0; i < num; i+=2)
if (jmap_obj_get(jmap, i+num)->self != objs[i].self) if (jmap_get(jmap, i+num)->self != objs[i].self)
abort(); abort();
gettimeofday(&stop, NULL); stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num)); printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Lookup after half-change(miss): "); printf("Lookup after half-change(miss): ");
fflush(stdout); fflush(stdout);
gettimeofday(&start, NULL); start = time_now();
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
if (jmap_obj_get(jmap, i+num*2)) if (jmap_get(jmap, i+num*2))
abort(); abort();
gettimeofday(&stop, NULL); stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num)); printf(" %zu ns\n", normalize(&start, &stop, num));
/* Hashtables with delete markers can fill with markers over time. /* Hashtables with delete markers can fill with markers over time.
* so do some changes to see how it operates in long-term. */ * so do some changes to see how it operates in long-term. */
printf("Details: churning first time\n"); printf("Details: churning first time\n");
for (i = 1; i < num; i+=2) { for (i = 1; i < num; i+=2) {
if (!jmap_obj_del(jmap, i)) if (!jmap_del(jmap, i))
abort(); abort();
jmap_obj_add(jmap, i, objs[i].self); jmap_add(jmap, i, objs[i].self);
} }
for (i = 0; i < num; i+=2) { for (i = 0; i < num; i+=2) {
if (!jmap_obj_del(jmap, i+num)) if (!jmap_del(jmap, i+num))
abort(); abort();
jmap_obj_add(jmap, i, objs[i].self); jmap_add(jmap, i, objs[i].self);
} }
for (i = 1; i < 5; i++) { for (i = 1; i < 5; i++) {
printf("Churning %s time: ", printf("Churning %s time: ",
...@@ -154,84 +149,88 @@ int main(int argc, char *argv[]) ...@@ -154,84 +149,88 @@ int main(int argc, char *argv[])
: i == 3 ? "fourth" : i == 3 ? "fourth"
: "fifth"); : "fifth");
fflush(stdout); fflush(stdout);
gettimeofday(&start, NULL);
start = time_now();
for (j = 0; j < num; j++) { for (j = 0; j < num; j++) {
if (!jmap_obj_del(jmap, num*(i-1)+j)) if (!jmap_del(jmap, num*(i-1)+j))
abort(); abort();
jmap_obj_add(jmap, num*i+j, &objs[j]); jmap_add(jmap, num*i+j, &objs[j]);
} }
gettimeofday(&stop, NULL); stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num)); printf(" %zu ns\n", normalize(&start, &stop, num));
} }
/* Spread out the keys more to try to make it harder. */ /* Spread out the keys more to try to make it harder. */
printf("Details: reinserting with spread\n"); printf("Details: reinserting with spread\n");
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
if (!jmap_obj_del(jmap, num*4 + i)) if (!jmap_del(jmap, num*4 + i))
abort(); abort();
jmap_obj_add(jmap, num * 5 + i * 9, objs[i].self); jmap_add(jmap, num * 5 + i * 9, objs[i].self);
} }
if (jmap_obj_popcount(jmap, 0, -1) != num) if (jmap_popcount(jmap, 0, -1) != num)
abort(); abort();
printf("Lookup after churn & spread (match): "); printf("Lookup after churn & spread (match): ");
fflush(stdout); fflush(stdout);
gettimeofday(&start, NULL); start = time_now();
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
if (jmap_obj_get(jmap, num * 5 + i * 9)->self != objs[i].self) { if (jmap_get(jmap, num * 5 + i * 9)->self != objs[i].self) {
printf("i =%u\n", i); printf("i =%u\n", i);
abort(); abort();
} }
gettimeofday(&stop, NULL); stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num)); printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Lookup after churn & spread (miss): "); printf("Lookup after churn & spread (miss): ");
fflush(stdout); fflush(stdout);
gettimeofday(&start, NULL); start = time_now();
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
if (jmap_obj_get(jmap, num * 6 + i * 9)) if (jmap_get(jmap, num * 6 + i * 9))
abort(); abort();
gettimeofday(&stop, NULL); stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num)); printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Lookup after churn & spread (random): "); printf("Lookup after churn & spread (random): ");
fflush(stdout); fflush(stdout);
gettimeofday(&start, NULL); start = time_now();
for (i = 0, j = 0; i < num; i++, j = (j + 10007) % num) for (i = 0, j = 0; i < num; i++, j = (j + 10007) % num)
if (jmap_obj_get(jmap, num * 5 + j * 9)->self != &objs[j]) if (jmap_get(jmap, num * 5 + j * 9)->self != &objs[j])
abort(); abort();
gettimeofday(&stop, NULL); stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num)); printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Lookup after churn & spread (half-random): "); printf("Lookup after churn & spread (half-random): ");
fflush(stdout); fflush(stdout);
gettimeofday(&start, NULL); start = time_now();
for (i = 0, j = 0; i < num/2; i++, j = (j + 10007) % num) { for (i = 0, j = 0; i < num/2; i++, j = (j + 10007) % num) {
if (jmap_obj_get(jmap, num * 5 + j * 9)->self != &objs[j]) if (jmap_get(jmap, num * 5 + j * 9)->self != &objs[j])
abort(); abort();
if (jmap_obj_get(jmap, num * 5 + (j + 1) * 9)->self != &objs[j+1]) if (jmap_get(jmap, num * 5 + (j + 1) * 9)->self != &objs[j+1])
abort(); abort();
} }
gettimeofday(&stop, NULL); stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num)); printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Deleting half after churn & spread: "); printf("Deleting half after churn & spread: ");
fflush(stdout); fflush(stdout);
gettimeofday(&start, NULL); start = time_now();
for (i = 0; i < num; i+=2) for (i = 0; i < num; i+=2)
jmap_obj_del(jmap, num * 5 + i * 9); jmap_del(jmap, num * 5 + i * 9);
gettimeofday(&stop, NULL); stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num)); printf(" %zu ns\n", normalize(&start, &stop, num));
printf("Adding (a different) half after churn & spread: "); printf("Adding (a different) half after churn & spread: ");
fflush(stdout); fflush(stdout);
gettimeofday(&start, NULL); start = time_now();
for (i = 0; i < num; i+=2) for (i = 0; i < num; i+=2)
jmap_obj_add(jmap, num * 6 + i * 9, objs[i].self); jmap_add(jmap, num * 6 + i * 9, objs[i].self);
gettimeofday(&stop, NULL); stop = time_now();
printf(" %zu ns\n", normalize(&start, &stop, num)); printf(" %zu ns\n", normalize(&start, &stop, num));
jmap_free(jmap);
free (objs);
return 0; return 0;
} }
...@@ -26,7 +26,7 @@ static bool likely_one_unlikely_two(unsigned int val1, unsigned int val2) ...@@ -26,7 +26,7 @@ static bool likely_one_unlikely_two(unsigned int val1, unsigned int val2)
return false; return false;
} }
int main(int argc, char *argv[]) int main(void)
{ {
char *bad; char *bad;
......
...@@ -17,7 +17,7 @@ static bool one_seems_unlikely(unsigned int val) ...@@ -17,7 +17,7 @@ static bool one_seems_unlikely(unsigned int val)
return false; return false;
} }
int main(int argc, char *argv[]) int main(void)
{ {
plan_tests(4); plan_tests(4);
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
* { * {
* struct parent p; * struct parent p;
* struct child *c; * struct child *c;
* unsigned int i; * int i;
* *
* if (argc < 2) * if (argc < 2)
* errx(1, "Usage: %s parent children...", argv[0]); * errx(1, "Usage: %s parent children...", argv[0]);
......
...@@ -291,6 +291,21 @@ static inline bool list_empty_nodebug(const struct list_head *h) ...@@ -291,6 +291,21 @@ static inline bool list_empty_nodebug(const struct list_head *h)
} }
#endif #endif
/**
* list_empty_nocheck - is a list empty?
* @h: the list_head
*
* If the list is empty, returns true. This doesn't perform any
* debug check for list consistency, so it can be called without
* locks, racing with the list being modified. This is ok for
* checks where an incorrect result is not an issue (optimized
* bail out path for example).
*/
static inline bool list_empty_nocheck(const struct list_head *h)
{
return h->n.next == &h->n;
}
/** /**
* list_del - delete an entry from an (unknown) linked list. * list_del - delete an entry from an (unknown) linked list.
* @n: the list_node to delete from the list. * @n: the list_node to delete from the list.
...@@ -701,12 +716,12 @@ static inline void list_prepend_list_(struct list_head *to, ...@@ -701,12 +716,12 @@ static inline void list_prepend_list_(struct list_head *to,
* so you can break and continue as normal. * so you can break and continue as normal.
* *
* WARNING! Being the low-level macro that it is, this wrapper doesn't know * WARNING! Being the low-level macro that it is, this wrapper doesn't know
* nor care about the type of @i. The only assumtion made is that @i points * nor care about the type of @i. The only assumption made is that @i points
* to a chunk of memory that at some @offset, relative to @i, contains a * to a chunk of memory that at some @offset, relative to @i, contains a
* properly filled `struct node_list' which in turn contains pointers to * properly filled `struct list_node' which in turn contains pointers to
* memory chunks and it's turtles all the way down. Whith all that in mind * memory chunks and it's turtles all the way down. With all that in mind
* remember that given the wrong pointer/offset couple this macro will * remember that given the wrong pointer/offset couple this macro will
* happilly churn all you memory untill SEGFAULT stops it, in other words * happily churn all you memory until SEGFAULT stops it, in other words
* caveat emptor. * caveat emptor.
* *
* It is worth mentioning that one of legitimate use-cases for that wrapper * It is worth mentioning that one of legitimate use-cases for that wrapper
......
...@@ -17,6 +17,7 @@ static int my_fprintf(FILE *stream, const char *format, ...) ...@@ -17,6 +17,7 @@ static int my_fprintf(FILE *stream, const char *format, ...)
{ {
va_list ap; va_list ap;
int ret; int ret;
(void)stream;
va_start(ap, format); va_start(ap, format);
ret = vsprintf(printf_buffer, format, ap); ret = vsprintf(printf_buffer, format, ap);
va_end(ap); va_end(ap);
...@@ -28,7 +29,7 @@ static int my_fprintf(FILE *stream, const char *format, ...) ...@@ -28,7 +29,7 @@ static int my_fprintf(FILE *stream, const char *format, ...)
#include <ccan/tap/tap.h> #include <ccan/tap/tap.h>
#include <ccan/list/list.c> #include <ccan/list/list.c>
int main(int argc, char *argv[]) int main(void)
{ {
struct list_head list; struct list_head list;
struct list_node n1; struct list_node n1;
...@@ -44,7 +45,7 @@ int main(int argc, char *argv[]) ...@@ -44,7 +45,7 @@ int main(int argc, char *argv[])
list.n.prev = &n1; list.n.prev = &n1;
/* Aborting version. */ /* Aborting version. */
sprintf(expect, "run-CCAN_LIST_DEBUG.c:50: prev corrupt in node %p (0) of %p\n", sprintf(expect, "run-CCAN_LIST_DEBUG.c:51: prev corrupt in node %p (0) of %p\n",
&list, &list); &list, &list);
if (setjmp(aborted) == 0) { if (setjmp(aborted) == 0) {
assert(list_empty(&list)); assert(list_empty(&list));
......
...@@ -16,6 +16,7 @@ static int my_fprintf(FILE *stream, const char *format, ...) ...@@ -16,6 +16,7 @@ static int my_fprintf(FILE *stream, const char *format, ...)
{ {
va_list ap; va_list ap;
int ret; int ret;
(void)stream;
va_start(ap, format); va_start(ap, format);
ret = vsprintf(printf_buffer, format, ap); ret = vsprintf(printf_buffer, format, ap);
va_end(ap); va_end(ap);
...@@ -26,7 +27,7 @@ static int my_fprintf(FILE *stream, const char *format, ...) ...@@ -26,7 +27,7 @@ static int my_fprintf(FILE *stream, const char *format, ...)
#include <ccan/tap/tap.h> #include <ccan/tap/tap.h>
#include <ccan/list/list.c> #include <ccan/list/list.c>
int main(int argc, char *argv[]) int main(void)
{ {
struct list_head list; struct list_head list;
struct list_node n1; struct list_node n1;
......
...@@ -8,7 +8,7 @@ struct child { ...@@ -8,7 +8,7 @@ struct child {
struct list_node list; struct list_node list;
}; };
int main(int argc, char *argv[]) int main(void)
{ {
struct child c1, c2; struct child c1, c2;
struct list_head list = LIST_HEAD_INIT(list); struct list_head list = LIST_HEAD_INIT(list);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
int main(int argc, char *argv[]) int main(void)
{ {
struct list_head list1, list2; struct list_head list1, list2;
struct list_node n1, n2, n3; struct list_node n1, n2, n3;
......
...@@ -14,7 +14,7 @@ struct child { ...@@ -14,7 +14,7 @@ struct child {
struct list_node list; struct list_node list;
}; };
int main(int argc, char *argv[]) int main(void)
{ {
struct parent parent; struct parent parent;
struct child c1, c2, c3; struct child c1, c2, c3;
......
...@@ -17,7 +17,7 @@ static bool list_expect(struct list_head *h, ...) ...@@ -17,7 +17,7 @@ static bool list_expect(struct list_head *h, ...)
return (n->next == &h->n); return (n->next == &h->n);
} }
int main(int argc, char *argv[]) int main(void)
{ {
struct list_head h1, h2; struct list_head h1, h2;
struct list_node n[4]; struct list_node n[4];
......
...@@ -19,7 +19,7 @@ static LIST_HEAD(static_list); ...@@ -19,7 +19,7 @@ static LIST_HEAD(static_list);
#define ref(obj, counter) ((counter)++, (obj)) #define ref(obj, counter) ((counter)++, (obj))
int main(int argc, char *argv[]) int main(void)
{ {
struct parent parent; struct parent parent;
struct child c1, c2, c3, *c, *n; struct child c1, c2, c3, *c, *n;
......
...@@ -16,7 +16,7 @@ struct child { ...@@ -16,7 +16,7 @@ struct child {
static LIST_HEAD(static_list); static LIST_HEAD(static_list);
int main(int argc, char *argv[]) int main(void)
{ {
struct parent parent; struct parent parent;
struct child c1, c2, c3, x1, *c, *n; struct child c1, c2, c3, x1, *c, *n;
......
...@@ -250,6 +250,7 @@ static inline void *memcheck_(const void *data, size_t len) ...@@ -250,6 +250,7 @@ static inline void *memcheck_(const void *data, size_t len)
#else #else
static inline void *memcheck_(const void *data, size_t len) static inline void *memcheck_(const void *data, size_t len)
{ {
(void)len;
return (void *)data; return (void *)data;
} }
#endif #endif
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* return false; * return false;
* } * }
* // A short write means out of space. * // A short write means out of space.
* if (ret < strlen(string)) { * if (ret < (int)strlen(string)) {
* unlink(file); * unlink(file);
* errno = ENOSPC; * errno = ENOSPC;
* return false; * return false;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
int main(int argc, char *argv[]) int main(void)
{ {
const char *name = "noerr.file"; const char *name = "noerr.file";
int fd; int fd;
......
...@@ -185,7 +185,7 @@ void opt_register_table(const struct opt_table *table, const char *desc); ...@@ -185,7 +185,7 @@ void opt_register_table(const struct opt_table *table, const char *desc);
* string (or see opt_set_alloc) and return false. * string (or see opt_set_alloc) and return false.
* *
* Example: * Example:
* static char *explode(const char *optarg, void *unused) * static char *explode(const char *optarg, void *unused UNNEEDED)
* { * {
* errx(1, "BOOM! %s", optarg); * errx(1, "BOOM! %s", optarg);
* } * }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include <ccan/opt/parse.c> #include <ccan/opt/parse.c>
#include <ccan/opt/usage.c> #include <ccan/opt/usage.c>
int main(int argc, char *argv[]) int main(void)
{ {
opt_register_noarg("-v", opt_version_and_exit, opt_register_noarg("-v", opt_version_and_exit,
(const char *)"1.2.3", (const char *)"1.2.3",
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment