File: nqueen_c_thread.c

package info (click to toggle)
smlsharp 4.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 123,732 kB
  • sloc: ansic: 16,725; sh: 4,347; makefile: 2,191; java: 742; haskell: 493; ruby: 305; cpp: 284; pascal: 256; ml: 255; lisp: 141; asm: 97; sql: 74
file content (130 lines) | stat: -rw-r--r-- 2,328 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include "thread_c.h"

static int repeat = 10;
static int size = 14;
static unsigned int cutOff = 7;

struct board {
	unsigned int queens, limit, left, down, right, kill;
};

static struct board
init(unsigned int width)
{
	struct board b;
	b.queens = width;
	b.limit = 1 << width;
	b.left = 0;
	b.down = 0;
	b.right = 0;
	b.kill = 0;
	return b;
}

static struct board *
put(const struct board *b, unsigned int bit)
{
	struct board *r = malloc(sizeof(struct board));;
	r->queens = b->queens - 1;
	r->limit = b->limit;
	r->left = (b->left | bit) >> 1;
	r->down = b->down | bit;
	r->right = (b->right | bit) << 1;
	r->kill = r->left | r->down | r->right;
	return r;
}

static int solve(const struct board *);

static int
ssum(const struct board *board, unsigned int bit)
{
	struct board *b;
	int sum = 0;
	while (bit < board->limit) {
		if ((board->kill & bit) == 0) {
			b = put(board, bit);
			sum += solve(b);
			free(b);
		}
		bit <<= 1;
	}
	return sum;
}

static void *
psum_fn(void *arg)
{
	const struct board *board = arg;
	int result = solve(board);
	free((void*)board);
	return RET(result);
}

static int
psum(const struct board *board, unsigned int bit)
{
	struct board *b;
	thread_t t;
	int n;
	while (bit < board->limit) {
		if ((board->kill & bit) == 0) {
			b = put(board, bit);
			t = create(psum_fn, b);
			n = psum(board, bit << 1);
			return n + GET(join(t));
		}
		bit <<= 1;
	}
	return 0;
}

static int
solve(const struct board *board)
{
	if (board->queens == 0)
		return 1;
	else if (board->queens <= cutOff)
		return ssum(board, 1);
	else
		return psum(board, 1);
}

static int
doit()
{
	const struct board b = init(size);
	return solve(&b);
}

static void
rep(int n)
{
	struct timeval t1, t2;
	double d1, d2;
	int r;
	while (n > 0) {
		gettimeofday(&t1, NULL);
		r = doit();
		gettimeofday(&t2, NULL);
		d1 = t1.tv_sec + (double)t1.tv_usec / 1000000;
		d2 = t2.tv_sec + (double)t2.tv_usec / 1000000;
		printf(" - {result: %d, time: %.6f}\n", r, d2 - d1);
		n--;
	}
}

int
main(int argc, char **argv)
{
	if (argc > 1) repeat = atoi(argv[1]);
	if (argc > 2) size = atoi(argv[2]);
	if (argc > 3) cutOff = atoi(argv[3]);
	printf(" bench: nqueen_c_%s\n size: %d\n cutoff: %d\n results:\n",
	       threadtype, size, cutOff);
	rep(repeat);
	return 0;
}