Compare commits
1143 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
021c3c2816 | ||
|
|
ff2c966e7f | ||
|
|
14cc40a31a | ||
|
|
881df0e629 | ||
|
|
1c2f6f5597 | ||
|
|
d51a9fd6b7 | ||
|
|
464f30d301 | ||
|
|
8a28408616 | ||
|
|
e1dc7ece62 | ||
|
|
99127ff2e7 | ||
|
|
81d6ec908a | ||
|
|
38b4fc8069 | ||
|
|
11ab73f6d8 | ||
|
|
18e9cb1187 | ||
|
|
502a2bd69f | ||
|
|
8b517d7f00 | ||
|
|
cad071009d | ||
|
|
181a3309df | ||
|
|
02fa3e3179 | ||
|
|
a8eafcdc0e | ||
|
|
bcf2465b0b | ||
|
|
c3dc01caf1 | ||
|
|
cf4faa491a | ||
|
|
59966255ad | ||
|
|
f8acc0af7e | ||
|
|
02a29060d2 | ||
|
|
0255ed6335 | ||
|
|
96c2ab22e0 | ||
|
|
5494e6e7ab | ||
|
|
32db571681 | ||
|
|
a6af56fa4d | ||
|
|
5884606ec3 | ||
|
|
f6c0f76cc5 | ||
|
|
f9be9a2302 | ||
|
|
95f0bd0acf | ||
|
|
8dce4c283d | ||
|
|
fff16169c6 | ||
|
|
5f7eb78918 | ||
|
|
e61035c5a3 | ||
|
|
37e3f561f1 | ||
|
|
ba3bcd16a6 | ||
|
|
207bd7d2cd | ||
|
|
4047ccad2f | ||
|
|
a13e920af0 | ||
|
|
f958d7d482 | ||
|
|
7cc6abeef6 | ||
|
|
54253aae4c | ||
|
|
09aabaea9f | ||
|
|
ecec454e92 | ||
|
|
7b2fc0643f | ||
|
|
d2fda73ad7 | ||
|
|
5aa21d8b32 | ||
|
|
9fc90b6747 | ||
|
|
edef84da2b | ||
|
|
6430e672c9 | ||
|
|
a31d268b76 | ||
|
|
e353f9c088 | ||
|
|
af48a331bf | ||
|
|
80e74fc1e0 | ||
|
|
03dffe3efd | ||
|
|
cb3f5f8b93 | ||
|
|
c7a4d9cf8a | ||
|
|
facc47cb5c | ||
|
|
6876e92f8d | ||
|
|
15f32a8d57 | ||
|
|
6d359dbcc6 | ||
|
|
65e1095c3f | ||
|
|
0cc492f815 | ||
|
|
ee05cc4a27 | ||
|
|
97f38ce4d6 | ||
|
|
732b75325c | ||
|
|
7d0ac94809 | ||
|
|
906378a32e | ||
|
|
cc5654cb59 | ||
|
|
b35aa21f9f | ||
|
|
409b61fe3c | ||
|
|
d5d910e8b6 | ||
|
|
5e29f4be93 | ||
|
|
b27589517a | ||
|
|
2870496124 | ||
|
|
43671067fb | ||
|
|
30d706c35e | ||
|
|
b57680b0b2 | ||
|
|
e418bc67d2 | ||
|
|
a7b9e484d0 | ||
|
|
6b7ae4e751 | ||
|
|
436acb4f75 | ||
|
|
050ceff1ae | ||
|
|
a0cd77e833 | ||
|
|
1d1d988aa7 | ||
|
|
dd37064a15 | ||
|
|
49f1e84253 | ||
|
|
9de257505b | ||
|
|
706a1e552c | ||
|
|
18bbe12425 | ||
|
|
04fcae207d | ||
|
|
542e42b21e | ||
|
|
feeccdf4ec | ||
|
|
bfe5eb7f8c | ||
|
|
f32b72ca5d | ||
|
|
9cd7135516 | ||
|
|
bd2c54fa9f | ||
|
|
8570ef19eb | ||
|
|
d144299af4 | ||
|
|
badbaf66b6 | ||
|
|
b801be99d4 | ||
|
|
cc13d576f0 | ||
|
|
71fdaa4238 | ||
|
|
158d603528 | ||
|
|
9aca9e6deb | ||
|
|
0ec1104ba9 | ||
|
|
702bef8493 | ||
|
|
c76ad94492 | ||
|
|
d83a9a8f44 | ||
|
|
3d8de95f99 | ||
|
|
24b9860c1b | ||
|
|
cc303017c3 | ||
|
|
49437a02c9 | ||
|
|
b319f027a0 | ||
|
|
09777952ee | ||
|
|
e50a5b7771 | ||
|
|
fb98a8c6c2 | ||
|
|
96d1a4aee6 | ||
|
|
105b37f1b4 | ||
|
|
c4a0efafd7 | ||
|
|
db93641941 | ||
|
|
1cf2ee4597 | ||
|
|
baf20010e7 | ||
|
|
16afb5c468 | ||
|
|
225c28716f | ||
|
|
aa9a78e463 | ||
|
|
7419d0c382 | ||
|
|
4be37e91b9 | ||
|
|
1018bf6a00 | ||
|
|
37e252587a | ||
|
|
bb7dca275c | ||
|
|
69ac6cc70e | ||
|
|
df1fbe3c06 | ||
|
|
8771c3061f | ||
|
|
8ff7e55ab5 | ||
|
|
37dd9086ec | ||
|
|
67c47459f2 | ||
|
|
0f4b75bea2 | ||
|
|
d42a56afc5 | ||
|
|
b4547a560b | ||
|
|
04fa6a3744 | ||
|
|
26da6daaa9 | ||
|
|
e7911ad9ea | ||
|
|
11e7a712f4 | ||
|
|
61d2150a07 | ||
|
|
3fa0fa713b | ||
|
|
f1534f5797 | ||
|
|
9a2720fb35 | ||
|
|
c213fd1fd8 | ||
|
|
525116dbff | ||
|
|
1c1dc0e0fc | ||
|
|
c6e6f1fec2 | ||
|
|
da7af44060 | ||
|
|
6742fc526f | ||
|
|
9b84caf3a5 | ||
|
|
06d6685eb5 | ||
|
|
1dfd65f6d0 | ||
|
|
7242e4f71b | ||
|
|
be39bf382a | ||
|
|
2ba9374789 | ||
|
|
d97dea51ec | ||
|
|
24dd0355a3 | ||
|
|
6d038e762b | ||
|
|
728a299728 | ||
|
|
4e4e5fca54 | ||
|
|
61ede86737 | ||
|
|
dc4c59d42b | ||
|
|
0a01f3f607 | ||
|
|
f3579f6460 | ||
|
|
5c8fa6ae1a | ||
|
|
b7d93500f1 | ||
|
|
df72e20cc5 | ||
|
|
023670f6ba | ||
|
|
567d41d936 | ||
|
|
3b00a77de5 | ||
|
|
288700c4d8 | ||
|
|
544247c918 | ||
|
|
8cf08e4b25 | ||
|
|
eee96a5bb7 | ||
|
|
667cd518ce | ||
|
|
4c6f4e569e | ||
|
|
9c4fd4e9c9 | ||
|
|
db2698c87c | ||
|
|
07c216d603 | ||
|
|
1a00e39539 | ||
|
|
92e50adfa3 | ||
|
|
2b284e7366 | ||
|
|
e7030c4bf5 | ||
|
|
a38e1a9c00 | ||
|
|
faf713632c | ||
|
|
725c2646a0 | ||
|
|
f2e94ff94b | ||
|
|
090699c0f6 | ||
|
|
213b8f9af4 | ||
|
|
9184249b39 | ||
|
|
280f08be84 | ||
|
|
d304da3803 | ||
|
|
357d00cdb1 | ||
|
|
f3b7dcc5bd | ||
|
|
82e7c1d124 | ||
|
|
f972691eea | ||
|
|
c52ab932e6 | ||
|
|
f30733c806 | ||
|
|
bf4155846c | ||
|
|
230cf2ec91 | ||
|
|
7ff75ac2f2 | ||
|
|
167be7f260 | ||
|
|
7e3762fdc6 | ||
|
|
94c71c171f | ||
|
|
5f7826270c | ||
|
|
b117da2db3 | ||
|
|
e02883c0a2 | ||
|
|
e588e0ca2b | ||
|
|
d4f60d362b | ||
|
|
46bcd9a92c | ||
|
|
dbd88a1aa4 | ||
|
|
965407f238 | ||
|
|
96ae35e2ac | ||
|
|
dc0a006c7c | ||
|
|
2f28a12cdb | ||
|
|
35e8308bf7 | ||
|
|
fc97c7a38d | ||
|
|
48bc07ae97 | ||
|
|
a624ce69f7 | ||
|
|
d0eba23af3 | ||
|
|
43362ab4fb | ||
|
|
38e273597c | ||
|
|
e8b3e22612 | ||
|
|
32ee1b3cd8 | ||
|
|
8676aeb798 | ||
|
|
37511ec520 | ||
|
|
46eea4d105 | ||
|
|
0a63c3e362 | ||
|
|
45c7cfd2e6 | ||
|
|
5c8fe28b72 | ||
|
|
50ee279f25 | ||
|
|
562ccff822 | ||
|
|
11539030cd | ||
|
|
aca066f337 | ||
|
|
5ee00209d2 | ||
|
|
e7bdb00700 | ||
|
|
357732a840 | ||
|
|
f89dd62776 | ||
|
|
1ca20a2697 | ||
|
|
23a5d64fd0 | ||
|
|
61e6bb1247 | ||
|
|
d4fd06c3dc | ||
|
|
47af53f9aa | ||
|
|
3f923f3902 | ||
|
|
189dee26c6 | ||
|
|
b9d48b4a93 | ||
|
|
ec7f81f4bc | ||
|
|
29fac7de44 | ||
|
|
555273495b | ||
|
|
024d41d0c2 | ||
|
|
46ec4357e7 | ||
|
|
c6e716eb31 | ||
|
|
388803b139 | ||
|
|
4ac481b45f | ||
|
|
94334c233e | ||
|
|
b7f010de52 | ||
|
|
a0c011f1a8 | ||
|
|
449a850023 | ||
|
|
e51f65af1f | ||
|
|
037c8b9ae9 | ||
|
|
b19e5885fe | ||
|
|
9b0af51386 | ||
|
|
bf21549faa | ||
|
|
6f74fb962e | ||
|
|
6ec8135256 | ||
|
|
e94dfb78f8 | ||
|
|
bdef758d5c | ||
|
|
2c4455b12a | ||
|
|
c8695fae35 | ||
|
|
a973d1d523 | ||
|
|
15a609d5d6 | ||
|
|
c12f4df910 | ||
|
|
72dcd3c58b | ||
|
|
4ece9c6cb0 | ||
|
|
a07539fb88 | ||
|
|
6988e5f074 | ||
|
|
aba016da72 | ||
|
|
09aef5c0ae | ||
|
|
9b161187ec | ||
|
|
8883f36fe3 | ||
|
|
0850f68fd1 | ||
|
|
57f4e90257 | ||
|
|
f8f428cc18 | ||
|
|
e23e86921b | ||
|
|
65ed6a9def | ||
|
|
e99c788155 | ||
|
|
c7022c1a0c | ||
|
|
26cd41f0c7 | ||
|
|
fb19846855 | ||
|
|
205ea95802 | ||
|
|
c5215fdd48 | ||
|
|
fad5eb0a87 | ||
|
|
b3c0e9d3cc | ||
|
|
470b79385b | ||
|
|
1ecf99bd0f | ||
|
|
e0fb4d1da9 | ||
|
|
ac2a0e615b | ||
|
|
52bd4e29ff | ||
|
|
833e4d1319 | ||
|
|
564b60520c | ||
|
|
085987ff2c | ||
|
|
aaf9cfd18c | ||
|
|
7ff686d6ec | ||
|
|
0cc9409fda | ||
|
|
6dd27e7cff | ||
|
|
d0eeb3ebdc | ||
|
|
fa99986143 | ||
|
|
6ea8eba8ce | ||
|
|
9b5c7153c9 | ||
|
|
d52b0c32a0 | ||
|
|
7734ead520 | ||
|
|
1bed9b3fea | ||
|
|
8b57c49490 | ||
|
|
296450451b | ||
|
|
4f5f90222f | ||
|
|
f58fb32283 | ||
|
|
9c45b4462c | ||
|
|
690f6ea1d7 | ||
|
|
1c140f7382 | ||
|
|
e5a93bf99a | ||
|
|
f3c368ca73 | ||
|
|
b8823a8b34 | ||
|
|
355a42f36d | ||
|
|
658bcbcbdc | ||
|
|
7669c5b5ec | ||
|
|
a390ca5f30 | ||
|
|
c46c41eae3 | ||
|
|
82aa5b1de6 | ||
|
|
12379c697a | ||
|
|
f5348e17f8 | ||
|
|
a2b4abd89a | ||
|
|
6d5e100d0d | ||
|
|
1886d03faa | ||
|
|
9b62facdd4 | ||
|
|
da92f5b2d6 | ||
|
|
f1069a30b9 | ||
|
|
2718b42828 | ||
|
|
fc52f2c007 | ||
|
|
0b9070fe01 | ||
|
|
c04598f2b0 | ||
|
|
96778a1c21 | ||
|
|
935d891e9d | ||
|
|
682875adff | ||
|
|
0126d01435 | ||
|
|
946db8ba65 | ||
|
|
7814a8e131 | ||
|
|
ebc3d232f4 | ||
|
|
f087c66f95 | ||
|
|
508fdc3496 | ||
|
|
d63752ef4d | ||
|
|
6fb76443b3 | ||
|
|
2eefed84c9 | ||
|
|
230530f5ea | ||
|
|
17d92233d9 | ||
|
|
54a65e6d87 | ||
|
|
26d385c18b | ||
|
|
da2a22c384 | ||
|
|
0fa9a8929c | ||
|
|
2a1a531ba3 | ||
|
|
51f6b6d33f | ||
|
|
b5a100b859 | ||
|
|
54fcab20e3 | ||
|
|
a2bc90d1d7 | ||
|
|
c01f8c3d3c | ||
|
|
e4181a7f1b | ||
|
|
01f6f2d741 | ||
|
|
c5df37c111 | ||
|
|
e0ceeab0d1 | ||
|
|
93077c98e4 | ||
|
|
3dab303826 | ||
|
|
3160fd24ba | ||
|
|
ce7822c130 | ||
|
|
745a3adebd | ||
|
|
218ec6c085 | ||
|
|
d30d7800e0 | ||
|
|
8820d97039 | ||
|
|
b52fde7cf7 | ||
|
|
2b4d0b6ff9 | ||
|
|
21f1370d2a | ||
|
|
d78f9b834a | ||
|
|
445deb7470 | ||
|
|
02b67558e8 | ||
|
|
91c8f87fb1 | ||
|
|
d056b7fa52 | ||
|
|
2a609af518 | ||
|
|
1d5d6616ae | ||
|
|
b9b3efb09f | ||
|
|
0f34d506b5 | ||
|
|
5eccc122e8 | ||
|
|
681b51aac4 | ||
|
|
4268cb8efe | ||
|
|
3f1a72908c | ||
|
|
2fed476ce1 | ||
|
|
6cb39dd3da | ||
|
|
88cc1ca55a | ||
|
|
1bd9769111 | ||
|
|
47372813ef | ||
|
|
fc213c873d | ||
|
|
972f0bd3db | ||
|
|
808310a569 | ||
|
|
0a5450fe04 | ||
|
|
9bab0b8a24 | ||
|
|
17182732f5 | ||
|
|
18c77744ff | ||
|
|
ac93a6ff6c | ||
|
|
13e3b2f433 | ||
|
|
f2da6581ba | ||
|
|
444fc892b0 | ||
|
|
b56aee3697 | ||
|
|
35a7dcb162 | ||
|
|
e0fde02290 | ||
|
|
59b8245bbc | ||
|
|
8f9daaa3ba | ||
|
|
d3b751e4d9 | ||
|
|
7731061903 | ||
|
|
b9683d3748 | ||
|
|
66979aa468 | ||
|
|
93f9c023cc | ||
|
|
e0ee0cc66a | ||
|
|
9b135a9c20 | ||
|
|
e171bf74f8 | ||
|
|
bb2e99dfc2 | ||
|
|
b37d175e59 | ||
|
|
f087633efd | ||
|
|
bbce726c8a | ||
|
|
bbc4ea4ae8 | ||
|
|
2126d81488 | ||
|
|
06b381d1c9 | ||
|
|
08eea0f0e4 | ||
|
|
a1798a8188 | ||
|
|
0fac8cba47 | ||
|
|
1ca74aba6f | ||
|
|
2ce30382d9 | ||
|
|
8bc545be2a | ||
|
|
891fcd8ce1 | ||
|
|
bd06091874 | ||
|
|
3e3edcc465 | ||
|
|
89a32267f7 | ||
|
|
021177ca9b | ||
|
|
115364b0a9 | ||
|
|
6d15d00ac4 | ||
|
|
bdaa43510b | ||
|
|
9a51f5c350 | ||
|
|
301c0a6303 | ||
|
|
65f486ff02 | ||
|
|
df096a7771 | ||
|
|
0e9a9f243f | ||
|
|
12c964b2b7 | ||
|
|
cf71f5cd60 | ||
|
|
adab2e16bd | ||
|
|
a3e3235d97 | ||
|
|
2be3c4b0e3 | ||
|
|
0ee796632a | ||
|
|
1fe67c125d | ||
|
|
ba996f5e27 | ||
|
|
64bf5bafe9 | ||
|
|
4d05bbf2a4 | ||
|
|
471990f771 | ||
|
|
7b623aab9d | ||
|
|
e871ae1270 | ||
|
|
c44830ebf3 | ||
|
|
3e4a04f34d | ||
|
|
38827dd9ca | ||
|
|
21fd9f037e | ||
|
|
033763eaf7 | ||
|
|
2573094df2 | ||
|
|
745026b7b4 | ||
|
|
a07d955eaa | ||
|
|
9d6f4e2e7f | ||
|
|
ff07d54843 | ||
|
|
e53879328c | ||
|
|
b792412d31 | ||
|
|
49c6f1053c | ||
|
|
4d960f6dc6 | ||
|
|
8941665896 | ||
|
|
9cc0f60666 | ||
|
|
fdb8edf5ea | ||
|
|
9ba9fe818d | ||
|
|
92224d27b1 | ||
|
|
157a4bd926 | ||
|
|
29d6881112 | ||
|
|
e2692921e1 | ||
|
|
b63138c3ec | ||
|
|
a59fcc33e6 | ||
|
|
07311f3157 | ||
|
|
17637ed1bb | ||
|
|
f15828e901 | ||
|
|
dadd689359 | ||
|
|
b750cab56a | ||
|
|
485748c416 | ||
|
|
080699f7df | ||
|
|
8e35f54931 | ||
|
|
d44f1a77ee | ||
|
|
4181046488 | ||
|
|
d7c398b638 | ||
|
|
5f5d0aa4ff | ||
|
|
9f1520b4c0 | ||
|
|
a98e8c0889 | ||
|
|
ee445a2ba4 | ||
|
|
b2c226cb7d | ||
|
|
13614f4e1c | ||
|
|
4f9ccdd70f | ||
|
|
4e36b1e3da | ||
|
|
f12f8a6c14 | ||
|
|
c57c54ce96 | ||
|
|
c8130df1d9 | ||
|
|
af8a742d00 | ||
|
|
e67500aa15 | ||
|
|
a6d3bf6fc3 | ||
|
|
3e617f3cd6 | ||
|
|
0fe35b907a | ||
|
|
3fc7c97827 | ||
|
|
7f79d249a6 | ||
|
|
f138374027 | ||
|
|
f52a1ae849 | ||
|
|
3bc0fe1ee3 | ||
|
|
fa0cc27400 | ||
|
|
4cb29bde2e | ||
|
|
2dcf75a722 | ||
|
|
671fd94e25 | ||
|
|
717d2f6f9e | ||
|
|
8cb95cb916 | ||
|
|
56b446190a | ||
|
|
86f9e836be | ||
|
|
a90a170361 | ||
|
|
889a5e0cf1 | ||
|
|
9f8bc00cf5 | ||
|
|
3363a1c227 | ||
|
|
fc9939c4e1 | ||
|
|
7267f796e6 | ||
|
|
7dfeceb8cc | ||
|
|
3807e520ec | ||
|
|
7625b1a4f4 | ||
|
|
1fc5cc1b59 | ||
|
|
61ccb43487 | ||
|
|
bf24b120d7 | ||
|
|
b70acf3c5b | ||
|
|
b5be6b72cb | ||
|
|
318ad3c1e4 | ||
|
|
e949a2ed2f | ||
|
|
8d0108fc5d | ||
|
|
ba41efa8a0 | ||
|
|
f81660b6db | ||
|
|
91bceb4ace | ||
|
|
be746628c7 | ||
|
|
ec5f531f4b | ||
|
|
37e5816bcd | ||
|
|
665bb43a4c | ||
|
|
e4bf004560 | ||
|
|
1609df3275 | ||
|
|
24f288770e | ||
|
|
65e6319b12 | ||
|
|
ec75953f50 | ||
|
|
801a13f791 | ||
|
|
eea8d6aa96 | ||
|
|
2b9cd71d67 | ||
|
|
5df83e3bd9 | ||
|
|
6061707371 | ||
|
|
20899c05a4 | ||
|
|
4c8c5e2f74 | ||
|
|
d1a95c643e | ||
|
|
9c3ea0d32d | ||
|
|
67e0894d9e | ||
|
|
6cc87a31c6 | ||
|
|
b8c766a9c5 | ||
|
|
66441c9b4b | ||
|
|
18d51d1de8 | ||
|
|
01d5fc670b | ||
|
|
0f1cbfd3da | ||
|
|
586f10ecb1 | ||
|
|
978737f5d5 | ||
|
|
fa0e057f8a | ||
|
|
bca7bfa927 | ||
|
|
12d654a6fc | ||
|
|
8e64e4383c | ||
|
|
f59d8cde26 | ||
|
|
94c0519be2 | ||
|
|
529c502876 | ||
|
|
c04c8f10f0 | ||
|
|
e05d35e6e0 | ||
|
|
e1e2df656a | ||
|
|
f7da5b29f0 | ||
|
|
2b4c236773 | ||
|
|
a8ca75738a | ||
|
|
aad4890082 | ||
|
|
e5edd3b983 | ||
|
|
a47341cf96 | ||
|
|
e46bda5093 | ||
|
|
a98d1d67d6 | ||
|
|
ba2884f343 | ||
|
|
1d80155d5e | ||
|
|
a0e42aa4e2 | ||
|
|
92959cd4ef | ||
|
|
2c802399c3 | ||
|
|
8ed72a8470 | ||
|
|
0d9a8207d6 | ||
|
|
04edbb0703 | ||
|
|
e1c1fce92c | ||
|
|
c8695209f6 | ||
|
|
9b95112a2d | ||
|
|
a602c57c8d | ||
|
|
f3228592f5 | ||
|
|
87b8254da1 | ||
|
|
20eab80189 | ||
|
|
810389c07a | ||
|
|
3badd3782b | ||
|
|
be2a264915 | ||
|
|
b81baf5423 | ||
|
|
64359c9417 | ||
|
|
5a3853f83f | ||
|
|
532d746036 | ||
|
|
c66e18b175 | ||
|
|
2d4bd3b3ad | ||
|
|
a96d6c68e2 | ||
|
|
504815091f | ||
|
|
4dd3e7fe35 | ||
|
|
4c614909ff | ||
|
|
b0a23c73cf | ||
|
|
922c1f8f9f | ||
|
|
c3c58eb601 | ||
|
|
ce3c52d17d | ||
|
|
6663d0264e | ||
|
|
6e4d623dc8 | ||
|
|
8e704d9718 | ||
|
|
5bd32bd90d | ||
|
|
b9f417e2e6 | ||
|
|
9f7b087235 | ||
|
|
2cb9738649 | ||
|
|
0dc590a9f8 | ||
|
|
dfd2c60509 | ||
|
|
fd27393df3 | ||
|
|
233950da40 | ||
|
|
bd0aafb4fd | ||
|
|
a672eae3d1 | ||
|
|
99d0d771a7 | ||
|
|
8dcea0ac07 | ||
|
|
7a6c6ec946 | ||
|
|
dfe79cc784 | ||
|
|
4a439c2359 | ||
|
|
4c16c82500 | ||
|
|
5513c49c54 | ||
|
|
b61f48e5aa | ||
|
|
de4b39a1a3 | ||
|
|
322502b441 | ||
|
|
b7dfd333c5 | ||
|
|
178da7c6a9 | ||
|
|
d89ea3e6f9 | ||
|
|
6c9c1e6712 | ||
|
|
b10bcd924b | ||
|
|
d8e2e9a41f | ||
|
|
1f70b279ba | ||
|
|
e33e57684f | ||
|
|
a0c6649960 | ||
|
|
ca73dea3b9 | ||
|
|
648bd22427 | ||
|
|
0231d8f86d | ||
|
|
a91908e567 | ||
|
|
ae33883c2f | ||
|
|
4dca5d4db7 | ||
|
|
21701190ac | ||
|
|
5cd86443ee | ||
|
|
779ddb1832 | ||
|
|
445feaeef5 | ||
|
|
932d973e36 | ||
|
|
9eb6f627fa | ||
|
|
323c2d6775 | ||
|
|
09baeec0da | ||
|
|
8247bccf71 | ||
|
|
bbf37c0404 | ||
|
|
e336b0d60e | ||
|
|
5cd4430a8d | ||
|
|
23420ff67a | ||
|
|
ef50e01c5e | ||
|
|
cc0064b267 | ||
|
|
1aaa599147 | ||
|
|
d27472cc74 | ||
|
|
80ea44c485 | ||
|
|
dba29970d7 | ||
|
|
4cd2617848 | ||
|
|
5b31794dfe | ||
|
|
355f4b0c15 | ||
|
|
bbb5e5d56a | ||
|
|
b8bd9a71c8 | ||
|
|
be3865211c | ||
|
|
0f19cbc6e5 | ||
|
|
49da42983a | ||
|
|
7db7109a5b | ||
|
|
9f8d192991 | ||
|
|
760fd65487 | ||
|
|
8b1df1a259 | ||
|
|
9bc97a5785 | ||
|
|
6707f70b4a | ||
|
|
df30ef5177 | ||
|
|
7e8ad6cad3 | ||
|
|
e0e18f3841 | ||
|
|
328f0dd631 | ||
|
|
15c8d46b04 | ||
|
|
052918a6d9 | ||
|
|
afe41de6b3 | ||
|
|
2ad5dba50a | ||
|
|
0b8a14fed7 | ||
|
|
ac9013162e | ||
|
|
ed2bc7fbe9 | ||
|
|
d0c820acd6 | ||
|
|
2f9f2cbb19 | ||
|
|
bad0de0dcb | ||
|
|
3b62c145f8 | ||
|
|
3914e82f17 | ||
|
|
b522b788b6 | ||
|
|
1b73c79234 | ||
|
|
36956da4d2 | ||
|
|
f4d878f3d8 | ||
|
|
61acd18e79 | ||
|
|
e1b4acfb6e | ||
|
|
d85d3c74db | ||
|
|
8ecee175f2 | ||
|
|
8b10617bba | ||
|
|
90b16a3e85 | ||
|
|
4dc1fb923a | ||
|
|
b8dec948d4 | ||
|
|
87670a7ac1 | ||
|
|
63d293cdbe | ||
|
|
f0dbec0c93 | ||
|
|
79789af2e7 | ||
|
|
8639b0fae9 | ||
|
|
00665a0b72 | ||
|
|
b59c8399fb | ||
|
|
289b30715d | ||
|
|
7770304576 | ||
|
|
890ffa05f8 | ||
|
|
89014b4524 | ||
|
|
f8608a5228 | ||
|
|
437c1e40b2 | ||
|
|
53db80da89 | ||
|
|
28cc3cc960 | ||
|
|
1291778032 | ||
|
|
b930baa580 | ||
|
|
66ee2dec53 | ||
|
|
f2ae2f7eef | ||
|
|
88a593d559 | ||
|
|
5d9bb0a050 | ||
|
|
8048f4d4f6 | ||
|
|
d48e6ae66f | ||
|
|
4f46bd19d0 | ||
|
|
ca49510e6d | ||
|
|
25ac04a444 | ||
|
|
8e52c2e754 | ||
|
|
2bb5ec1e41 | ||
|
|
55522373fd | ||
|
|
c9471e7782 | ||
|
|
5b262ff5ab | ||
|
|
e8d0538a00 | ||
|
|
a1c63e8be6 | ||
|
|
a64b1b4375 | ||
|
|
64500ab0fa | ||
|
|
00b853418e | ||
|
|
8d56bf5ceb | ||
|
|
44f419ec0f | ||
|
|
177cab5fe7 | ||
|
|
187d6a66a5 | ||
|
|
6952fe3a5c | ||
|
|
b19b7c39ac | ||
|
|
9276c4e163 | ||
|
|
2cd7a0395d | ||
|
|
f2be249385 | ||
|
|
81b01f1c2b | ||
|
|
a4d9e63d12 | ||
|
|
64af2aafda | ||
|
|
40cdcf1183 | ||
|
|
182d9cb752 | ||
|
|
c2ddfb343a | ||
|
|
9e9bfc4e26 | ||
|
|
f63c6c008f | ||
|
|
eb2f01aee8 | ||
|
|
30fb5c3e81 | ||
|
|
c780901cd5 | ||
|
|
ca419f3cd8 | ||
|
|
a45421baaf | ||
|
|
be6a3696a9 | ||
|
|
7943ecb812 | ||
|
|
16d8397e30 | ||
|
|
1a6682c21d | ||
|
|
82b14a05f2 | ||
|
|
e66b158f0b | ||
|
|
c88e435724 | ||
|
|
eeb2a1a6e3 | ||
|
|
7335a70a02 | ||
|
|
1b7b2ba216 | ||
|
|
3c836dd71b | ||
|
|
90fce8bfa6 | ||
|
|
1f1ea18b54 | ||
|
|
07caa3fccd | ||
|
|
83fc6fdb34 | ||
|
|
2acb9a6ea7 | ||
|
|
e482b5694f | ||
|
|
6c959207db | ||
|
|
71e8ae01b8 | ||
|
|
a7cc3248fe | ||
|
|
82e09c17a9 | ||
|
|
ae341b31c8 | ||
|
|
ab7adb0027 | ||
|
|
b4b5921dd0 | ||
|
|
c683e4aaa2 | ||
|
|
b7159818f9 | ||
|
|
d4b55fc5b2 | ||
|
|
4f7627972e | ||
|
|
920e1ccfe0 | ||
|
|
54ea317375 | ||
|
|
0731b44809 | ||
|
|
cb84e3f029 | ||
|
|
bb6115b737 | ||
|
|
d8715fba1a | ||
|
|
b4cc8cbac4 | ||
|
|
c3a77d6268 | ||
|
|
ba8c4c6b1a | ||
|
|
44bc2e80dd | ||
|
|
4e8cec05ab | ||
|
|
afecb93e2e | ||
|
|
437c3863f1 | ||
|
|
710435b51b | ||
|
|
cd791bd855 | ||
|
|
7cc6b801e0 | ||
|
|
5a3844981b | ||
|
|
863d166c7b | ||
|
|
b04219fdbb | ||
|
|
61734cc7ae | ||
|
|
0951524ca2 | ||
|
|
b0a6b979a3 | ||
|
|
7f2b077da4 | ||
|
|
06ac31cf1a | ||
|
|
2e14aff80f | ||
|
|
a59a93f476 | ||
|
|
e859f36967 | ||
|
|
25ed5fedda | ||
|
|
3778f1bf77 | ||
|
|
f85f46461f | ||
|
|
5bb517355e | ||
|
|
22eea17b06 | ||
|
|
c8d6efd602 | ||
|
|
b6b17e5648 | ||
|
|
88b012ad3b | ||
|
|
581b320b9d | ||
|
|
b42a5b118f | ||
|
|
eeb322ae64 | ||
|
|
52ede09b17 | ||
|
|
f5c432bcab | ||
|
|
7c12e8ea44 | ||
|
|
30860491ba | ||
|
|
0f6f83a709 | ||
|
|
e3fe634f99 | ||
|
|
dc3e969e14 | ||
|
|
b7f6404168 | ||
|
|
b6b5ec8f75 | ||
|
|
ca37730c9d | ||
|
|
6fb8ae2bd6 | ||
|
|
2924fdfcf7 | ||
|
|
eac390f289 | ||
|
|
de54273f51 | ||
|
|
6b727c0440 | ||
|
|
2c6be49d20 | ||
|
|
a42b7355f4 | ||
|
|
b4a5251391 | ||
|
|
a183ea29f9 | ||
|
|
affffb39b3 | ||
|
|
0ef327bbee | ||
|
|
795b70423e | ||
|
|
49227f65ff | ||
|
|
a386b4c983 | ||
|
|
5cb3fa2f89 | ||
|
|
43d716280e | ||
|
|
cc6170d7fc | ||
|
|
4d300e4dec | ||
|
|
1f58b2d084 | ||
|
|
6903fa2d47 | ||
|
|
319ae90184 | ||
|
|
7b884e0075 | ||
|
|
3e7b4ae0c3 | ||
|
|
3b75d0ce23 | ||
|
|
48807de305 | ||
|
|
1d7d1a3499 | ||
|
|
969008dbb0 | ||
|
|
6976e602f6 | ||
|
|
3b087e03ea | ||
|
|
6c8b023298 | ||
|
|
8dbf59fec5 | ||
|
|
ac0f8b81ae | ||
|
|
5fc032a9d1 | ||
|
|
806e3cd075 | ||
|
|
8923325d5c | ||
|
|
a2b2c8adc9 | ||
|
|
d20238c2a7 | ||
|
|
4ce83bf57b | ||
|
|
b500953425 | ||
|
|
2f99720901 | ||
|
|
6bd9008025 | ||
|
|
c97df052a9 | ||
|
|
7d9c5e0f7d | ||
|
|
d62d5fe59a | ||
|
|
d8cec35b10 | ||
|
|
f81cff539a | ||
|
|
5fff491bbd | ||
|
|
781915f183 | ||
|
|
5b44a819d3 | ||
|
|
056f15aa53 | ||
|
|
37bda7e029 | ||
|
|
454dc9b7c2 | ||
|
|
b3d7a5c5d0 | ||
|
|
475521dd74 | ||
|
|
3c09c5f12d | ||
|
|
1a9e66915b | ||
|
|
84d11c19fd | ||
|
|
312263c7d9 | ||
|
|
3369783e0a | ||
|
|
47ff813012 | ||
|
|
3b39d4d1c1 | ||
|
|
2fab2b310b | ||
|
|
c2ac4465cd | ||
|
|
bb8059f6aa | ||
|
|
4c2cc32f2e | ||
|
|
89a3fbc0fb | ||
|
|
077353b47e | ||
|
|
46621fd2c3 | ||
|
|
d6625ac34d | ||
|
|
b46b36729f | ||
|
|
893fabd336 | ||
|
|
44ea0da2b0 | ||
|
|
4f4e1026f5 | ||
|
|
8c23f20c68 | ||
|
|
4f65227971 | ||
|
|
e4736fe469 | ||
|
|
e32925397b | ||
|
|
f5f042ffdc | ||
|
|
d445a9aafb | ||
|
|
464660651d | ||
|
|
8d9141ed9a | ||
|
|
4be37222ef | ||
|
|
b0d9f7372a | ||
|
|
704fde01e8 | ||
|
|
0c9a858f2d | ||
|
|
b8ba80bff7 | ||
|
|
8ec6ccc54d | ||
|
|
1ca9e552d9 | ||
|
|
8f0a4a25f8 | ||
|
|
071af57bcf | ||
|
|
d68865f3b1 | ||
|
|
a724952f75 | ||
|
|
a4215f469c | ||
|
|
4c1abcb0ce | ||
|
|
1dd272080d | ||
|
|
3e3a79ea13 | ||
|
|
771655e3fe | ||
|
|
60cd5bf939 | ||
|
|
91b7690428 | ||
|
|
bb01bea4e2 | ||
|
|
c145589f25 | ||
|
|
c7c82f1b44 | ||
|
|
f58ac2b46b | ||
|
|
016007bd25 | ||
|
|
4ee00b2309 | ||
|
|
fb81bc3291 | ||
|
|
c646d287f8 | ||
|
|
51d4539a79 | ||
|
|
f273c64a94 | ||
|
|
74ec95e7f6 | ||
|
|
65f340bb95 | ||
|
|
4d014d6d7e | ||
|
|
fe56461387 | ||
|
|
56efed71b5 | ||
|
|
91f18ffd47 | ||
|
|
a4c4125b11 | ||
|
|
993b412160 | ||
|
|
2c2e389b77 | ||
|
|
3291235711 | ||
|
|
461cdb593b | ||
|
|
7f00e8c033 | ||
|
|
a87089fd2d | ||
|
|
1e24c2e4f4 | ||
|
|
9e56811a37 | ||
|
|
6060e098c9 | ||
|
|
aa1e052cb4 | ||
|
|
1a652afe16 | ||
|
|
6f1e45d5ba | ||
|
|
91130ea3fc | ||
|
|
b7caa1751c | ||
|
|
4c3da0f2e1 | ||
|
|
39b4ef4b02 | ||
|
|
74be4a62c5 | ||
|
|
e11489eb5f | ||
|
|
f970610c04 | ||
|
|
68b48cc045 | ||
|
|
7596b33506 | ||
|
|
2b7aff202a | ||
|
|
e76c55a9b8 | ||
|
|
ca211065b6 | ||
|
|
c7442ef0d2 | ||
|
|
a691aa2a13 | ||
|
|
00787fe781 | ||
|
|
f5a29eab5c | ||
|
|
2b94d7fc7f | ||
|
|
51f8ce26cf | ||
|
|
092fcaffe4 | ||
|
|
7e6ede1051 | ||
|
|
ddfef21125 | ||
|
|
3af101ccc1 | ||
|
|
4f088b6f1c | ||
|
|
da9aad8876 | ||
|
|
96dc42d99c | ||
|
|
1e50f5dd28 | ||
|
|
f127799d79 | ||
|
|
6b1d73446d | ||
|
|
fd4e161497 | ||
|
|
6362a9d610 | ||
|
|
d55fc35df1 | ||
|
|
67e9d33486 | ||
|
|
219859f8bb | ||
|
|
e0493457d5 | ||
|
|
1e3a7d4fab | ||
|
|
848dec3da2 | ||
|
|
ae0880997b | ||
|
|
9eb50a9624 | ||
|
|
acecefee88 | ||
|
|
ba784bdf36 | ||
|
|
c4de28938f | ||
|
|
6c33ba14a4 | ||
|
|
7a5b571c67 | ||
|
|
599e3c7b3f | ||
|
|
86bc7795a3 | ||
|
|
a3efdb13f2 | ||
|
|
3a97280ae8 | ||
|
|
4f3f6e28d5 | ||
|
|
79ada05756 | ||
|
|
c48271958f | ||
|
|
ac66d96c5a | ||
|
|
e5165aeb27 | ||
|
|
970f4c06e1 | ||
|
|
22ef7370e7 | ||
|
|
a38be3eb48 | ||
|
|
73c028c40a | ||
|
|
783289068a | ||
|
|
bb3651abc8 | ||
|
|
f0134f363b | ||
|
|
ce88d41907 | ||
|
|
0f9539e1e3 | ||
|
|
90e07b19ab | ||
|
|
63d1d145e2 | ||
|
|
c039bb38d4 | ||
|
|
861add3d72 | ||
|
|
6886913fdf | ||
|
|
c75d3b0ede | ||
|
|
7c0eb47dfb | ||
|
|
dbcdf83ed8 | ||
|
|
d31eab94fd | ||
|
|
553f08b819 | ||
|
|
32258af87b | ||
|
|
d251d48439 | ||
|
|
f9917c8c7b | ||
|
|
5a458da42a | ||
|
|
89c6c5bb85 | ||
|
|
fdd61b83ff | ||
|
|
32559ccad1 | ||
|
|
826efc2295 | ||
|
|
88f174a014 | ||
|
|
780bdb3e80 | ||
|
|
828e1e35fd | ||
|
|
fc85dd175e | ||
|
|
89ba380b3c | ||
|
|
b57b6e341e | ||
|
|
ad0e6e971e | ||
|
|
fdba0cb03c | ||
|
|
61ee9f299d | ||
|
|
16a23ff740 | ||
|
|
1d5d21726a | ||
|
|
7b662103a0 | ||
|
|
da729e5b38 | ||
|
|
5c39a1bb26 | ||
|
|
14ae5708d6 | ||
|
|
ffaf58f0a9 | ||
|
|
4496a44f68 | ||
|
|
4f1d92b332 | ||
|
|
ab664c7e17 | ||
|
|
8ee84584a4 | ||
|
|
748d1c171d | ||
|
|
a7434fd008 | ||
|
|
d9bb8179d3 | ||
|
|
ee36057dd5 | ||
|
|
a476aabf1a | ||
|
|
f3769a97d5 | ||
|
|
ca18202eb9 | ||
|
|
5eb60a6da2 | ||
|
|
f86ea9aad5 | ||
|
|
5bcdbb1ce4 | ||
|
|
2e530f4889 | ||
|
|
7f515b0e88 | ||
|
|
b4dd3209b2 | ||
|
|
262d92834a | ||
|
|
faf663133b | ||
|
|
64a6c2c1b6 | ||
|
|
847aaffbb8 | ||
|
|
a8472e0fdb | ||
|
|
1580ec1804 | ||
|
|
8906b2fe09 | ||
|
|
e798e4fd75 | ||
|
|
4b1a7d3868 | ||
|
|
e27af97a3c | ||
|
|
542b839ec7 | ||
|
|
67cd4ee8d2 | ||
|
|
c8a8ad97f7 | ||
|
|
d87f7a1e81 | ||
|
|
adc1b50395 | ||
|
|
e86619e75d | ||
|
|
b40dc8a1da | ||
|
|
86da6feb40 | ||
|
|
fe532a98f9 | ||
|
|
39ce85cf5d | ||
|
|
72e60dea36 | ||
|
|
7c1f74713e | ||
|
|
a5ff487889 | ||
|
|
331b815300 | ||
|
|
2348f8e2a8 | ||
|
|
251b3c6406 | ||
|
|
cc21706c50 | ||
|
|
25931f12c1 | ||
|
|
91a7a4a786 | ||
|
|
d89e57ea8d | ||
|
|
5a901bb555 | ||
|
|
284f1d6beb | ||
|
|
bc6fdad786 | ||
|
|
c05db38a5e | ||
|
|
34c56766b7 | ||
|
|
5479097790 | ||
|
|
20d4e527bd | ||
|
|
a824c3f02f | ||
|
|
bc3b406bff |
3
.dockerignore
Normal file
3
.dockerignore
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.git
|
||||||
|
build/_workspace
|
||||||
|
build/_bin
|
||||||
4
.github/CONTRIBUTING.md
vendored
4
.github/CONTRIBUTING.md
vendored
@@ -9,9 +9,7 @@ and help.
|
|||||||
|
|
||||||
If you'd like to contribute to go-ethereum please fork, fix, commit and
|
If you'd like to contribute to go-ethereum please fork, fix, commit and
|
||||||
send a pull request. Commits which do not comply with the coding standards
|
send a pull request. Commits which do not comply with the coding standards
|
||||||
are ignored (use gofmt!). If you send pull requests make absolute sure that you
|
are ignored (use gofmt!).
|
||||||
commit on the `develop` branch and that you do not merge to master.
|
|
||||||
Commits that are directly based on master are simply ignored.
|
|
||||||
|
|
||||||
See [Developers' Guide](https://github.com/ethereum/go-ethereum/wiki/Developers'-Guide)
|
See [Developers' Guide](https://github.com/ethereum/go-ethereum/wiki/Developers'-Guide)
|
||||||
for more details on configuring your environment, testing, and
|
for more details on configuring your environment, testing, and
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -13,8 +13,7 @@
|
|||||||
.ethtest
|
.ethtest
|
||||||
*/**/*tx_database*
|
*/**/*tx_database*
|
||||||
*/**/*dapps*
|
*/**/*dapps*
|
||||||
Godeps/_workspace/pkg
|
build/_vendor/pkg
|
||||||
Godeps/_workspace/bin
|
|
||||||
|
|
||||||
#*
|
#*
|
||||||
.#*
|
.#*
|
||||||
|
|||||||
48
.mailmap
48
.mailmap
@@ -17,6 +17,7 @@ Taylor Gerring <taylor.gerring@gmail.com> <taylor.gerring@ethereum.org>
|
|||||||
Bas van Kervel <bas@ethdev.com>
|
Bas van Kervel <bas@ethdev.com>
|
||||||
Bas van Kervel <bas@ethdev.com> <basvankervel@ziggo.nl>
|
Bas van Kervel <bas@ethdev.com> <basvankervel@ziggo.nl>
|
||||||
Bas van Kervel <bas@ethdev.com> <basvankervel@gmail.com>
|
Bas van Kervel <bas@ethdev.com> <basvankervel@gmail.com>
|
||||||
|
Bas van Kervel <bas@ethdev.com> <bas-vk@users.noreply.github.com>
|
||||||
|
|
||||||
Sven Ehlert <sven@ethdev.com>
|
Sven Ehlert <sven@ethdev.com>
|
||||||
|
|
||||||
@@ -62,4 +63,49 @@ Joseph Chow <ethereum@outlook.com> ethers <TODO>
|
|||||||
|
|
||||||
Enrique Fynn <enriquefynn@gmail.com>
|
Enrique Fynn <enriquefynn@gmail.com>
|
||||||
|
|
||||||
Vincent G <caktux@gmail.com>
|
Vincent G <caktux@gmail.com>
|
||||||
|
|
||||||
|
RJ Catalano <rj@erisindustries.com>
|
||||||
|
|
||||||
|
Nchinda Nchinda <nchinda2@gmail.com>
|
||||||
|
|
||||||
|
Aron Fischer <github@aron.guru> <homotopycolimit@users.noreply.github.com>
|
||||||
|
|
||||||
|
Vlad Gluhovsky <gluk256@users.noreply.github.com>
|
||||||
|
|
||||||
|
Ville Sundell <github@solarius.fi>
|
||||||
|
|
||||||
|
Elliot Shepherd <elliot@identitii.com>
|
||||||
|
|
||||||
|
Yohann Léon <sybiload@gmail.com>
|
||||||
|
|
||||||
|
Gregg Dourgarian <greggd@tempworks.com>
|
||||||
|
|
||||||
|
Casey Detrio <cdetrio@gmail.com>
|
||||||
|
|
||||||
|
Jens Agerberg <github@agerberg.me>
|
||||||
|
|
||||||
|
Nick Johnson <arachnid@notdot.net>
|
||||||
|
|
||||||
|
Henning Diedrich <hd@eonblast.com>
|
||||||
|
Henning Diedrich <hd@eonblast.com> Drake Burroughs <wildfyre@hotmail.com>
|
||||||
|
|
||||||
|
Felix Lange <fjl@twurst.com>
|
||||||
|
Felix Lange <fjl@twurst.com> <fjl@users.noreply.github.com>
|
||||||
|
|
||||||
|
Максим Чусовлянов <mchusovlianov@gmail.com>
|
||||||
|
|
||||||
|
Louis Holbrook <dev@holbrook.no>
|
||||||
|
Louis Holbrook <dev@holbrook.no> <nolash@users.noreply.github.com>
|
||||||
|
|
||||||
|
Thomas Bocek <tom@tomp2p.net>
|
||||||
|
|
||||||
|
Victor Tran <vu.tran54@gmail.com>
|
||||||
|
|
||||||
|
Justin Drake <drakefjustin@gmail.com>
|
||||||
|
|
||||||
|
Frank Wang <eternnoir@gmail.com>
|
||||||
|
|
||||||
|
Gary Rong <garyrong0905@gmail.com>
|
||||||
|
|
||||||
|
Guillaume Nicolas <guin56@gmail.com>
|
||||||
|
|||||||
170
.travis.yml
170
.travis.yml
@@ -5,37 +5,175 @@ matrix:
|
|||||||
include:
|
include:
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: trusty
|
||||||
go: 1.4.2
|
sudo: required
|
||||||
- os: linux
|
go: 1.7.5
|
||||||
dist: trusty
|
script:
|
||||||
go: 1.5.4
|
- sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install fuse
|
||||||
- os: linux
|
- sudo modprobe fuse
|
||||||
dist: trusty
|
- sudo chmod 666 /dev/fuse
|
||||||
go: 1.6.2
|
- sudo chown root:$USER /etc/fuse.conf
|
||||||
- os: osx
|
- go run build/ci.go install
|
||||||
go: 1.6.2
|
- go run build/ci.go test -coverage
|
||||||
|
|
||||||
# This builder does the PPA upload (and nothing else).
|
# These are the latest Go versions.
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: trusty
|
||||||
go: 1.6.2
|
sudo: required
|
||||||
env: PPA
|
go: 1.8.1
|
||||||
|
script:
|
||||||
|
- sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install fuse
|
||||||
|
- sudo modprobe fuse
|
||||||
|
- sudo chmod 666 /dev/fuse
|
||||||
|
- sudo chown root:$USER /etc/fuse.conf
|
||||||
|
- go run build/ci.go install
|
||||||
|
- go run build/ci.go test -coverage -misspell
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
go: 1.8.1
|
||||||
|
sudo: required
|
||||||
|
script:
|
||||||
|
- brew update
|
||||||
|
- brew install caskroom/cask/brew-cask
|
||||||
|
- brew cask install osxfuse
|
||||||
|
- go run build/ci.go install
|
||||||
|
- go run build/ci.go test -coverage -misspell
|
||||||
|
|
||||||
|
# This builder does the Ubuntu PPA and Linux Azure uploads
|
||||||
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
|
sudo: required
|
||||||
|
go: 1.8.1
|
||||||
|
env:
|
||||||
|
- ubuntu-ppa
|
||||||
|
- azure-linux
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- devscripts
|
- devscripts
|
||||||
- debhelper
|
- debhelper
|
||||||
- dput
|
- dput
|
||||||
|
- gcc-multilib
|
||||||
script:
|
script:
|
||||||
- go run build/ci.go debsrc -signer "Felix Lange (Geth CI Testing Key) <fjl@twurst.com>" -upload ppa:lp-fjl/geth-ci-testing
|
# Build for the primary platforms that Trusty can manage
|
||||||
|
- go run build/ci.go debsrc -signer "Go Ethereum Linux Builder <geth-ci@ethereum.org>" -upload ppa:ethereum/ethereum
|
||||||
|
- go run build/ci.go install
|
||||||
|
- go run build/ci.go archive -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
- go run build/ci.go install -arch 386
|
||||||
|
- go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
|
||||||
|
# Switch over GCC to cross compilation (breaks 386, hence why do it here only)
|
||||||
|
- sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross
|
||||||
|
- sudo ln -s /usr/include/asm-generic /usr/include/asm
|
||||||
|
|
||||||
|
- GOARM=5 CC=arm-linux-gnueabi-gcc go run build/ci.go install -arch arm
|
||||||
|
- GOARM=5 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
- GOARM=6 CC=arm-linux-gnueabi-gcc go run build/ci.go install -arch arm
|
||||||
|
- GOARM=6 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
- GOARM=7 CC=arm-linux-gnueabihf-gcc go run build/ci.go install -arch arm
|
||||||
|
- GOARM=7 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
- CC=aarch64-linux-gnu-gcc go run build/ci.go install -arch arm64
|
||||||
|
- go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
|
||||||
|
# This builder does the Linux Azure MIPS xgo uploads
|
||||||
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
|
sudo: required
|
||||||
|
services:
|
||||||
|
- docker
|
||||||
|
go: 1.8.1
|
||||||
|
env:
|
||||||
|
- azure-linux-mips
|
||||||
|
script:
|
||||||
|
- go run build/ci.go xgo --alltools -- --targets=linux/mips --ldflags '-extldflags "-static"' -v
|
||||||
|
- for bin in build/bin/*-linux-mips; do mv -f "${bin}" "${bin/-linux-mips/}"; done
|
||||||
|
- go run build/ci.go archive -arch mips -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
|
||||||
|
- go run build/ci.go xgo --alltools -- --targets=linux/mipsle --ldflags '-extldflags "-static"' -v
|
||||||
|
- for bin in build/bin/*-linux-mipsle; do mv -f "${bin}" "${bin/-linux-mipsle/}"; done
|
||||||
|
- go run build/ci.go archive -arch mipsle -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
|
||||||
|
- go run build/ci.go xgo --alltools -- --targets=linux/mips64 --ldflags '-extldflags "-static"' -v
|
||||||
|
- for bin in build/bin/*-linux-mips64; do mv -f "${bin}" "${bin/-linux-mips64/}"; done
|
||||||
|
- go run build/ci.go archive -arch mips64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
|
||||||
|
- go run build/ci.go xgo --alltools -- --targets=linux/mips64le --ldflags '-extldflags "-static"' -v
|
||||||
|
- for bin in build/bin/*-linux-mips64le; do mv -f "${bin}" "${bin/-linux-mips64le/}"; done
|
||||||
|
- go run build/ci.go archive -arch mips64le -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
|
||||||
|
# This builder does the Android Maven and Azure uploads
|
||||||
|
- os: linux
|
||||||
|
dist: precise # Needed for the android tools
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- oracle-java8-installer
|
||||||
|
- oracle-java8-set-default
|
||||||
|
language: android
|
||||||
|
android:
|
||||||
|
components:
|
||||||
|
- platform-tools
|
||||||
|
- tools
|
||||||
|
- android-15
|
||||||
|
- android-19
|
||||||
|
- android-24
|
||||||
|
env:
|
||||||
|
- azure-android
|
||||||
|
- maven-android
|
||||||
|
before_install:
|
||||||
|
- curl https://storage.googleapis.com/golang/go1.8.1.linux-amd64.tar.gz | tar -xz
|
||||||
|
- export PATH=`pwd`/go/bin:$PATH
|
||||||
|
- export GOROOT=`pwd`/go
|
||||||
|
- export GOPATH=$HOME/go
|
||||||
|
script:
|
||||||
|
# Build the Android archive and upload it to Maven Central and Azure
|
||||||
|
- curl https://dl.google.com/android/repository/android-ndk-r13b-linux-x86_64.zip -o android-ndk-r13b.zip
|
||||||
|
- unzip -q android-ndk-r13b.zip && rm android-ndk-r13b.zip
|
||||||
|
- mv android-ndk-r13b $HOME
|
||||||
|
- export ANDROID_NDK=$HOME/android-ndk-r13b
|
||||||
|
|
||||||
|
- mkdir -p $GOPATH/src/github.com/ethereum
|
||||||
|
- ln -s `pwd` $GOPATH/src/github.com/ethereum
|
||||||
|
- go run build/ci.go aar -signer ANDROID_SIGNING_KEY -deploy https://oss.sonatype.org -upload gethstore/builds
|
||||||
|
|
||||||
|
# This builder does the OSX Azure, iOS CocoaPods and iOS Azure uploads
|
||||||
|
- os: osx
|
||||||
|
go: 1.8.1
|
||||||
|
env:
|
||||||
|
- azure-osx
|
||||||
|
- azure-ios
|
||||||
|
- cocoapods-ios
|
||||||
|
script:
|
||||||
|
- go run build/ci.go install
|
||||||
|
- go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -upload gethstore/builds
|
||||||
|
|
||||||
|
# Build the iOS framework and upload it to CocoaPods and Azure
|
||||||
|
- gem uninstall cocoapods -a
|
||||||
|
- gem install cocoapods
|
||||||
|
|
||||||
|
- mv ~/.cocoapods/repos/master ~/.cocoapods/repos/master.bak
|
||||||
|
- sed -i '.bak' 's/repo.join/!repo.join/g' $(dirname `gem which cocoapods`)/cocoapods/sources_manager.rb
|
||||||
|
- if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then git clone --depth=1 https://github.com/CocoaPods/Specs.git ~/.cocoapods/repos/master && pod setup --verbose; fi
|
||||||
|
|
||||||
|
- xctool -version
|
||||||
|
- xcrun simctl list
|
||||||
|
|
||||||
|
- go run build/ci.go xcode -signer IOS_SIGNING_KEY -deploy trunk -upload gethstore/builds
|
||||||
|
|
||||||
|
# This builder does the Azure archive purges to avoid accumulating junk
|
||||||
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
|
sudo: required
|
||||||
|
go: 1.8.1
|
||||||
|
env:
|
||||||
|
- azure-purge
|
||||||
|
script:
|
||||||
|
- go run build/ci.go purge -store gethstore/builds -days 14
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- go get golang.org/x/tools/cmd/cover
|
- go get golang.org/x/tools/cmd/cover
|
||||||
script:
|
script:
|
||||||
- go run build/ci.go install
|
- go run build/ci.go install
|
||||||
- go run build/ci.go test -coverage -vet
|
- go run build/ci.go test -coverage
|
||||||
after_success:
|
|
||||||
# - go run build/ci.go archive -type tar
|
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
webhooks:
|
webhooks:
|
||||||
|
|||||||
51
AUTHORS
51
AUTHORS
@@ -1,36 +1,85 @@
|
|||||||
# This is the official list of go-ethereum authors for copyright purposes.
|
# This is the official list of go-ethereum authors for copyright purposes.
|
||||||
|
|
||||||
|
Ales Katona <ales@coinbase.com>
|
||||||
Alex Leverington <alex@ethdev.com>
|
Alex Leverington <alex@ethdev.com>
|
||||||
Alexandre Van de Sande <alex.vandesande@ethdev.com>
|
Alexandre Van de Sande <alex.vandesande@ethdev.com>
|
||||||
|
Aron Fischer <github@aron.guru>
|
||||||
Bas van Kervel <bas@ethdev.com>
|
Bas van Kervel <bas@ethdev.com>
|
||||||
|
Benjamin Brent <benjamin@benjaminbrent.com>
|
||||||
|
Brian Schroeder <bts@gmail.com>
|
||||||
|
Casey Detrio <cdetrio@gmail.com>
|
||||||
Christoph Jentzsch <jentzsch.software@gmail.com>
|
Christoph Jentzsch <jentzsch.software@gmail.com>
|
||||||
Daniel A. Nagy <nagy.da@gmail.com>
|
Daniel A. Nagy <nagy.da@gmail.com>
|
||||||
Drake Burroughs <wildfyre@hotmail.com>
|
Diego Siqueira <DiSiqueira@users.noreply.github.com>
|
||||||
|
Elliot Shepherd <elliot@identitii.com>
|
||||||
Enrique Fynn <enriquefynn@gmail.com>
|
Enrique Fynn <enriquefynn@gmail.com>
|
||||||
Ethan Buchman <ethan@coinculture.info>
|
Ethan Buchman <ethan@coinculture.info>
|
||||||
Fabian Vogelsteller <fabian@frozeman.de>
|
Fabian Vogelsteller <fabian@frozeman.de>
|
||||||
|
Fabio Berger <fabioberger1991@gmail.com>
|
||||||
Felix Lange <fjl@twurst.com>
|
Felix Lange <fjl@twurst.com>
|
||||||
|
Frank Wang <eternnoir@gmail.com>
|
||||||
|
Gary Rong <garyrong0905@gmail.com>
|
||||||
|
Gregg Dourgarian <greggd@tempworks.com>
|
||||||
|
Guillaume Nicolas <guin56@gmail.com>
|
||||||
Gustav Simonsson <gustav.simonsson@gmail.com>
|
Gustav Simonsson <gustav.simonsson@gmail.com>
|
||||||
|
Hao Bryan Cheng <haobcheng@gmail.com>
|
||||||
|
Henning Diedrich <hd@eonblast.com>
|
||||||
Isidoro Ghezzi <isidoro.ghezzi@icloud.com>
|
Isidoro Ghezzi <isidoro.ghezzi@icloud.com>
|
||||||
Jae Kwon <jkwon.work@gmail.com>
|
Jae Kwon <jkwon.work@gmail.com>
|
||||||
|
Jamie Pitts <james.pitts@gmail.com>
|
||||||
Jason Carver <jacarver@linkedin.com>
|
Jason Carver <jacarver@linkedin.com>
|
||||||
Jeff R. Allen <jra@nella.org>
|
Jeff R. Allen <jra@nella.org>
|
||||||
Jeffrey Wilcke <jeffrey@ethereum.org>
|
Jeffrey Wilcke <jeffrey@ethereum.org>
|
||||||
|
Jens Agerberg <github@agerberg.me>
|
||||||
|
Jonathan Brown <jbrown@bluedroplet.com>
|
||||||
Joseph Chow <ethereum@outlook.com>
|
Joseph Chow <ethereum@outlook.com>
|
||||||
|
Justin Clark-Casey <justincc@justincc.org>
|
||||||
|
Justin Drake <drakefjustin@gmail.com>
|
||||||
|
Kenji Siu <kenji@isuntv.com>
|
||||||
Kobi Gurkan <kobigurk@gmail.com>
|
Kobi Gurkan <kobigurk@gmail.com>
|
||||||
Lefteris Karapetsas <lefteris@refu.co>
|
Lefteris Karapetsas <lefteris@refu.co>
|
||||||
Leif Jurvetson <leijurv@gmail.com>
|
Leif Jurvetson <leijurv@gmail.com>
|
||||||
|
Lewis Marshall <lewis@lmars.net>
|
||||||
|
Louis Holbrook <dev@holbrook.no>
|
||||||
|
Luca Zeug <luclu@users.noreply.github.com>
|
||||||
Maran Hidskes <maran.hidskes@gmail.com>
|
Maran Hidskes <maran.hidskes@gmail.com>
|
||||||
Marek Kotewicz <marek.kotewicz@gmail.com>
|
Marek Kotewicz <marek.kotewicz@gmail.com>
|
||||||
|
Martin Holst Swende <martin@swende.se>
|
||||||
|
Matthew Di Ferrante <mattdf@users.noreply.github.com>
|
||||||
Matthew Wampler-Doty <matthew.wampler.doty@gmail.com>
|
Matthew Wampler-Doty <matthew.wampler.doty@gmail.com>
|
||||||
|
Micah Zoltu <micah@zoltu.net>
|
||||||
|
Nchinda Nchinda <nchinda2@gmail.com>
|
||||||
Nick Dodson <silentcicero@outlook.com>
|
Nick Dodson <silentcicero@outlook.com>
|
||||||
|
Nick Johnson <arachnid@notdot.net>
|
||||||
|
Paulo L F Casaretto <pcasaretto@gmail.com>
|
||||||
Peter Pratscher <pratscher@gmail.com>
|
Peter Pratscher <pratscher@gmail.com>
|
||||||
Péter Szilágyi <peterke@gmail.com>
|
Péter Szilágyi <peterke@gmail.com>
|
||||||
|
RJ Catalano <rj@erisindustries.com>
|
||||||
Ramesh Nair <ram@hiddentao.com>
|
Ramesh Nair <ram@hiddentao.com>
|
||||||
Ricardo Catalinas Jiménez <r@untroubled.be>
|
Ricardo Catalinas Jiménez <r@untroubled.be>
|
||||||
Rémy Roy <remyroy@remyroy.com>
|
Rémy Roy <remyroy@remyroy.com>
|
||||||
|
Shintaro Kaneko <kaneshin0120@gmail.com>
|
||||||
|
Stein Dekker <dekker.stein@gmail.com>
|
||||||
|
Steven Roose <stevenroose@gmail.com>
|
||||||
Taylor Gerring <taylor.gerring@gmail.com>
|
Taylor Gerring <taylor.gerring@gmail.com>
|
||||||
|
Thomas Bocek <tom@tomp2p.net>
|
||||||
|
Tosh Camille <tochecamille@gmail.com>
|
||||||
|
Valentin Wüstholz <wuestholz@users.noreply.github.com>
|
||||||
|
Victor Farazdagi <simple.square@gmail.com>
|
||||||
|
Victor Tran <vu.tran54@gmail.com>
|
||||||
Viktor Trón <viktor.tron@gmail.com>
|
Viktor Trón <viktor.tron@gmail.com>
|
||||||
|
Ville Sundell <github@solarius.fi>
|
||||||
Vincent G <caktux@gmail.com>
|
Vincent G <caktux@gmail.com>
|
||||||
Vitalik Buterin <v@buterin.com>
|
Vitalik Buterin <v@buterin.com>
|
||||||
|
Vivek Anand <vivekanand1101@users.noreply.github.com>
|
||||||
|
Vlad Gluhovsky <gluk256@users.noreply.github.com>
|
||||||
|
Yohann Léon <sybiload@gmail.com>
|
||||||
|
Yoichi Hirai <i@yoichihirai.com>
|
||||||
|
Zahoor Mohamed <zahoor@zahoor.in>
|
||||||
Zsolt Felföldi <zsfelfoldi@gmail.com>
|
Zsolt Felföldi <zsfelfoldi@gmail.com>
|
||||||
|
holisticode <holistic.computing@gmail.com>
|
||||||
|
ken10100147 <sunhongping@kanjian.com>
|
||||||
|
ligi <ligi@ligi.de>
|
||||||
|
xiekeyang <xiekeyang@users.noreply.github.com>
|
||||||
|
ΞTHΞЯSPHΞЯΞ <{viktor.tron,nagydani,zsfelfoldi}@gmail.com>
|
||||||
|
Максим Чусовлянов <mchusovlianov@gmail.com>
|
||||||
|
|||||||
14
Dockerfile
Normal file
14
Dockerfile
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
FROM alpine:3.5
|
||||||
|
|
||||||
|
ADD . /go-ethereum
|
||||||
|
RUN \
|
||||||
|
apk add --update git go make gcc musl-dev linux-headers && \
|
||||||
|
(cd go-ethereum && make geth) && \
|
||||||
|
cp go-ethereum/build/bin/geth /geth && \
|
||||||
|
apk del git go make gcc musl-dev linux-headers && \
|
||||||
|
rm -rf /go-ethereum && rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
|
EXPOSE 8545
|
||||||
|
EXPOSE 30303
|
||||||
|
|
||||||
|
ENTRYPOINT ["/geth"]
|
||||||
329
Godeps/Godeps.json
generated
329
Godeps/Godeps.json
generated
@@ -1,329 +0,0 @@
|
|||||||
{
|
|
||||||
"ImportPath": "github.com/ethereum/go-ethereum",
|
|
||||||
"GoVersion": "go1.5.2",
|
|
||||||
"GodepVersion": "v74",
|
|
||||||
"Packages": [
|
|
||||||
"./..."
|
|
||||||
],
|
|
||||||
"Deps": [
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/Gustav-Simonsson/go-opencl/cl",
|
|
||||||
"Rev": "593e01cfc4f3353585015321e01951d4a907d3ef"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/cespare/cp",
|
|
||||||
"Rev": "165db2f241fd235aec29ba6d9b1ccd5f1c14637c"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/davecgh/go-spew/spew",
|
|
||||||
"Rev": "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/ethereum/ethash",
|
|
||||||
"Comment": "v23.1-247-g2e80de5",
|
|
||||||
"Rev": "2e80de5022370cfe632195b1720db52d07ff8a77"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/fatih/color",
|
|
||||||
"Comment": "v0.1-12-g9aae6aa",
|
|
||||||
"Rev": "9aae6aaa22315390f03959adca2c4d395b02fcef"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/gizak/termui",
|
|
||||||
"Rev": "08a5d3f67b7d9ec87830ea39c48e570a1f18531f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/golang/snappy",
|
|
||||||
"Rev": "799c780093d646c1b79d30894e22512c319fa137"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/golang-lru",
|
|
||||||
"Rev": "a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/hashicorp/golang-lru/simplelru",
|
|
||||||
"Rev": "a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/huin/goupnp",
|
|
||||||
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/huin/goupnp/dcps/internetgateway1",
|
|
||||||
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/huin/goupnp/dcps/internetgateway2",
|
|
||||||
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/huin/goupnp/httpu",
|
|
||||||
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/huin/goupnp/scpd",
|
|
||||||
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/huin/goupnp/soap",
|
|
||||||
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/huin/goupnp/ssdp",
|
|
||||||
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/jackpal/gateway",
|
|
||||||
"Rev": "192609c58b8985e645cbe82ddcb28a4362ca0fdc"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/jackpal/go-nat-pmp",
|
|
||||||
"Rev": "46523a463303c6ede3ddfe45bde1c7ed52ebaacd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/mattn/go-colorable",
|
|
||||||
"Rev": "9fdad7c47650b7d2e1da50644c1f4ba7f172f252"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/mattn/go-isatty",
|
|
||||||
"Rev": "56b76bdf51f7708750eac80fa38b952bb9f32639"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/mattn/go-runewidth",
|
|
||||||
"Comment": "travisish-44-ge882a96",
|
|
||||||
"Rev": "e882a96ec18dd43fa283187b66af74497c9101c0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/microsoft/go-winio",
|
|
||||||
"Comment": "v0.2.0",
|
|
||||||
"Rev": "9e2895e5f6c3f16473b91d37fae6e89990a4520c"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/nsf/termbox-go",
|
|
||||||
"Rev": "362329b0aa6447eadd52edd8d660ec1dff470295"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/pborman/uuid",
|
|
||||||
"Comment": "v1.0-6-g0f1a469",
|
|
||||||
"Rev": "0f1a46960a86dcdf5dd30d3e6568a497a997909f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/peterh/liner",
|
|
||||||
"Rev": "ad1edfd30321d8f006ccf05f1e0524adeb943060"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/rcrowley/go-metrics",
|
|
||||||
"Rev": "51425a2415d21afadfd55cd93432c0bc69e9598d"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/rjeczalik/notify",
|
|
||||||
"Rev": "f627deca7a510d96f0ef9388f2d0e8b16d21f87f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/robertkrimen/otto",
|
|
||||||
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/robertkrimen/otto/ast",
|
|
||||||
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/robertkrimen/otto/dbg",
|
|
||||||
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/robertkrimen/otto/file",
|
|
||||||
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/robertkrimen/otto/parser",
|
|
||||||
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/robertkrimen/otto/registry",
|
|
||||||
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/robertkrimen/otto/token",
|
|
||||||
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/rs/cors",
|
|
||||||
"Rev": "5950cf11d77f8a61b432a25dd4d444b4ced01379"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/rs/xhandler",
|
|
||||||
"Rev": "d9d9599b6aaf6a058cb7b1f48291ded2cbd13390"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/cache",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/comparer",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/errors",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/filter",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/iterator",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/journal",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/memdb",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/opt",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/storage",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/table",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb/util",
|
|
||||||
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/crypto/pbkdf2",
|
|
||||||
"Rev": "1f22c0103821b9390939b6776727195525381532"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/crypto/ripemd160",
|
|
||||||
"Rev": "1f22c0103821b9390939b6776727195525381532"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/crypto/scrypt",
|
|
||||||
"Rev": "1f22c0103821b9390939b6776727195525381532"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/net/context",
|
|
||||||
"Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/net/html",
|
|
||||||
"Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/net/html/atom",
|
|
||||||
"Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/net/html/charset",
|
|
||||||
"Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/net/websocket",
|
|
||||||
"Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/sys/unix",
|
|
||||||
"Rev": "50c6bc5e4292a1d4e65c6e9be5f53be28bcbe28e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding/charmap",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding/htmlindex",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding/internal",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding/internal/identifier",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding/japanese",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding/korean",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding/simplifiedchinese",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding/traditionalchinese",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/encoding/unicode",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/internal/tag",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/internal/utf8internal",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/language",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/runes",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/text/transform",
|
|
||||||
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/tools/go/ast/astutil",
|
|
||||||
"Rev": "758728c4b28cfbac299730969ef8f655c4761283"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/tools/imports",
|
|
||||||
"Rev": "758728c4b28cfbac299730969ef8f655c4761283"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "gopkg.in/check.v1",
|
|
||||||
"Rev": "4f90aeace3a26ad7021961c297b22c42160c7b25"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "gopkg.in/fatih/set.v0",
|
|
||||||
"Comment": "v0.1.0-3-g27c4092",
|
|
||||||
"Rev": "27c40922c40b43fe04554d8223a402af3ea333f3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "gopkg.in/karalabe/cookiejar.v2/collections/prque",
|
|
||||||
"Rev": "8dcd6a7f4951f6ff3ee9cbb919a06d8925822e57"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "gopkg.in/urfave/cli.v1",
|
|
||||||
"Comment": "v1.17.0",
|
|
||||||
"Rev": "01857ac33766ce0c93856370626f9799281c14f4"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
5
Godeps/Readme
generated
5
Godeps/Readme
generated
@@ -1,5 +0,0 @@
|
|||||||
This directory tree is generated automatically by godep.
|
|
||||||
|
|
||||||
Please do not edit.
|
|
||||||
|
|
||||||
See https://github.com/tools/godep for more information.
|
|
||||||
2
Godeps/_workspace/.gitignore
generated
vendored
2
Godeps/_workspace/.gitignore
generated
vendored
@@ -1,2 +0,0 @@
|
|||||||
/pkg
|
|
||||||
/bin
|
|
||||||
26
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/cl.go
generated
vendored
26
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/cl.go
generated
vendored
@@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
Package cl provides a binding to the OpenCL api. It's mostly a low-level
|
|
||||||
wrapper that avoids adding functionality while still making the interface
|
|
||||||
a little more friendly and easy to use.
|
|
||||||
|
|
||||||
Resource life-cycle management:
|
|
||||||
|
|
||||||
For any CL object that gets created (buffer, queue, kernel, etc..) you should
|
|
||||||
call object.Release() when finished with it to free the CL resources. This
|
|
||||||
explicitely calls the related clXXXRelease method for the type. However,
|
|
||||||
as a fallback there is a finalizer set for every resource item that takes
|
|
||||||
care of it (eventually) if Release isn't called. In this way you can have
|
|
||||||
better control over the life cycle of resources while having a fall back
|
|
||||||
to avoid leaks. This is similar to how file handles and such are handled
|
|
||||||
in the Go standard packages.
|
|
||||||
*/
|
|
||||||
package cl
|
|
||||||
|
|
||||||
// #include "headers/1.2/opencl.h"
|
|
||||||
// #cgo CFLAGS: -Iheaders/1.2
|
|
||||||
// #cgo darwin LDFLAGS: -framework OpenCL
|
|
||||||
// #cgo linux LDFLAGS: -lOpenCL
|
|
||||||
import "C"
|
|
||||||
import "errors"
|
|
||||||
|
|
||||||
var ErrUnsupported = errors.New("cl: unsupported")
|
|
||||||
161
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/context.go
generated
vendored
161
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/context.go
generated
vendored
@@ -1,161 +0,0 @@
|
|||||||
package cl
|
|
||||||
|
|
||||||
// #include <stdlib.h>
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"runtime"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const maxImageFormats = 256
|
|
||||||
|
|
||||||
type Context struct {
|
|
||||||
clContext C.cl_context
|
|
||||||
devices []*Device
|
|
||||||
}
|
|
||||||
|
|
||||||
type MemObject struct {
|
|
||||||
clMem C.cl_mem
|
|
||||||
size int
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseContext(c *Context) {
|
|
||||||
if c.clContext != nil {
|
|
||||||
C.clReleaseContext(c.clContext)
|
|
||||||
c.clContext = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseMemObject(b *MemObject) {
|
|
||||||
if b.clMem != nil {
|
|
||||||
C.clReleaseMemObject(b.clMem)
|
|
||||||
b.clMem = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newMemObject(mo C.cl_mem, size int) *MemObject {
|
|
||||||
memObject := &MemObject{clMem: mo, size: size}
|
|
||||||
runtime.SetFinalizer(memObject, releaseMemObject)
|
|
||||||
return memObject
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *MemObject) Release() {
|
|
||||||
releaseMemObject(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: properties
|
|
||||||
func CreateContext(devices []*Device) (*Context, error) {
|
|
||||||
deviceIds := buildDeviceIdList(devices)
|
|
||||||
var err C.cl_int
|
|
||||||
clContext := C.clCreateContext(nil, C.cl_uint(len(devices)), &deviceIds[0], nil, nil, &err)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
if clContext == nil {
|
|
||||||
return nil, ErrUnknown
|
|
||||||
}
|
|
||||||
context := &Context{clContext: clContext, devices: devices}
|
|
||||||
runtime.SetFinalizer(context, releaseContext)
|
|
||||||
return context, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) GetSupportedImageFormats(flags MemFlag, imageType MemObjectType) ([]ImageFormat, error) {
|
|
||||||
var formats [maxImageFormats]C.cl_image_format
|
|
||||||
var nFormats C.cl_uint
|
|
||||||
if err := C.clGetSupportedImageFormats(ctx.clContext, C.cl_mem_flags(flags), C.cl_mem_object_type(imageType), maxImageFormats, &formats[0], &nFormats); err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
fmts := make([]ImageFormat, nFormats)
|
|
||||||
for i, f := range formats[:nFormats] {
|
|
||||||
fmts[i] = ImageFormat{
|
|
||||||
ChannelOrder: ChannelOrder(f.image_channel_order),
|
|
||||||
ChannelDataType: ChannelDataType(f.image_channel_data_type),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmts, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) CreateCommandQueue(device *Device, properties CommandQueueProperty) (*CommandQueue, error) {
|
|
||||||
var err C.cl_int
|
|
||||||
clQueue := C.clCreateCommandQueue(ctx.clContext, device.id, C.cl_command_queue_properties(properties), &err)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
if clQueue == nil {
|
|
||||||
return nil, ErrUnknown
|
|
||||||
}
|
|
||||||
commandQueue := &CommandQueue{clQueue: clQueue, device: device}
|
|
||||||
runtime.SetFinalizer(commandQueue, releaseCommandQueue)
|
|
||||||
return commandQueue, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) CreateProgramWithSource(sources []string) (*Program, error) {
|
|
||||||
cSources := make([]*C.char, len(sources))
|
|
||||||
for i, s := range sources {
|
|
||||||
cs := C.CString(s)
|
|
||||||
cSources[i] = cs
|
|
||||||
defer C.free(unsafe.Pointer(cs))
|
|
||||||
}
|
|
||||||
var err C.cl_int
|
|
||||||
clProgram := C.clCreateProgramWithSource(ctx.clContext, C.cl_uint(len(sources)), &cSources[0], nil, &err)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
if clProgram == nil {
|
|
||||||
return nil, ErrUnknown
|
|
||||||
}
|
|
||||||
program := &Program{clProgram: clProgram, devices: ctx.devices}
|
|
||||||
runtime.SetFinalizer(program, releaseProgram)
|
|
||||||
return program, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) CreateBufferUnsafe(flags MemFlag, size int, dataPtr unsafe.Pointer) (*MemObject, error) {
|
|
||||||
var err C.cl_int
|
|
||||||
clBuffer := C.clCreateBuffer(ctx.clContext, C.cl_mem_flags(flags), C.size_t(size), dataPtr, &err)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
if clBuffer == nil {
|
|
||||||
return nil, ErrUnknown
|
|
||||||
}
|
|
||||||
return newMemObject(clBuffer, size), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) CreateEmptyBuffer(flags MemFlag, size int) (*MemObject, error) {
|
|
||||||
return ctx.CreateBufferUnsafe(flags, size, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) CreateEmptyBufferFloat32(flags MemFlag, size int) (*MemObject, error) {
|
|
||||||
return ctx.CreateBufferUnsafe(flags, 4*size, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) CreateBuffer(flags MemFlag, data []byte) (*MemObject, error) {
|
|
||||||
return ctx.CreateBufferUnsafe(flags, len(data), unsafe.Pointer(&data[0]))
|
|
||||||
}
|
|
||||||
|
|
||||||
//float64
|
|
||||||
func (ctx *Context) CreateBufferFloat32(flags MemFlag, data []float32) (*MemObject, error) {
|
|
||||||
return ctx.CreateBufferUnsafe(flags, 4*len(data), unsafe.Pointer(&data[0]))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) CreateUserEvent() (*Event, error) {
|
|
||||||
var err C.cl_int
|
|
||||||
clEvent := C.clCreateUserEvent(ctx.clContext, &err)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
return newEvent(clEvent), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) Release() {
|
|
||||||
releaseContext(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
// http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateSubBuffer.html
|
|
||||||
// func (memObject *MemObject) CreateSubBuffer(flags MemFlag, bufferCreateType BufferCreateType, )
|
|
||||||
510
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/device.go
generated
vendored
510
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/device.go
generated
vendored
@@ -1,510 +0,0 @@
|
|||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #include "cl_ext.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const maxDeviceCount = 64
|
|
||||||
|
|
||||||
type DeviceType uint
|
|
||||||
|
|
||||||
const (
|
|
||||||
DeviceTypeCPU DeviceType = C.CL_DEVICE_TYPE_CPU
|
|
||||||
DeviceTypeGPU DeviceType = C.CL_DEVICE_TYPE_GPU
|
|
||||||
DeviceTypeAccelerator DeviceType = C.CL_DEVICE_TYPE_ACCELERATOR
|
|
||||||
DeviceTypeDefault DeviceType = C.CL_DEVICE_TYPE_DEFAULT
|
|
||||||
DeviceTypeAll DeviceType = C.CL_DEVICE_TYPE_ALL
|
|
||||||
)
|
|
||||||
|
|
||||||
type FPConfig int
|
|
||||||
|
|
||||||
const (
|
|
||||||
FPConfigDenorm FPConfig = C.CL_FP_DENORM // denorms are supported
|
|
||||||
FPConfigInfNaN FPConfig = C.CL_FP_INF_NAN // INF and NaNs are supported
|
|
||||||
FPConfigRoundToNearest FPConfig = C.CL_FP_ROUND_TO_NEAREST // round to nearest even rounding mode supported
|
|
||||||
FPConfigRoundToZero FPConfig = C.CL_FP_ROUND_TO_ZERO // round to zero rounding mode supported
|
|
||||||
FPConfigRoundToInf FPConfig = C.CL_FP_ROUND_TO_INF // round to positive and negative infinity rounding modes supported
|
|
||||||
FPConfigFMA FPConfig = C.CL_FP_FMA // IEEE754-2008 fused multiply-add is supported
|
|
||||||
FPConfigSoftFloat FPConfig = C.CL_FP_SOFT_FLOAT // Basic floating-point operations (such as addition, subtraction, multiplication) are implemented in software
|
|
||||||
)
|
|
||||||
|
|
||||||
var fpConfigNameMap = map[FPConfig]string{
|
|
||||||
FPConfigDenorm: "Denorm",
|
|
||||||
FPConfigInfNaN: "InfNaN",
|
|
||||||
FPConfigRoundToNearest: "RoundToNearest",
|
|
||||||
FPConfigRoundToZero: "RoundToZero",
|
|
||||||
FPConfigRoundToInf: "RoundToInf",
|
|
||||||
FPConfigFMA: "FMA",
|
|
||||||
FPConfigSoftFloat: "SoftFloat",
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c FPConfig) String() string {
|
|
||||||
var parts []string
|
|
||||||
for bit, name := range fpConfigNameMap {
|
|
||||||
if c&bit != 0 {
|
|
||||||
parts = append(parts, name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if parts == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return strings.Join(parts, "|")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dt DeviceType) String() string {
|
|
||||||
var parts []string
|
|
||||||
if dt&DeviceTypeCPU != 0 {
|
|
||||||
parts = append(parts, "CPU")
|
|
||||||
}
|
|
||||||
if dt&DeviceTypeGPU != 0 {
|
|
||||||
parts = append(parts, "GPU")
|
|
||||||
}
|
|
||||||
if dt&DeviceTypeAccelerator != 0 {
|
|
||||||
parts = append(parts, "Accelerator")
|
|
||||||
}
|
|
||||||
if dt&DeviceTypeDefault != 0 {
|
|
||||||
parts = append(parts, "Default")
|
|
||||||
}
|
|
||||||
if parts == nil {
|
|
||||||
parts = append(parts, "None")
|
|
||||||
}
|
|
||||||
return strings.Join(parts, "|")
|
|
||||||
}
|
|
||||||
|
|
||||||
type Device struct {
|
|
||||||
id C.cl_device_id
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildDeviceIdList(devices []*Device) []C.cl_device_id {
|
|
||||||
deviceIds := make([]C.cl_device_id, len(devices))
|
|
||||||
for i, d := range devices {
|
|
||||||
deviceIds[i] = d.id
|
|
||||||
}
|
|
||||||
return deviceIds
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtain the list of devices available on a platform. 'platform' refers
|
|
||||||
// to the platform returned by GetPlatforms or can be nil. If platform
|
|
||||||
// is nil, the behavior is implementation-defined.
|
|
||||||
func GetDevices(platform *Platform, deviceType DeviceType) ([]*Device, error) {
|
|
||||||
var deviceIds [maxDeviceCount]C.cl_device_id
|
|
||||||
var numDevices C.cl_uint
|
|
||||||
var platformId C.cl_platform_id
|
|
||||||
if platform != nil {
|
|
||||||
platformId = platform.id
|
|
||||||
}
|
|
||||||
if err := C.clGetDeviceIDs(platformId, C.cl_device_type(deviceType), C.cl_uint(maxDeviceCount), &deviceIds[0], &numDevices); err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
if numDevices > maxDeviceCount {
|
|
||||||
numDevices = maxDeviceCount
|
|
||||||
}
|
|
||||||
devices := make([]*Device, numDevices)
|
|
||||||
for i := 0; i < int(numDevices); i++ {
|
|
||||||
devices[i] = &Device{id: deviceIds[i]}
|
|
||||||
}
|
|
||||||
return devices, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) nullableId() C.cl_device_id {
|
|
||||||
if d == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return d.id
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) GetInfoString(param C.cl_device_info, panicOnError bool) (string, error) {
|
|
||||||
var strC [1024]C.char
|
|
||||||
var strN C.size_t
|
|
||||||
if err := C.clGetDeviceInfo(d.id, param, 1024, unsafe.Pointer(&strC), &strN); err != C.CL_SUCCESS {
|
|
||||||
if panicOnError {
|
|
||||||
panic("Should never fail")
|
|
||||||
}
|
|
||||||
return "", toError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenCL strings are NUL-terminated, and the terminator is included in strN
|
|
||||||
// Go strings aren't NUL-terminated, so subtract 1 from the length
|
|
||||||
return C.GoStringN((*C.char)(unsafe.Pointer(&strC)), C.int(strN-1)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) getInfoUint(param C.cl_device_info, panicOnError bool) (uint, error) {
|
|
||||||
var val C.cl_uint
|
|
||||||
if err := C.clGetDeviceInfo(d.id, param, C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), nil); err != C.CL_SUCCESS {
|
|
||||||
if panicOnError {
|
|
||||||
panic("Should never fail")
|
|
||||||
}
|
|
||||||
return 0, toError(err)
|
|
||||||
}
|
|
||||||
return uint(val), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) getInfoSize(param C.cl_device_info, panicOnError bool) (int, error) {
|
|
||||||
var val C.size_t
|
|
||||||
if err := C.clGetDeviceInfo(d.id, param, C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), nil); err != C.CL_SUCCESS {
|
|
||||||
if panicOnError {
|
|
||||||
panic("Should never fail")
|
|
||||||
}
|
|
||||||
return 0, toError(err)
|
|
||||||
}
|
|
||||||
return int(val), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) getInfoUlong(param C.cl_device_info, panicOnError bool) (int64, error) {
|
|
||||||
var val C.cl_ulong
|
|
||||||
if err := C.clGetDeviceInfo(d.id, param, C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), nil); err != C.CL_SUCCESS {
|
|
||||||
if panicOnError {
|
|
||||||
panic("Should never fail")
|
|
||||||
}
|
|
||||||
return 0, toError(err)
|
|
||||||
}
|
|
||||||
return int64(val), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) getInfoBool(param C.cl_device_info, panicOnError bool) (bool, error) {
|
|
||||||
var val C.cl_bool
|
|
||||||
if err := C.clGetDeviceInfo(d.id, param, C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), nil); err != C.CL_SUCCESS {
|
|
||||||
if panicOnError {
|
|
||||||
panic("Should never fail")
|
|
||||||
}
|
|
||||||
return false, toError(err)
|
|
||||||
}
|
|
||||||
return val == C.CL_TRUE, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) Name() string {
|
|
||||||
str, _ := d.GetInfoString(C.CL_DEVICE_NAME, true)
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) Vendor() string {
|
|
||||||
str, _ := d.GetInfoString(C.CL_DEVICE_VENDOR, true)
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) Extensions() string {
|
|
||||||
str, _ := d.GetInfoString(C.CL_DEVICE_EXTENSIONS, true)
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) OpenCLCVersion() string {
|
|
||||||
str, _ := d.GetInfoString(C.CL_DEVICE_OPENCL_C_VERSION, true)
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) Profile() string {
|
|
||||||
str, _ := d.GetInfoString(C.CL_DEVICE_PROFILE, true)
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) Version() string {
|
|
||||||
str, _ := d.GetInfoString(C.CL_DEVICE_VERSION, true)
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) DriverVersion() string {
|
|
||||||
str, _ := d.GetInfoString(C.CL_DRIVER_VERSION, true)
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
// The default compute device address space size specified as an
|
|
||||||
// unsigned integer value in bits. Currently supported values are 32 or 64 bits.
|
|
||||||
func (d *Device) AddressBits() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_ADDRESS_BITS, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Size of global memory cache line in bytes.
|
|
||||||
func (d *Device) GlobalMemCachelineSize() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maximum configured clock frequency of the device in MHz.
|
|
||||||
func (d *Device) MaxClockFrequency() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_MAX_CLOCK_FREQUENCY, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The number of parallel compute units on the OpenCL device.
|
|
||||||
// A work-group executes on a single compute unit. The minimum value is 1.
|
|
||||||
func (d *Device) MaxComputeUnits() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_MAX_COMPUTE_UNITS, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max number of arguments declared with the __constant qualifier in a kernel.
|
|
||||||
// The minimum value is 8 for devices that are not of type CL_DEVICE_TYPE_CUSTOM.
|
|
||||||
func (d *Device) MaxConstantArgs() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_MAX_CONSTANT_ARGS, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max number of simultaneous image objects that can be read by a kernel.
|
|
||||||
// The minimum value is 128 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE.
|
|
||||||
func (d *Device) MaxReadImageArgs() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_MAX_READ_IMAGE_ARGS, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maximum number of samplers that can be used in a kernel. The minimum
|
|
||||||
// value is 16 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE. (Also see sampler_t.)
|
|
||||||
func (d *Device) MaxSamplers() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_MAX_SAMPLERS, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maximum dimensions that specify the global and local work-item IDs used
|
|
||||||
// by the data parallel execution model. (Refer to clEnqueueNDRangeKernel).
|
|
||||||
// The minimum value is 3 for devices that are not of type CL_DEVICE_TYPE_CUSTOM.
|
|
||||||
func (d *Device) MaxWorkItemDimensions() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max number of simultaneous image objects that can be written to by a
|
|
||||||
// kernel. The minimum value is 8 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE.
|
|
||||||
func (d *Device) MaxWriteImageArgs() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_MAX_WRITE_IMAGE_ARGS, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The minimum value is the size (in bits) of the largest OpenCL built-in
|
|
||||||
// data type supported by the device (long16 in FULL profile, long16 or
|
|
||||||
// int16 in EMBEDDED profile) for devices that are not of type CL_DEVICE_TYPE_CUSTOM.
|
|
||||||
func (d *Device) MemBaseAddrAlign() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_MEM_BASE_ADDR_ALIGN, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) NativeVectorWidthChar() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) NativeVectorWidthShort() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) NativeVectorWidthInt() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_NATIVE_VECTOR_WIDTH_INT, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) NativeVectorWidthLong() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) NativeVectorWidthFloat() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) NativeVectorWidthDouble() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) NativeVectorWidthHalf() int {
|
|
||||||
val, _ := d.getInfoUint(C.CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max height of 2D image in pixels. The minimum value is 8192
|
|
||||||
// if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE.
|
|
||||||
func (d *Device) Image2DMaxHeight() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_IMAGE2D_MAX_HEIGHT, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max width of 2D image or 1D image not created from a buffer object in
|
|
||||||
// pixels. The minimum value is 8192 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE.
|
|
||||||
func (d *Device) Image2DMaxWidth() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_IMAGE2D_MAX_WIDTH, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max depth of 3D image in pixels. The minimum value is 2048 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE.
|
|
||||||
func (d *Device) Image3DMaxDepth() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_IMAGE3D_MAX_DEPTH, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max height of 3D image in pixels. The minimum value is 2048 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE.
|
|
||||||
func (d *Device) Image3DMaxHeight() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_IMAGE3D_MAX_HEIGHT, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max width of 3D image in pixels. The minimum value is 2048 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE.
|
|
||||||
func (d *Device) Image3DMaxWidth() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_IMAGE3D_MAX_WIDTH, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max size in bytes of the arguments that can be passed to a kernel. The
|
|
||||||
// minimum value is 1024 for devices that are not of type CL_DEVICE_TYPE_CUSTOM.
|
|
||||||
// For this minimum value, only a maximum of 128 arguments can be passed to a kernel.
|
|
||||||
func (d *Device) MaxParameterSize() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_MAX_PARAMETER_SIZE, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maximum number of work-items in a work-group executing a kernel on a
|
|
||||||
// single compute unit, using the data parallel execution model. (Refer
|
|
||||||
// to clEnqueueNDRangeKernel). The minimum value is 1.
|
|
||||||
func (d *Device) MaxWorkGroupSize() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_MAX_WORK_GROUP_SIZE, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describes the resolution of device timer. This is measured in nanoseconds.
|
|
||||||
func (d *Device) ProfilingTimerResolution() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_PROFILING_TIMER_RESOLUTION, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Size of local memory arena in bytes. The minimum value is 32 KB for
|
|
||||||
// devices that are not of type CL_DEVICE_TYPE_CUSTOM.
|
|
||||||
func (d *Device) LocalMemSize() int64 {
|
|
||||||
val, _ := d.getInfoUlong(C.CL_DEVICE_LOCAL_MEM_SIZE, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max size in bytes of a constant buffer allocation. The minimum value is
|
|
||||||
// 64 KB for devices that are not of type CL_DEVICE_TYPE_CUSTOM.
|
|
||||||
func (d *Device) MaxConstantBufferSize() int64 {
|
|
||||||
val, _ := d.getInfoUlong(C.CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max size of memory object allocation in bytes. The minimum value is max
|
|
||||||
// (1/4th of CL_DEVICE_GLOBAL_MEM_SIZE, 128*1024*1024) for devices that are
|
|
||||||
// not of type CL_DEVICE_TYPE_CUSTOM.
|
|
||||||
func (d *Device) MaxMemAllocSize() int64 {
|
|
||||||
val, _ := d.getInfoUlong(C.CL_DEVICE_MAX_MEM_ALLOC_SIZE, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
// Size of global device memory in bytes.
|
|
||||||
func (d *Device) GlobalMemSize() int64 {
|
|
||||||
val, _ := d.getInfoUlong(C.CL_DEVICE_GLOBAL_MEM_SIZE, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) Available() bool {
|
|
||||||
val, _ := d.getInfoBool(C.CL_DEVICE_AVAILABLE, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) CompilerAvailable() bool {
|
|
||||||
val, _ := d.getInfoBool(C.CL_DEVICE_COMPILER_AVAILABLE, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) EndianLittle() bool {
|
|
||||||
val, _ := d.getInfoBool(C.CL_DEVICE_ENDIAN_LITTLE, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is CL_TRUE if the device implements error correction for all
|
|
||||||
// accesses to compute device memory (global and constant). Is
|
|
||||||
// CL_FALSE if the device does not implement such error correction.
|
|
||||||
func (d *Device) ErrorCorrectionSupport() bool {
|
|
||||||
val, _ := d.getInfoBool(C.CL_DEVICE_ERROR_CORRECTION_SUPPORT, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) HostUnifiedMemory() bool {
|
|
||||||
val, _ := d.getInfoBool(C.CL_DEVICE_HOST_UNIFIED_MEMORY, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) ImageSupport() bool {
|
|
||||||
val, _ := d.getInfoBool(C.CL_DEVICE_IMAGE_SUPPORT, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) Type() DeviceType {
|
|
||||||
var deviceType C.cl_device_type
|
|
||||||
if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_TYPE, C.size_t(unsafe.Sizeof(deviceType)), unsafe.Pointer(&deviceType), nil); err != C.CL_SUCCESS {
|
|
||||||
panic("Failed to get device type")
|
|
||||||
}
|
|
||||||
return DeviceType(deviceType)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describes double precision floating-point capability of the OpenCL device
|
|
||||||
func (d *Device) DoubleFPConfig() FPConfig {
|
|
||||||
var fpConfig C.cl_device_fp_config
|
|
||||||
if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_DOUBLE_FP_CONFIG, C.size_t(unsafe.Sizeof(fpConfig)), unsafe.Pointer(&fpConfig), nil); err != C.CL_SUCCESS {
|
|
||||||
panic("Failed to get double FP config")
|
|
||||||
}
|
|
||||||
return FPConfig(fpConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describes the OPTIONAL half precision floating-point capability of the OpenCL device
|
|
||||||
func (d *Device) HalfFPConfig() FPConfig {
|
|
||||||
var fpConfig C.cl_device_fp_config
|
|
||||||
err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_HALF_FP_CONFIG, C.size_t(unsafe.Sizeof(fpConfig)), unsafe.Pointer(&fpConfig), nil)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return FPConfig(0)
|
|
||||||
}
|
|
||||||
return FPConfig(fpConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type of local memory supported. This can be set to CL_LOCAL implying dedicated
|
|
||||||
// local memory storage such as SRAM, or CL_GLOBAL. For custom devices, CL_NONE
|
|
||||||
// can also be returned indicating no local memory support.
|
|
||||||
func (d *Device) LocalMemType() LocalMemType {
|
|
||||||
var memType C.cl_device_local_mem_type
|
|
||||||
if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_LOCAL_MEM_TYPE, C.size_t(unsafe.Sizeof(memType)), unsafe.Pointer(&memType), nil); err != C.CL_SUCCESS {
|
|
||||||
return LocalMemType(C.CL_NONE)
|
|
||||||
}
|
|
||||||
return LocalMemType(memType)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describes the execution capabilities of the device. The mandated minimum capability is CL_EXEC_KERNEL.
|
|
||||||
func (d *Device) ExecutionCapabilities() ExecCapability {
|
|
||||||
var execCap C.cl_device_exec_capabilities
|
|
||||||
if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_EXECUTION_CAPABILITIES, C.size_t(unsafe.Sizeof(execCap)), unsafe.Pointer(&execCap), nil); err != C.CL_SUCCESS {
|
|
||||||
panic("Failed to get execution capabilities")
|
|
||||||
}
|
|
||||||
return ExecCapability(execCap)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) GlobalMemCacheType() MemCacheType {
|
|
||||||
var memType C.cl_device_mem_cache_type
|
|
||||||
if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, C.size_t(unsafe.Sizeof(memType)), unsafe.Pointer(&memType), nil); err != C.CL_SUCCESS {
|
|
||||||
return MemCacheType(C.CL_NONE)
|
|
||||||
}
|
|
||||||
return MemCacheType(memType)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maximum number of work-items that can be specified in each dimension of the work-group to clEnqueueNDRangeKernel.
|
|
||||||
//
|
|
||||||
// Returns n size_t entries, where n is the value returned by the query for CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS.
|
|
||||||
//
|
|
||||||
// The minimum value is (1, 1, 1) for devices that are not of type CL_DEVICE_TYPE_CUSTOM.
|
|
||||||
func (d *Device) MaxWorkItemSizes() []int {
|
|
||||||
dims := d.MaxWorkItemDimensions()
|
|
||||||
sizes := make([]C.size_t, dims)
|
|
||||||
if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_MAX_WORK_ITEM_SIZES, C.size_t(int(unsafe.Sizeof(sizes[0]))*dims), unsafe.Pointer(&sizes[0]), nil); err != C.CL_SUCCESS {
|
|
||||||
panic("Failed to get max work item sizes")
|
|
||||||
}
|
|
||||||
intSizes := make([]int, dims)
|
|
||||||
for i, s := range sizes {
|
|
||||||
intSizes[i] = int(s)
|
|
||||||
}
|
|
||||||
return intSizes
|
|
||||||
}
|
|
||||||
51
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/device12.go
generated
vendored
51
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/device12.go
generated
vendored
@@ -1,51 +0,0 @@
|
|||||||
// +build cl12
|
|
||||||
|
|
||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
const FPConfigCorrectlyRoundedDivideSqrt FPConfig = C.CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
fpConfigNameMap[FPConfigCorrectlyRoundedDivideSqrt] = "CorrectlyRoundedDivideSqrt"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) BuiltInKernels() string {
|
|
||||||
str, _ := d.getInfoString(C.CL_DEVICE_BUILT_IN_KERNELS, true)
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is CL_FALSE if the implementation does not have a linker available. Is CL_TRUE if the linker is available. This can be CL_FALSE for the embedded platform profile only. This must be CL_TRUE if CL_DEVICE_COMPILER_AVAILABLE is CL_TRUE
|
|
||||||
func (d *Device) LinkerAvailable() bool {
|
|
||||||
val, _ := d.getInfoBool(C.CL_DEVICE_LINKER_AVAILABLE, true)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) ParentDevice() *Device {
|
|
||||||
var deviceId C.cl_device_id
|
|
||||||
if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_PARENT_DEVICE, C.size_t(unsafe.Sizeof(deviceId)), unsafe.Pointer(&deviceId), nil); err != C.CL_SUCCESS {
|
|
||||||
panic("ParentDevice failed")
|
|
||||||
}
|
|
||||||
if deviceId == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &Device{id: deviceId}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max number of pixels for a 1D image created from a buffer object. The minimum value is 65536 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE.
|
|
||||||
func (d *Device) ImageMaxBufferSize() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_IMAGE_MAX_BUFFER_SIZE, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max number of images in a 1D or 2D image array. The minimum value is 2048 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE
|
|
||||||
func (d *Device) ImageMaxArraySize() int {
|
|
||||||
val, _ := d.getInfoSize(C.CL_DEVICE_IMAGE_MAX_ARRAY_SIZE, true)
|
|
||||||
return int(val)
|
|
||||||
}
|
|
||||||
1210
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl.h
generated
vendored
1210
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl.h
generated
vendored
File diff suppressed because it is too large
Load Diff
315
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl_ext.h
generated
vendored
315
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl_ext.h
generated
vendored
@@ -1,315 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2008-2013 The Khronos Group Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and/or associated documentation files (the
|
|
||||||
* "Materials"), to deal in the Materials without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Materials, and to
|
|
||||||
* permit persons to whom the Materials are furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Materials.
|
|
||||||
*
|
|
||||||
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* $Revision: 11928 $ on $Date: 2010-07-13 09:04:56 -0700 (Tue, 13 Jul 2010) $ */
|
|
||||||
|
|
||||||
/* cl_ext.h contains OpenCL extensions which don't have external */
|
|
||||||
/* (OpenGL, D3D) dependencies. */
|
|
||||||
|
|
||||||
#ifndef __CL_EXT_H
|
|
||||||
#define __CL_EXT_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#include <AvailabilityMacros.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cl.h>
|
|
||||||
|
|
||||||
/* cl_khr_fp16 extension - no extension #define since it has no functions */
|
|
||||||
#define CL_DEVICE_HALF_FP_CONFIG 0x1033
|
|
||||||
|
|
||||||
/* Memory object destruction
|
|
||||||
*
|
|
||||||
* Apple extension for use to manage externally allocated buffers used with cl_mem objects with CL_MEM_USE_HOST_PTR
|
|
||||||
*
|
|
||||||
* Registers a user callback function that will be called when the memory object is deleted and its resources
|
|
||||||
* freed. Each call to clSetMemObjectCallbackFn registers the specified user callback function on a callback
|
|
||||||
* stack associated with memobj. The registered user callback functions are called in the reverse order in
|
|
||||||
* which they were registered. The user callback functions are called and then the memory object is deleted
|
|
||||||
* and its resources freed. This provides a mechanism for the application (and libraries) using memobj to be
|
|
||||||
* notified when the memory referenced by host_ptr, specified when the memory object is created and used as
|
|
||||||
* the storage bits for the memory object, can be reused or freed.
|
|
||||||
*
|
|
||||||
* The application may not call CL api's with the cl_mem object passed to the pfn_notify.
|
|
||||||
*
|
|
||||||
* Please check for the "cl_APPLE_SetMemObjectDestructor" extension using clGetDeviceInfo(CL_DEVICE_EXTENSIONS)
|
|
||||||
* before using.
|
|
||||||
*/
|
|
||||||
#define cl_APPLE_SetMemObjectDestructor 1
|
|
||||||
cl_int CL_API_ENTRY clSetMemObjectDestructorAPPLE( cl_mem /* memobj */,
|
|
||||||
void (* /*pfn_notify*/)( cl_mem /* memobj */, void* /*user_data*/),
|
|
||||||
void * /*user_data */ ) CL_EXT_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
|
|
||||||
/* Context Logging Functions
|
|
||||||
*
|
|
||||||
* The next three convenience functions are intended to be used as the pfn_notify parameter to clCreateContext().
|
|
||||||
* Please check for the "cl_APPLE_ContextLoggingFunctions" extension using clGetDeviceInfo(CL_DEVICE_EXTENSIONS)
|
|
||||||
* before using.
|
|
||||||
*
|
|
||||||
* clLogMessagesToSystemLog fowards on all log messages to the Apple System Logger
|
|
||||||
*/
|
|
||||||
#define cl_APPLE_ContextLoggingFunctions 1
|
|
||||||
extern void CL_API_ENTRY clLogMessagesToSystemLogAPPLE( const char * /* errstr */,
|
|
||||||
const void * /* private_info */,
|
|
||||||
size_t /* cb */,
|
|
||||||
void * /* user_data */ ) CL_EXT_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
/* clLogMessagesToStdout sends all log messages to the file descriptor stdout */
|
|
||||||
extern void CL_API_ENTRY clLogMessagesToStdoutAPPLE( const char * /* errstr */,
|
|
||||||
const void * /* private_info */,
|
|
||||||
size_t /* cb */,
|
|
||||||
void * /* user_data */ ) CL_EXT_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
/* clLogMessagesToStderr sends all log messages to the file descriptor stderr */
|
|
||||||
extern void CL_API_ENTRY clLogMessagesToStderrAPPLE( const char * /* errstr */,
|
|
||||||
const void * /* private_info */,
|
|
||||||
size_t /* cb */,
|
|
||||||
void * /* user_data */ ) CL_EXT_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
|
|
||||||
/************************
|
|
||||||
* cl_khr_icd extension *
|
|
||||||
************************/
|
|
||||||
#define cl_khr_icd 1
|
|
||||||
|
|
||||||
/* cl_platform_info */
|
|
||||||
#define CL_PLATFORM_ICD_SUFFIX_KHR 0x0920
|
|
||||||
|
|
||||||
/* Additional Error Codes */
|
|
||||||
#define CL_PLATFORM_NOT_FOUND_KHR -1001
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clIcdGetPlatformIDsKHR(cl_uint /* num_entries */,
|
|
||||||
cl_platform_id * /* platforms */,
|
|
||||||
cl_uint * /* num_platforms */);
|
|
||||||
|
|
||||||
typedef CL_API_ENTRY cl_int (CL_API_CALL *clIcdGetPlatformIDsKHR_fn)(
|
|
||||||
cl_uint /* num_entries */,
|
|
||||||
cl_platform_id * /* platforms */,
|
|
||||||
cl_uint * /* num_platforms */);
|
|
||||||
|
|
||||||
|
|
||||||
/* Extension: cl_khr_image2D_buffer
|
|
||||||
*
|
|
||||||
* This extension allows a 2D image to be created from a cl_mem buffer without a copy.
|
|
||||||
* The type associated with a 2D image created from a buffer in an OpenCL program is image2d_t.
|
|
||||||
* Both the sampler and sampler-less read_image built-in functions are supported for 2D images
|
|
||||||
* and 2D images created from a buffer. Similarly, the write_image built-ins are also supported
|
|
||||||
* for 2D images created from a buffer.
|
|
||||||
*
|
|
||||||
* When the 2D image from buffer is created, the client must specify the width,
|
|
||||||
* height, image format (i.e. channel order and channel data type) and optionally the row pitch
|
|
||||||
*
|
|
||||||
* The pitch specified must be a multiple of CL_DEVICE_IMAGE_PITCH_ALIGNMENT pixels.
|
|
||||||
* The base address of the buffer must be aligned to CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT pixels.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*************************************
|
|
||||||
* cl_khr_initalize_memory extension *
|
|
||||||
*************************************/
|
|
||||||
|
|
||||||
#define CL_CONTEXT_MEMORY_INITIALIZE_KHR 0x200E
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
* cl_khr_terminate_context extension *
|
|
||||||
**************************************/
|
|
||||||
|
|
||||||
#define CL_DEVICE_TERMINATE_CAPABILITY_KHR 0x200F
|
|
||||||
#define CL_CONTEXT_TERMINATE_KHR 0x2010
|
|
||||||
|
|
||||||
#define cl_khr_terminate_context 1
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL clTerminateContextKHR(cl_context /* context */) CL_EXT_SUFFIX__VERSION_1_2;
|
|
||||||
|
|
||||||
typedef CL_API_ENTRY cl_int (CL_API_CALL *clTerminateContextKHR_fn)(cl_context /* context */) CL_EXT_SUFFIX__VERSION_1_2;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Extension: cl_khr_spir
|
|
||||||
*
|
|
||||||
* This extension adds support to create an OpenCL program object from a
|
|
||||||
* Standard Portable Intermediate Representation (SPIR) instance
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define CL_DEVICE_SPIR_VERSIONS 0x40E0
|
|
||||||
#define CL_PROGRAM_BINARY_TYPE_INTERMEDIATE 0x40E1
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************
|
|
||||||
* cl_nv_device_attribute_query extension *
|
|
||||||
******************************************/
|
|
||||||
/* cl_nv_device_attribute_query extension - no extension #define since it has no functions */
|
|
||||||
#define CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV 0x4000
|
|
||||||
#define CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV 0x4001
|
|
||||||
#define CL_DEVICE_REGISTERS_PER_BLOCK_NV 0x4002
|
|
||||||
#define CL_DEVICE_WARP_SIZE_NV 0x4003
|
|
||||||
#define CL_DEVICE_GPU_OVERLAP_NV 0x4004
|
|
||||||
#define CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV 0x4005
|
|
||||||
#define CL_DEVICE_INTEGRATED_MEMORY_NV 0x4006
|
|
||||||
|
|
||||||
/*********************************
|
|
||||||
* cl_amd_device_attribute_query *
|
|
||||||
*********************************/
|
|
||||||
#define CL_DEVICE_PROFILING_TIMER_OFFSET_AMD 0x4036
|
|
||||||
|
|
||||||
/*********************************
|
|
||||||
* cl_arm_printf extension
|
|
||||||
*********************************/
|
|
||||||
#define CL_PRINTF_CALLBACK_ARM 0x40B0
|
|
||||||
#define CL_PRINTF_BUFFERSIZE_ARM 0x40B1
|
|
||||||
|
|
||||||
#ifdef CL_VERSION_1_1
|
|
||||||
/***********************************
|
|
||||||
* cl_ext_device_fission extension *
|
|
||||||
***********************************/
|
|
||||||
#define cl_ext_device_fission 1
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clReleaseDeviceEXT( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1;
|
|
||||||
|
|
||||||
typedef CL_API_ENTRY cl_int
|
|
||||||
(CL_API_CALL *clReleaseDeviceEXT_fn)( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1;
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clRetainDeviceEXT( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1;
|
|
||||||
|
|
||||||
typedef CL_API_ENTRY cl_int
|
|
||||||
(CL_API_CALL *clRetainDeviceEXT_fn)( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1;
|
|
||||||
|
|
||||||
typedef cl_ulong cl_device_partition_property_ext;
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clCreateSubDevicesEXT( cl_device_id /*in_device*/,
|
|
||||||
const cl_device_partition_property_ext * /* properties */,
|
|
||||||
cl_uint /*num_entries*/,
|
|
||||||
cl_device_id * /*out_devices*/,
|
|
||||||
cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1;
|
|
||||||
|
|
||||||
typedef CL_API_ENTRY cl_int
|
|
||||||
( CL_API_CALL * clCreateSubDevicesEXT_fn)( cl_device_id /*in_device*/,
|
|
||||||
const cl_device_partition_property_ext * /* properties */,
|
|
||||||
cl_uint /*num_entries*/,
|
|
||||||
cl_device_id * /*out_devices*/,
|
|
||||||
cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1;
|
|
||||||
|
|
||||||
/* cl_device_partition_property_ext */
|
|
||||||
#define CL_DEVICE_PARTITION_EQUALLY_EXT 0x4050
|
|
||||||
#define CL_DEVICE_PARTITION_BY_COUNTS_EXT 0x4051
|
|
||||||
#define CL_DEVICE_PARTITION_BY_NAMES_EXT 0x4052
|
|
||||||
#define CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN_EXT 0x4053
|
|
||||||
|
|
||||||
/* clDeviceGetInfo selectors */
|
|
||||||
#define CL_DEVICE_PARENT_DEVICE_EXT 0x4054
|
|
||||||
#define CL_DEVICE_PARTITION_TYPES_EXT 0x4055
|
|
||||||
#define CL_DEVICE_AFFINITY_DOMAINS_EXT 0x4056
|
|
||||||
#define CL_DEVICE_REFERENCE_COUNT_EXT 0x4057
|
|
||||||
#define CL_DEVICE_PARTITION_STYLE_EXT 0x4058
|
|
||||||
|
|
||||||
/* error codes */
|
|
||||||
#define CL_DEVICE_PARTITION_FAILED_EXT -1057
|
|
||||||
#define CL_INVALID_PARTITION_COUNT_EXT -1058
|
|
||||||
#define CL_INVALID_PARTITION_NAME_EXT -1059
|
|
||||||
|
|
||||||
/* CL_AFFINITY_DOMAINs */
|
|
||||||
#define CL_AFFINITY_DOMAIN_L1_CACHE_EXT 0x1
|
|
||||||
#define CL_AFFINITY_DOMAIN_L2_CACHE_EXT 0x2
|
|
||||||
#define CL_AFFINITY_DOMAIN_L3_CACHE_EXT 0x3
|
|
||||||
#define CL_AFFINITY_DOMAIN_L4_CACHE_EXT 0x4
|
|
||||||
#define CL_AFFINITY_DOMAIN_NUMA_EXT 0x10
|
|
||||||
#define CL_AFFINITY_DOMAIN_NEXT_FISSIONABLE_EXT 0x100
|
|
||||||
|
|
||||||
/* cl_device_partition_property_ext list terminators */
|
|
||||||
#define CL_PROPERTIES_LIST_END_EXT ((cl_device_partition_property_ext) 0)
|
|
||||||
#define CL_PARTITION_BY_COUNTS_LIST_END_EXT ((cl_device_partition_property_ext) 0)
|
|
||||||
#define CL_PARTITION_BY_NAMES_LIST_END_EXT ((cl_device_partition_property_ext) 0 - 1)
|
|
||||||
|
|
||||||
/*********************************
|
|
||||||
* cl_qcom_ext_host_ptr extension
|
|
||||||
*********************************/
|
|
||||||
|
|
||||||
#define CL_MEM_EXT_HOST_PTR_QCOM (1 << 29)
|
|
||||||
|
|
||||||
#define CL_DEVICE_EXT_MEM_PADDING_IN_BYTES_QCOM 0x40A0
|
|
||||||
#define CL_DEVICE_PAGE_SIZE_QCOM 0x40A1
|
|
||||||
#define CL_IMAGE_ROW_ALIGNMENT_QCOM 0x40A2
|
|
||||||
#define CL_IMAGE_SLICE_ALIGNMENT_QCOM 0x40A3
|
|
||||||
#define CL_MEM_HOST_UNCACHED_QCOM 0x40A4
|
|
||||||
#define CL_MEM_HOST_WRITEBACK_QCOM 0x40A5
|
|
||||||
#define CL_MEM_HOST_WRITETHROUGH_QCOM 0x40A6
|
|
||||||
#define CL_MEM_HOST_WRITE_COMBINING_QCOM 0x40A7
|
|
||||||
|
|
||||||
typedef cl_uint cl_image_pitch_info_qcom;
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clGetDeviceImageInfoQCOM(cl_device_id device,
|
|
||||||
size_t image_width,
|
|
||||||
size_t image_height,
|
|
||||||
const cl_image_format *image_format,
|
|
||||||
cl_image_pitch_info_qcom param_name,
|
|
||||||
size_t param_value_size,
|
|
||||||
void *param_value,
|
|
||||||
size_t *param_value_size_ret);
|
|
||||||
|
|
||||||
typedef struct _cl_mem_ext_host_ptr
|
|
||||||
{
|
|
||||||
/* Type of external memory allocation. */
|
|
||||||
/* Legal values will be defined in layered extensions. */
|
|
||||||
cl_uint allocation_type;
|
|
||||||
|
|
||||||
/* Host cache policy for this external memory allocation. */
|
|
||||||
cl_uint host_cache_policy;
|
|
||||||
|
|
||||||
} cl_mem_ext_host_ptr;
|
|
||||||
|
|
||||||
/*********************************
|
|
||||||
* cl_qcom_ion_host_ptr extension
|
|
||||||
*********************************/
|
|
||||||
|
|
||||||
#define CL_MEM_ION_HOST_PTR_QCOM 0x40A8
|
|
||||||
|
|
||||||
typedef struct _cl_mem_ion_host_ptr
|
|
||||||
{
|
|
||||||
/* Type of external memory allocation. */
|
|
||||||
/* Must be CL_MEM_ION_HOST_PTR_QCOM for ION allocations. */
|
|
||||||
cl_mem_ext_host_ptr ext_host_ptr;
|
|
||||||
|
|
||||||
/* ION file descriptor */
|
|
||||||
int ion_filedesc;
|
|
||||||
|
|
||||||
/* Host pointer to the ION allocated memory */
|
|
||||||
void* ion_hostptr;
|
|
||||||
|
|
||||||
} cl_mem_ion_host_ptr;
|
|
||||||
|
|
||||||
#endif /* CL_VERSION_1_1 */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __CL_EXT_H */
|
|
||||||
158
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl_gl.h
generated
vendored
158
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl_gl.h
generated
vendored
@@ -1,158 +0,0 @@
|
|||||||
/**********************************************************************************
|
|
||||||
* Copyright (c) 2008 - 2012 The Khronos Group Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and/or associated documentation files (the
|
|
||||||
* "Materials"), to deal in the Materials without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Materials, and to
|
|
||||||
* permit persons to whom the Materials are furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Materials.
|
|
||||||
*
|
|
||||||
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
||||||
**********************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __OPENCL_CL_GL_H
|
|
||||||
#define __OPENCL_CL_GL_H
|
|
||||||
|
|
||||||
#include <cl.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef cl_uint cl_gl_object_type;
|
|
||||||
typedef cl_uint cl_gl_texture_info;
|
|
||||||
typedef cl_uint cl_gl_platform_info;
|
|
||||||
typedef struct __GLsync *cl_GLsync;
|
|
||||||
|
|
||||||
/* cl_gl_object_type = 0x2000 - 0x200F enum values are currently taken */
|
|
||||||
#define CL_GL_OBJECT_BUFFER 0x2000
|
|
||||||
#define CL_GL_OBJECT_TEXTURE2D 0x2001
|
|
||||||
#define CL_GL_OBJECT_TEXTURE3D 0x2002
|
|
||||||
#define CL_GL_OBJECT_RENDERBUFFER 0x2003
|
|
||||||
#define CL_GL_OBJECT_TEXTURE2D_ARRAY 0x200E
|
|
||||||
#define CL_GL_OBJECT_TEXTURE1D 0x200F
|
|
||||||
#define CL_GL_OBJECT_TEXTURE1D_ARRAY 0x2010
|
|
||||||
#define CL_GL_OBJECT_TEXTURE_BUFFER 0x2011
|
|
||||||
|
|
||||||
/* cl_gl_texture_info */
|
|
||||||
#define CL_GL_TEXTURE_TARGET 0x2004
|
|
||||||
#define CL_GL_MIPMAP_LEVEL 0x2005
|
|
||||||
#define CL_GL_NUM_SAMPLES 0x2012
|
|
||||||
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_mem CL_API_CALL
|
|
||||||
clCreateFromGLBuffer(cl_context /* context */,
|
|
||||||
cl_mem_flags /* flags */,
|
|
||||||
cl_GLuint /* bufobj */,
|
|
||||||
int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_mem CL_API_CALL
|
|
||||||
clCreateFromGLTexture(cl_context /* context */,
|
|
||||||
cl_mem_flags /* flags */,
|
|
||||||
cl_GLenum /* target */,
|
|
||||||
cl_GLint /* miplevel */,
|
|
||||||
cl_GLuint /* texture */,
|
|
||||||
cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_2;
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_mem CL_API_CALL
|
|
||||||
clCreateFromGLRenderbuffer(cl_context /* context */,
|
|
||||||
cl_mem_flags /* flags */,
|
|
||||||
cl_GLuint /* renderbuffer */,
|
|
||||||
cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clGetGLObjectInfo(cl_mem /* memobj */,
|
|
||||||
cl_gl_object_type * /* gl_object_type */,
|
|
||||||
cl_GLuint * /* gl_object_name */) CL_API_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clGetGLTextureInfo(cl_mem /* memobj */,
|
|
||||||
cl_gl_texture_info /* param_name */,
|
|
||||||
size_t /* param_value_size */,
|
|
||||||
void * /* param_value */,
|
|
||||||
size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clEnqueueAcquireGLObjects(cl_command_queue /* command_queue */,
|
|
||||||
cl_uint /* num_objects */,
|
|
||||||
const cl_mem * /* mem_objects */,
|
|
||||||
cl_uint /* num_events_in_wait_list */,
|
|
||||||
const cl_event * /* event_wait_list */,
|
|
||||||
cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clEnqueueReleaseGLObjects(cl_command_queue /* command_queue */,
|
|
||||||
cl_uint /* num_objects */,
|
|
||||||
const cl_mem * /* mem_objects */,
|
|
||||||
cl_uint /* num_events_in_wait_list */,
|
|
||||||
const cl_event * /* event_wait_list */,
|
|
||||||
cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
|
|
||||||
/* Deprecated OpenCL 1.1 APIs */
|
|
||||||
extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL
|
|
||||||
clCreateFromGLTexture2D(cl_context /* context */,
|
|
||||||
cl_mem_flags /* flags */,
|
|
||||||
cl_GLenum /* target */,
|
|
||||||
cl_GLint /* miplevel */,
|
|
||||||
cl_GLuint /* texture */,
|
|
||||||
cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
|
|
||||||
|
|
||||||
extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL
|
|
||||||
clCreateFromGLTexture3D(cl_context /* context */,
|
|
||||||
cl_mem_flags /* flags */,
|
|
||||||
cl_GLenum /* target */,
|
|
||||||
cl_GLint /* miplevel */,
|
|
||||||
cl_GLuint /* texture */,
|
|
||||||
cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
|
|
||||||
|
|
||||||
/* cl_khr_gl_sharing extension */
|
|
||||||
|
|
||||||
#define cl_khr_gl_sharing 1
|
|
||||||
|
|
||||||
typedef cl_uint cl_gl_context_info;
|
|
||||||
|
|
||||||
/* Additional Error Codes */
|
|
||||||
#define CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR -1000
|
|
||||||
|
|
||||||
/* cl_gl_context_info */
|
|
||||||
#define CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR 0x2006
|
|
||||||
#define CL_DEVICES_FOR_GL_CONTEXT_KHR 0x2007
|
|
||||||
|
|
||||||
/* Additional cl_context_properties */
|
|
||||||
#define CL_GL_CONTEXT_KHR 0x2008
|
|
||||||
#define CL_EGL_DISPLAY_KHR 0x2009
|
|
||||||
#define CL_GLX_DISPLAY_KHR 0x200A
|
|
||||||
#define CL_WGL_HDC_KHR 0x200B
|
|
||||||
#define CL_CGL_SHAREGROUP_KHR 0x200C
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_int CL_API_CALL
|
|
||||||
clGetGLContextInfoKHR(const cl_context_properties * /* properties */,
|
|
||||||
cl_gl_context_info /* param_name */,
|
|
||||||
size_t /* param_value_size */,
|
|
||||||
void * /* param_value */,
|
|
||||||
size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
|
|
||||||
|
|
||||||
typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetGLContextInfoKHR_fn)(
|
|
||||||
const cl_context_properties * properties,
|
|
||||||
cl_gl_context_info param_name,
|
|
||||||
size_t param_value_size,
|
|
||||||
void * param_value,
|
|
||||||
size_t * param_value_size_ret);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __OPENCL_CL_GL_H */
|
|
||||||
65
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl_gl_ext.h
generated
vendored
65
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl_gl_ext.h
generated
vendored
@@ -1,65 +0,0 @@
|
|||||||
/**********************************************************************************
|
|
||||||
* Copyright (c) 2008-2012 The Khronos Group Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and/or associated documentation files (the
|
|
||||||
* "Materials"), to deal in the Materials without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Materials, and to
|
|
||||||
* permit persons to whom the Materials are furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Materials.
|
|
||||||
*
|
|
||||||
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
||||||
**********************************************************************************/
|
|
||||||
|
|
||||||
/* $Revision: 11708 $ on $Date: 2010-06-13 23:36:24 -0700 (Sun, 13 Jun 2010) $ */
|
|
||||||
|
|
||||||
/* cl_gl_ext.h contains vendor (non-KHR) OpenCL extensions which have */
|
|
||||||
/* OpenGL dependencies. */
|
|
||||||
|
|
||||||
#ifndef __OPENCL_CL_GL_EXT_H
|
|
||||||
#define __OPENCL_CL_GL_EXT_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cl_gl.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For each extension, follow this template
|
|
||||||
* cl_VEN_extname extension */
|
|
||||||
/* #define cl_VEN_extname 1
|
|
||||||
* ... define new types, if any
|
|
||||||
* ... define new tokens, if any
|
|
||||||
* ... define new APIs, if any
|
|
||||||
*
|
|
||||||
* If you need GLtypes here, mirror them with a cl_GLtype, rather than including a GL header
|
|
||||||
* This allows us to avoid having to decide whether to include GL headers or GLES here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* cl_khr_gl_event extension
|
|
||||||
* See section 9.9 in the OpenCL 1.1 spec for more information
|
|
||||||
*/
|
|
||||||
#define CL_COMMAND_GL_FENCE_SYNC_OBJECT_KHR 0x200D
|
|
||||||
|
|
||||||
extern CL_API_ENTRY cl_event CL_API_CALL
|
|
||||||
clCreateEventFromGLsyncKHR(cl_context /* context */,
|
|
||||||
cl_GLsync /* cl_GLsync */,
|
|
||||||
cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __OPENCL_CL_GL_EXT_H */
|
|
||||||
1278
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl_platform.h
generated
vendored
1278
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/cl_platform.h
generated
vendored
File diff suppressed because it is too large
Load Diff
43
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/opencl.h
generated
vendored
43
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/headers/1.2/opencl.h
generated
vendored
@@ -1,43 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2008-2012 The Khronos Group Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and/or associated documentation files (the
|
|
||||||
* "Materials"), to deal in the Materials without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Materials, and to
|
|
||||||
* permit persons to whom the Materials are furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Materials.
|
|
||||||
*
|
|
||||||
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* $Revision: 11708 $ on $Date: 2010-06-13 23:36:24 -0700 (Sun, 13 Jun 2010) $ */
|
|
||||||
|
|
||||||
#ifndef __OPENCL_H
|
|
||||||
#define __OPENCL_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cl.h>
|
|
||||||
#include <cl_gl.h>
|
|
||||||
#include <cl_gl_ext.h>
|
|
||||||
#include <cl_ext.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __OPENCL_H */
|
|
||||||
|
|
||||||
83
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/image.go
generated
vendored
83
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/image.go
generated
vendored
@@ -1,83 +0,0 @@
|
|||||||
// +build cl12
|
|
||||||
|
|
||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
import (
|
|
||||||
"image"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (ctx *Context) CreateImage(flags MemFlag, imageFormat ImageFormat, imageDesc ImageDescription, data []byte) (*MemObject, error) {
|
|
||||||
format := imageFormat.toCl()
|
|
||||||
desc := imageDesc.toCl()
|
|
||||||
var dataPtr unsafe.Pointer
|
|
||||||
if data != nil {
|
|
||||||
dataPtr = unsafe.Pointer(&data[0])
|
|
||||||
}
|
|
||||||
var err C.cl_int
|
|
||||||
clBuffer := C.clCreateImage(ctx.clContext, C.cl_mem_flags(flags), &format, &desc, dataPtr, &err)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
if clBuffer == nil {
|
|
||||||
return nil, ErrUnknown
|
|
||||||
}
|
|
||||||
return newMemObject(clBuffer, len(data)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) CreateImageSimple(flags MemFlag, width, height int, channelOrder ChannelOrder, channelDataType ChannelDataType, data []byte) (*MemObject, error) {
|
|
||||||
format := ImageFormat{channelOrder, channelDataType}
|
|
||||||
desc := ImageDescription{
|
|
||||||
Type: MemObjectTypeImage2D,
|
|
||||||
Width: width,
|
|
||||||
Height: height,
|
|
||||||
}
|
|
||||||
return ctx.CreateImage(flags, format, desc, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) CreateImageFromImage(flags MemFlag, img image.Image) (*MemObject, error) {
|
|
||||||
switch m := img.(type) {
|
|
||||||
case *image.Gray:
|
|
||||||
format := ImageFormat{ChannelOrderIntensity, ChannelDataTypeUNormInt8}
|
|
||||||
desc := ImageDescription{
|
|
||||||
Type: MemObjectTypeImage2D,
|
|
||||||
Width: m.Bounds().Dx(),
|
|
||||||
Height: m.Bounds().Dy(),
|
|
||||||
RowPitch: m.Stride,
|
|
||||||
}
|
|
||||||
return ctx.CreateImage(flags, format, desc, m.Pix)
|
|
||||||
case *image.RGBA:
|
|
||||||
format := ImageFormat{ChannelOrderRGBA, ChannelDataTypeUNormInt8}
|
|
||||||
desc := ImageDescription{
|
|
||||||
Type: MemObjectTypeImage2D,
|
|
||||||
Width: m.Bounds().Dx(),
|
|
||||||
Height: m.Bounds().Dy(),
|
|
||||||
RowPitch: m.Stride,
|
|
||||||
}
|
|
||||||
return ctx.CreateImage(flags, format, desc, m.Pix)
|
|
||||||
}
|
|
||||||
|
|
||||||
b := img.Bounds()
|
|
||||||
w := b.Dx()
|
|
||||||
h := b.Dy()
|
|
||||||
data := make([]byte, w*h*4)
|
|
||||||
dataOffset := 0
|
|
||||||
for y := 0; y < h; y++ {
|
|
||||||
for x := 0; x < w; x++ {
|
|
||||||
c := img.At(x+b.Min.X, y+b.Min.Y)
|
|
||||||
r, g, b, a := c.RGBA()
|
|
||||||
data[dataOffset] = uint8(r >> 8)
|
|
||||||
data[dataOffset+1] = uint8(g >> 8)
|
|
||||||
data[dataOffset+2] = uint8(b >> 8)
|
|
||||||
data[dataOffset+3] = uint8(a >> 8)
|
|
||||||
dataOffset += 4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ctx.CreateImageSimple(flags, w, h, ChannelOrderRGBA, ChannelDataTypeUNormInt8, data)
|
|
||||||
}
|
|
||||||
127
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/kernel.go
generated
vendored
127
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/kernel.go
generated
vendored
@@ -1,127 +0,0 @@
|
|||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ErrUnsupportedArgumentType struct {
|
|
||||||
Index int
|
|
||||||
Value interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e ErrUnsupportedArgumentType) Error() string {
|
|
||||||
return fmt.Sprintf("cl: unsupported argument type for index %d: %+v", e.Index, e.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Kernel struct {
|
|
||||||
clKernel C.cl_kernel
|
|
||||||
name string
|
|
||||||
}
|
|
||||||
|
|
||||||
type LocalBuffer int
|
|
||||||
|
|
||||||
func releaseKernel(k *Kernel) {
|
|
||||||
if k.clKernel != nil {
|
|
||||||
C.clReleaseKernel(k.clKernel)
|
|
||||||
k.clKernel = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) Release() {
|
|
||||||
releaseKernel(k)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgs(args ...interface{}) error {
|
|
||||||
for index, arg := range args {
|
|
||||||
if err := k.SetArg(index, arg); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArg(index int, arg interface{}) error {
|
|
||||||
switch val := arg.(type) {
|
|
||||||
case uint8:
|
|
||||||
return k.SetArgUint8(index, val)
|
|
||||||
case int8:
|
|
||||||
return k.SetArgInt8(index, val)
|
|
||||||
case uint32:
|
|
||||||
return k.SetArgUint32(index, val)
|
|
||||||
case uint64:
|
|
||||||
return k.SetArgUint64(index, val)
|
|
||||||
case int32:
|
|
||||||
return k.SetArgInt32(index, val)
|
|
||||||
case float32:
|
|
||||||
return k.SetArgFloat32(index, val)
|
|
||||||
case *MemObject:
|
|
||||||
return k.SetArgBuffer(index, val)
|
|
||||||
case LocalBuffer:
|
|
||||||
return k.SetArgLocal(index, int(val))
|
|
||||||
default:
|
|
||||||
return ErrUnsupportedArgumentType{Index: index, Value: arg}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgBuffer(index int, buffer *MemObject) error {
|
|
||||||
return k.SetArgUnsafe(index, int(unsafe.Sizeof(buffer.clMem)), unsafe.Pointer(&buffer.clMem))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgFloat32(index int, val float32) error {
|
|
||||||
return k.SetArgUnsafe(index, int(unsafe.Sizeof(val)), unsafe.Pointer(&val))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgInt8(index int, val int8) error {
|
|
||||||
return k.SetArgUnsafe(index, int(unsafe.Sizeof(val)), unsafe.Pointer(&val))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgUint8(index int, val uint8) error {
|
|
||||||
return k.SetArgUnsafe(index, int(unsafe.Sizeof(val)), unsafe.Pointer(&val))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgInt32(index int, val int32) error {
|
|
||||||
return k.SetArgUnsafe(index, int(unsafe.Sizeof(val)), unsafe.Pointer(&val))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgUint32(index int, val uint32) error {
|
|
||||||
return k.SetArgUnsafe(index, int(unsafe.Sizeof(val)), unsafe.Pointer(&val))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgUint64(index int, val uint64) error {
|
|
||||||
return k.SetArgUnsafe(index, int(unsafe.Sizeof(val)), unsafe.Pointer(&val))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgLocal(index int, size int) error {
|
|
||||||
return k.SetArgUnsafe(index, size, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) SetArgUnsafe(index, argSize int, arg unsafe.Pointer) error {
|
|
||||||
//fmt.Println("FUNKY: ", index, argSize)
|
|
||||||
return toError(C.clSetKernelArg(k.clKernel, C.cl_uint(index), C.size_t(argSize), arg))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) PreferredWorkGroupSizeMultiple(device *Device) (int, error) {
|
|
||||||
var size C.size_t
|
|
||||||
err := C.clGetKernelWorkGroupInfo(k.clKernel, device.nullableId(), C.CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, C.size_t(unsafe.Sizeof(size)), unsafe.Pointer(&size), nil)
|
|
||||||
return int(size), toError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) WorkGroupSize(device *Device) (int, error) {
|
|
||||||
var size C.size_t
|
|
||||||
err := C.clGetKernelWorkGroupInfo(k.clKernel, device.nullableId(), C.CL_KERNEL_WORK_GROUP_SIZE, C.size_t(unsafe.Sizeof(size)), unsafe.Pointer(&size), nil)
|
|
||||||
return int(size), toError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *Kernel) NumArgs() (int, error) {
|
|
||||||
var num C.cl_uint
|
|
||||||
err := C.clGetKernelInfo(k.clKernel, C.CL_KERNEL_NUM_ARGS, C.size_t(unsafe.Sizeof(num)), unsafe.Pointer(&num), nil)
|
|
||||||
return int(num), toError(err)
|
|
||||||
}
|
|
||||||
7
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/kernel10.go
generated
vendored
7
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/kernel10.go
generated
vendored
@@ -1,7 +0,0 @@
|
|||||||
// +build !cl12
|
|
||||||
|
|
||||||
package cl
|
|
||||||
|
|
||||||
func (k *Kernel) ArgName(index int) (string, error) {
|
|
||||||
return "", ErrUnsupported
|
|
||||||
}
|
|
||||||
20
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/kernel12.go
generated
vendored
20
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/kernel12.go
generated
vendored
@@ -1,20 +0,0 @@
|
|||||||
// +build cl12
|
|
||||||
|
|
||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
func (k *Kernel) ArgName(index int) (string, error) {
|
|
||||||
var strC [1024]byte
|
|
||||||
var strN C.size_t
|
|
||||||
if err := C.clGetKernelArgInfo(k.clKernel, C.cl_uint(index), C.CL_KERNEL_ARG_NAME, 1024, unsafe.Pointer(&strC[0]), &strN); err != C.CL_SUCCESS {
|
|
||||||
return "", toError(err)
|
|
||||||
}
|
|
||||||
return string(strC[:strN]), nil
|
|
||||||
}
|
|
||||||
83
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/platform.go
generated
vendored
83
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/platform.go
generated
vendored
@@ -1,83 +0,0 @@
|
|||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
const maxPlatforms = 32
|
|
||||||
|
|
||||||
type Platform struct {
|
|
||||||
id C.cl_platform_id
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtain the list of platforms available.
|
|
||||||
func GetPlatforms() ([]*Platform, error) {
|
|
||||||
var platformIds [maxPlatforms]C.cl_platform_id
|
|
||||||
var nPlatforms C.cl_uint
|
|
||||||
if err := C.clGetPlatformIDs(C.cl_uint(maxPlatforms), &platformIds[0], &nPlatforms); err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
platforms := make([]*Platform, nPlatforms)
|
|
||||||
for i := 0; i < int(nPlatforms); i++ {
|
|
||||||
platforms[i] = &Platform{id: platformIds[i]}
|
|
||||||
}
|
|
||||||
return platforms, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Platform) GetDevices(deviceType DeviceType) ([]*Device, error) {
|
|
||||||
return GetDevices(p, deviceType)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Platform) getInfoString(param C.cl_platform_info) (string, error) {
|
|
||||||
var strC [2048]byte
|
|
||||||
var strN C.size_t
|
|
||||||
if err := C.clGetPlatformInfo(p.id, param, 2048, unsafe.Pointer(&strC[0]), &strN); err != C.CL_SUCCESS {
|
|
||||||
return "", toError(err)
|
|
||||||
}
|
|
||||||
return string(strC[:(strN - 1)]), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Platform) Name() string {
|
|
||||||
if str, err := p.getInfoString(C.CL_PLATFORM_NAME); err != nil {
|
|
||||||
panic("Platform.Name() should never fail")
|
|
||||||
} else {
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Platform) Vendor() string {
|
|
||||||
if str, err := p.getInfoString(C.CL_PLATFORM_VENDOR); err != nil {
|
|
||||||
panic("Platform.Vendor() should never fail")
|
|
||||||
} else {
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Platform) Profile() string {
|
|
||||||
if str, err := p.getInfoString(C.CL_PLATFORM_PROFILE); err != nil {
|
|
||||||
panic("Platform.Profile() should never fail")
|
|
||||||
} else {
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Platform) Version() string {
|
|
||||||
if str, err := p.getInfoString(C.CL_PLATFORM_VERSION); err != nil {
|
|
||||||
panic("Platform.Version() should never fail")
|
|
||||||
} else {
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Platform) Extensions() string {
|
|
||||||
if str, err := p.getInfoString(C.CL_PLATFORM_EXTENSIONS); err != nil {
|
|
||||||
panic("Platform.Extensions() should never fail")
|
|
||||||
} else {
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
}
|
|
||||||
105
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/program.go
generated
vendored
105
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/program.go
generated
vendored
@@ -1,105 +0,0 @@
|
|||||||
package cl
|
|
||||||
|
|
||||||
// #include <stdlib.h>
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"runtime"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BuildError struct {
|
|
||||||
Message string
|
|
||||||
Device *Device
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e BuildError) Error() string {
|
|
||||||
if e.Device != nil {
|
|
||||||
return fmt.Sprintf("cl: build error on %q: %s", e.Device.Name(), e.Message)
|
|
||||||
} else {
|
|
||||||
return fmt.Sprintf("cl: build error: %s", e.Message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Program struct {
|
|
||||||
clProgram C.cl_program
|
|
||||||
devices []*Device
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseProgram(p *Program) {
|
|
||||||
if p.clProgram != nil {
|
|
||||||
C.clReleaseProgram(p.clProgram)
|
|
||||||
p.clProgram = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Program) Release() {
|
|
||||||
releaseProgram(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Program) BuildProgram(devices []*Device, options string) error {
|
|
||||||
var cOptions *C.char
|
|
||||||
if options != "" {
|
|
||||||
cOptions = C.CString(options)
|
|
||||||
defer C.free(unsafe.Pointer(cOptions))
|
|
||||||
}
|
|
||||||
var deviceList []C.cl_device_id
|
|
||||||
var deviceListPtr *C.cl_device_id
|
|
||||||
numDevices := C.cl_uint(len(devices))
|
|
||||||
if devices != nil && len(devices) > 0 {
|
|
||||||
deviceList = buildDeviceIdList(devices)
|
|
||||||
deviceListPtr = &deviceList[0]
|
|
||||||
}
|
|
||||||
if err := C.clBuildProgram(p.clProgram, numDevices, deviceListPtr, cOptions, nil, nil); err != C.CL_SUCCESS {
|
|
||||||
buffer := make([]byte, 4096)
|
|
||||||
var bLen C.size_t
|
|
||||||
var err C.cl_int
|
|
||||||
|
|
||||||
for _, dev := range p.devices {
|
|
||||||
for i := 2; i >= 0; i-- {
|
|
||||||
err = C.clGetProgramBuildInfo(p.clProgram, dev.id, C.CL_PROGRAM_BUILD_LOG, C.size_t(len(buffer)), unsafe.Pointer(&buffer[0]), &bLen)
|
|
||||||
if err == C.CL_INVALID_VALUE && i > 0 && bLen < 1024*1024 {
|
|
||||||
// INVALID_VALUE probably means our buffer isn't large enough
|
|
||||||
buffer = make([]byte, bLen)
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return toError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if bLen > 1 {
|
|
||||||
return BuildError{
|
|
||||||
Device: dev,
|
|
||||||
Message: string(buffer[:bLen-1]),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return BuildError{
|
|
||||||
Device: nil,
|
|
||||||
Message: "build failed and produced no log entries",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Program) CreateKernel(name string) (*Kernel, error) {
|
|
||||||
cName := C.CString(name)
|
|
||||||
defer C.free(unsafe.Pointer(cName))
|
|
||||||
var err C.cl_int
|
|
||||||
clKernel := C.clCreateKernel(p.clProgram, cName, &err)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
kernel := &Kernel{clKernel: clKernel, name: name}
|
|
||||||
runtime.SetFinalizer(kernel, releaseKernel)
|
|
||||||
return kernel, nil
|
|
||||||
}
|
|
||||||
193
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/queue.go
generated
vendored
193
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/queue.go
generated
vendored
@@ -1,193 +0,0 @@
|
|||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
type CommandQueueProperty int
|
|
||||||
|
|
||||||
const (
|
|
||||||
CommandQueueOutOfOrderExecModeEnable CommandQueueProperty = C.CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
|
|
||||||
CommandQueueProfilingEnable CommandQueueProperty = C.CL_QUEUE_PROFILING_ENABLE
|
|
||||||
)
|
|
||||||
|
|
||||||
type CommandQueue struct {
|
|
||||||
clQueue C.cl_command_queue
|
|
||||||
device *Device
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseCommandQueue(q *CommandQueue) {
|
|
||||||
if q.clQueue != nil {
|
|
||||||
C.clReleaseCommandQueue(q.clQueue)
|
|
||||||
q.clQueue = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call clReleaseCommandQueue on the CommandQueue. Using the CommandQueue after Release will cause a panick.
|
|
||||||
func (q *CommandQueue) Release() {
|
|
||||||
releaseCommandQueue(q)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Blocks until all previously queued OpenCL commands in a command-queue are issued to the associated device and have completed.
|
|
||||||
func (q *CommandQueue) Finish() error {
|
|
||||||
return toError(C.clFinish(q.clQueue))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Issues all previously queued OpenCL commands in a command-queue to the device associated with the command-queue.
|
|
||||||
func (q *CommandQueue) Flush() error {
|
|
||||||
return toError(C.clFlush(q.clQueue))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueues a command to map a region of the buffer object given by buffer into the host address space and returns a pointer to this mapped region.
|
|
||||||
func (q *CommandQueue) EnqueueMapBuffer(buffer *MemObject, blocking bool, flags MapFlag, offset, size int, eventWaitList []*Event) (*MappedMemObject, *Event, error) {
|
|
||||||
var event C.cl_event
|
|
||||||
var err C.cl_int
|
|
||||||
ptr := C.clEnqueueMapBuffer(q.clQueue, buffer.clMem, clBool(blocking), flags.toCl(), C.size_t(offset), C.size_t(size), C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event, &err)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return nil, nil, toError(err)
|
|
||||||
}
|
|
||||||
ev := newEvent(event)
|
|
||||||
if ptr == nil {
|
|
||||||
return nil, ev, ErrUnknown
|
|
||||||
}
|
|
||||||
return &MappedMemObject{ptr: ptr, size: size}, ev, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueues a command to map a region of an image object into the host address space and returns a pointer to this mapped region.
|
|
||||||
func (q *CommandQueue) EnqueueMapImage(buffer *MemObject, blocking bool, flags MapFlag, origin, region [3]int, eventWaitList []*Event) (*MappedMemObject, *Event, error) {
|
|
||||||
cOrigin := sizeT3(origin)
|
|
||||||
cRegion := sizeT3(region)
|
|
||||||
var event C.cl_event
|
|
||||||
var err C.cl_int
|
|
||||||
var rowPitch, slicePitch C.size_t
|
|
||||||
ptr := C.clEnqueueMapImage(q.clQueue, buffer.clMem, clBool(blocking), flags.toCl(), &cOrigin[0], &cRegion[0], &rowPitch, &slicePitch, C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event, &err)
|
|
||||||
if err != C.CL_SUCCESS {
|
|
||||||
return nil, nil, toError(err)
|
|
||||||
}
|
|
||||||
ev := newEvent(event)
|
|
||||||
if ptr == nil {
|
|
||||||
return nil, ev, ErrUnknown
|
|
||||||
}
|
|
||||||
size := 0 // TODO: could calculate this
|
|
||||||
return &MappedMemObject{ptr: ptr, size: size, rowPitch: int(rowPitch), slicePitch: int(slicePitch)}, ev, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueues a command to unmap a previously mapped region of a memory object.
|
|
||||||
func (q *CommandQueue) EnqueueUnmapMemObject(buffer *MemObject, mappedObj *MappedMemObject, eventWaitList []*Event) (*Event, error) {
|
|
||||||
var event C.cl_event
|
|
||||||
if err := C.clEnqueueUnmapMemObject(q.clQueue, buffer.clMem, mappedObj.ptr, C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event); err != C.CL_SUCCESS {
|
|
||||||
return nil, toError(err)
|
|
||||||
}
|
|
||||||
return newEvent(event), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueues a command to copy a buffer object to another buffer object.
|
|
||||||
func (q *CommandQueue) EnqueueCopyBuffer(srcBuffer, dstBuffer *MemObject, srcOffset, dstOffset, byteCount int, eventWaitList []*Event) (*Event, error) {
|
|
||||||
var event C.cl_event
|
|
||||||
err := toError(C.clEnqueueCopyBuffer(q.clQueue, srcBuffer.clMem, dstBuffer.clMem, C.size_t(srcOffset), C.size_t(dstOffset), C.size_t(byteCount), C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event))
|
|
||||||
return newEvent(event), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueue commands to write to a buffer object from host memory.
|
|
||||||
func (q *CommandQueue) EnqueueWriteBuffer(buffer *MemObject, blocking bool, offset, dataSize int, dataPtr unsafe.Pointer, eventWaitList []*Event) (*Event, error) {
|
|
||||||
var event C.cl_event
|
|
||||||
err := toError(C.clEnqueueWriteBuffer(q.clQueue, buffer.clMem, clBool(blocking), C.size_t(offset), C.size_t(dataSize), dataPtr, C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event))
|
|
||||||
return newEvent(event), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *CommandQueue) EnqueueWriteBufferFloat32(buffer *MemObject, blocking bool, offset int, data []float32, eventWaitList []*Event) (*Event, error) {
|
|
||||||
dataPtr := unsafe.Pointer(&data[0])
|
|
||||||
dataSize := int(unsafe.Sizeof(data[0])) * len(data)
|
|
||||||
return q.EnqueueWriteBuffer(buffer, blocking, offset, dataSize, dataPtr, eventWaitList)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueue commands to read from a buffer object to host memory.
|
|
||||||
func (q *CommandQueue) EnqueueReadBuffer(buffer *MemObject, blocking bool, offset, dataSize int, dataPtr unsafe.Pointer, eventWaitList []*Event) (*Event, error) {
|
|
||||||
var event C.cl_event
|
|
||||||
err := toError(C.clEnqueueReadBuffer(q.clQueue, buffer.clMem, clBool(blocking), C.size_t(offset), C.size_t(dataSize), dataPtr, C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event))
|
|
||||||
return newEvent(event), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *CommandQueue) EnqueueReadBufferFloat32(buffer *MemObject, blocking bool, offset int, data []float32, eventWaitList []*Event) (*Event, error) {
|
|
||||||
dataPtr := unsafe.Pointer(&data[0])
|
|
||||||
dataSize := int(unsafe.Sizeof(data[0])) * len(data)
|
|
||||||
return q.EnqueueReadBuffer(buffer, blocking, offset, dataSize, dataPtr, eventWaitList)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueues a command to execute a kernel on a device.
|
|
||||||
func (q *CommandQueue) EnqueueNDRangeKernel(kernel *Kernel, globalWorkOffset, globalWorkSize, localWorkSize []int, eventWaitList []*Event) (*Event, error) {
|
|
||||||
workDim := len(globalWorkSize)
|
|
||||||
var globalWorkOffsetList []C.size_t
|
|
||||||
var globalWorkOffsetPtr *C.size_t
|
|
||||||
if globalWorkOffset != nil {
|
|
||||||
globalWorkOffsetList = make([]C.size_t, len(globalWorkOffset))
|
|
||||||
for i, off := range globalWorkOffset {
|
|
||||||
globalWorkOffsetList[i] = C.size_t(off)
|
|
||||||
}
|
|
||||||
globalWorkOffsetPtr = &globalWorkOffsetList[0]
|
|
||||||
}
|
|
||||||
var globalWorkSizeList []C.size_t
|
|
||||||
var globalWorkSizePtr *C.size_t
|
|
||||||
if globalWorkSize != nil {
|
|
||||||
globalWorkSizeList = make([]C.size_t, len(globalWorkSize))
|
|
||||||
for i, off := range globalWorkSize {
|
|
||||||
globalWorkSizeList[i] = C.size_t(off)
|
|
||||||
}
|
|
||||||
globalWorkSizePtr = &globalWorkSizeList[0]
|
|
||||||
}
|
|
||||||
var localWorkSizeList []C.size_t
|
|
||||||
var localWorkSizePtr *C.size_t
|
|
||||||
if localWorkSize != nil {
|
|
||||||
localWorkSizeList = make([]C.size_t, len(localWorkSize))
|
|
||||||
for i, off := range localWorkSize {
|
|
||||||
localWorkSizeList[i] = C.size_t(off)
|
|
||||||
}
|
|
||||||
localWorkSizePtr = &localWorkSizeList[0]
|
|
||||||
}
|
|
||||||
var event C.cl_event
|
|
||||||
err := toError(C.clEnqueueNDRangeKernel(q.clQueue, kernel.clKernel, C.cl_uint(workDim), globalWorkOffsetPtr, globalWorkSizePtr, localWorkSizePtr, C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event))
|
|
||||||
return newEvent(event), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueues a command to read from a 2D or 3D image object to host memory.
|
|
||||||
func (q *CommandQueue) EnqueueReadImage(image *MemObject, blocking bool, origin, region [3]int, rowPitch, slicePitch int, data []byte, eventWaitList []*Event) (*Event, error) {
|
|
||||||
cOrigin := sizeT3(origin)
|
|
||||||
cRegion := sizeT3(region)
|
|
||||||
var event C.cl_event
|
|
||||||
err := toError(C.clEnqueueReadImage(q.clQueue, image.clMem, clBool(blocking), &cOrigin[0], &cRegion[0], C.size_t(rowPitch), C.size_t(slicePitch), unsafe.Pointer(&data[0]), C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event))
|
|
||||||
return newEvent(event), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueues a command to write from a 2D or 3D image object to host memory.
|
|
||||||
func (q *CommandQueue) EnqueueWriteImage(image *MemObject, blocking bool, origin, region [3]int, rowPitch, slicePitch int, data []byte, eventWaitList []*Event) (*Event, error) {
|
|
||||||
cOrigin := sizeT3(origin)
|
|
||||||
cRegion := sizeT3(region)
|
|
||||||
var event C.cl_event
|
|
||||||
err := toError(C.clEnqueueWriteImage(q.clQueue, image.clMem, clBool(blocking), &cOrigin[0], &cRegion[0], C.size_t(rowPitch), C.size_t(slicePitch), unsafe.Pointer(&data[0]), C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event))
|
|
||||||
return newEvent(event), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *CommandQueue) EnqueueFillBuffer(buffer *MemObject, pattern unsafe.Pointer, patternSize, offset, size int, eventWaitList []*Event) (*Event, error) {
|
|
||||||
var event C.cl_event
|
|
||||||
err := toError(C.clEnqueueFillBuffer(q.clQueue, buffer.clMem, pattern, C.size_t(patternSize), C.size_t(offset), C.size_t(size), C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event))
|
|
||||||
return newEvent(event), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// A synchronization point that enqueues a barrier operation.
|
|
||||||
func (q *CommandQueue) EnqueueBarrierWithWaitList(eventWaitList []*Event) (*Event, error) {
|
|
||||||
var event C.cl_event
|
|
||||||
err := toError(C.clEnqueueBarrierWithWaitList(q.clQueue, C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event))
|
|
||||||
return newEvent(event), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueues a marker command which waits for either a list of events to complete, or all previously enqueued commands to complete.
|
|
||||||
func (q *CommandQueue) EnqueueMarkerWithWaitList(eventWaitList []*Event) (*Event, error) {
|
|
||||||
var event C.cl_event
|
|
||||||
err := toError(C.clEnqueueMarkerWithWaitList(q.clQueue, C.cl_uint(len(eventWaitList)), eventListPtr(eventWaitList), &event))
|
|
||||||
return newEvent(event), err
|
|
||||||
}
|
|
||||||
487
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/types.go
generated
vendored
487
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/types.go
generated
vendored
@@ -1,487 +0,0 @@
|
|||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrUnknown = errors.New("cl: unknown error") // Generally an unexpected result from an OpenCL function (e.g. CL_SUCCESS but null pointer)
|
|
||||||
)
|
|
||||||
|
|
||||||
type ErrOther int
|
|
||||||
|
|
||||||
func (e ErrOther) Error() string {
|
|
||||||
return fmt.Sprintf("cl: error %d", int(e))
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrDeviceNotFound = errors.New("cl: Device Not Found")
|
|
||||||
ErrDeviceNotAvailable = errors.New("cl: Device Not Available")
|
|
||||||
ErrCompilerNotAvailable = errors.New("cl: Compiler Not Available")
|
|
||||||
ErrMemObjectAllocationFailure = errors.New("cl: Mem Object Allocation Failure")
|
|
||||||
ErrOutOfResources = errors.New("cl: Out Of Resources")
|
|
||||||
ErrOutOfHostMemory = errors.New("cl: Out Of Host Memory")
|
|
||||||
ErrProfilingInfoNotAvailable = errors.New("cl: Profiling Info Not Available")
|
|
||||||
ErrMemCopyOverlap = errors.New("cl: Mem Copy Overlap")
|
|
||||||
ErrImageFormatMismatch = errors.New("cl: Image Format Mismatch")
|
|
||||||
ErrImageFormatNotSupported = errors.New("cl: Image Format Not Supported")
|
|
||||||
ErrBuildProgramFailure = errors.New("cl: Build Program Failure")
|
|
||||||
ErrMapFailure = errors.New("cl: Map Failure")
|
|
||||||
ErrMisalignedSubBufferOffset = errors.New("cl: Misaligned Sub Buffer Offset")
|
|
||||||
ErrExecStatusErrorForEventsInWaitList = errors.New("cl: Exec Status Error For Events In Wait List")
|
|
||||||
ErrCompileProgramFailure = errors.New("cl: Compile Program Failure")
|
|
||||||
ErrLinkerNotAvailable = errors.New("cl: Linker Not Available")
|
|
||||||
ErrLinkProgramFailure = errors.New("cl: Link Program Failure")
|
|
||||||
ErrDevicePartitionFailed = errors.New("cl: Device Partition Failed")
|
|
||||||
ErrKernelArgInfoNotAvailable = errors.New("cl: Kernel Arg Info Not Available")
|
|
||||||
ErrInvalidValue = errors.New("cl: Invalid Value")
|
|
||||||
ErrInvalidDeviceType = errors.New("cl: Invalid Device Type")
|
|
||||||
ErrInvalidPlatform = errors.New("cl: Invalid Platform")
|
|
||||||
ErrInvalidDevice = errors.New("cl: Invalid Device")
|
|
||||||
ErrInvalidContext = errors.New("cl: Invalid Context")
|
|
||||||
ErrInvalidQueueProperties = errors.New("cl: Invalid Queue Properties")
|
|
||||||
ErrInvalidCommandQueue = errors.New("cl: Invalid Command Queue")
|
|
||||||
ErrInvalidHostPtr = errors.New("cl: Invalid Host Ptr")
|
|
||||||
ErrInvalidMemObject = errors.New("cl: Invalid Mem Object")
|
|
||||||
ErrInvalidImageFormatDescriptor = errors.New("cl: Invalid Image Format Descriptor")
|
|
||||||
ErrInvalidImageSize = errors.New("cl: Invalid Image Size")
|
|
||||||
ErrInvalidSampler = errors.New("cl: Invalid Sampler")
|
|
||||||
ErrInvalidBinary = errors.New("cl: Invalid Binary")
|
|
||||||
ErrInvalidBuildOptions = errors.New("cl: Invalid Build Options")
|
|
||||||
ErrInvalidProgram = errors.New("cl: Invalid Program")
|
|
||||||
ErrInvalidProgramExecutable = errors.New("cl: Invalid Program Executable")
|
|
||||||
ErrInvalidKernelName = errors.New("cl: Invalid Kernel Name")
|
|
||||||
ErrInvalidKernelDefinition = errors.New("cl: Invalid Kernel Definition")
|
|
||||||
ErrInvalidKernel = errors.New("cl: Invalid Kernel")
|
|
||||||
ErrInvalidArgIndex = errors.New("cl: Invalid Arg Index")
|
|
||||||
ErrInvalidArgValue = errors.New("cl: Invalid Arg Value")
|
|
||||||
ErrInvalidArgSize = errors.New("cl: Invalid Arg Size")
|
|
||||||
ErrInvalidKernelArgs = errors.New("cl: Invalid Kernel Args")
|
|
||||||
ErrInvalidWorkDimension = errors.New("cl: Invalid Work Dimension")
|
|
||||||
ErrInvalidWorkGroupSize = errors.New("cl: Invalid Work Group Size")
|
|
||||||
ErrInvalidWorkItemSize = errors.New("cl: Invalid Work Item Size")
|
|
||||||
ErrInvalidGlobalOffset = errors.New("cl: Invalid Global Offset")
|
|
||||||
ErrInvalidEventWaitList = errors.New("cl: Invalid Event Wait List")
|
|
||||||
ErrInvalidEvent = errors.New("cl: Invalid Event")
|
|
||||||
ErrInvalidOperation = errors.New("cl: Invalid Operation")
|
|
||||||
ErrInvalidGlObject = errors.New("cl: Invalid Gl Object")
|
|
||||||
ErrInvalidBufferSize = errors.New("cl: Invalid Buffer Size")
|
|
||||||
ErrInvalidMipLevel = errors.New("cl: Invalid Mip Level")
|
|
||||||
ErrInvalidGlobalWorkSize = errors.New("cl: Invalid Global Work Size")
|
|
||||||
ErrInvalidProperty = errors.New("cl: Invalid Property")
|
|
||||||
ErrInvalidImageDescriptor = errors.New("cl: Invalid Image Descriptor")
|
|
||||||
ErrInvalidCompilerOptions = errors.New("cl: Invalid Compiler Options")
|
|
||||||
ErrInvalidLinkerOptions = errors.New("cl: Invalid Linker Options")
|
|
||||||
ErrInvalidDevicePartitionCount = errors.New("cl: Invalid Device Partition Count")
|
|
||||||
)
|
|
||||||
var errorMap = map[C.cl_int]error{
|
|
||||||
C.CL_SUCCESS: nil,
|
|
||||||
C.CL_DEVICE_NOT_FOUND: ErrDeviceNotFound,
|
|
||||||
C.CL_DEVICE_NOT_AVAILABLE: ErrDeviceNotAvailable,
|
|
||||||
C.CL_COMPILER_NOT_AVAILABLE: ErrCompilerNotAvailable,
|
|
||||||
C.CL_MEM_OBJECT_ALLOCATION_FAILURE: ErrMemObjectAllocationFailure,
|
|
||||||
C.CL_OUT_OF_RESOURCES: ErrOutOfResources,
|
|
||||||
C.CL_OUT_OF_HOST_MEMORY: ErrOutOfHostMemory,
|
|
||||||
C.CL_PROFILING_INFO_NOT_AVAILABLE: ErrProfilingInfoNotAvailable,
|
|
||||||
C.CL_MEM_COPY_OVERLAP: ErrMemCopyOverlap,
|
|
||||||
C.CL_IMAGE_FORMAT_MISMATCH: ErrImageFormatMismatch,
|
|
||||||
C.CL_IMAGE_FORMAT_NOT_SUPPORTED: ErrImageFormatNotSupported,
|
|
||||||
C.CL_BUILD_PROGRAM_FAILURE: ErrBuildProgramFailure,
|
|
||||||
C.CL_MAP_FAILURE: ErrMapFailure,
|
|
||||||
C.CL_MISALIGNED_SUB_BUFFER_OFFSET: ErrMisalignedSubBufferOffset,
|
|
||||||
C.CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST: ErrExecStatusErrorForEventsInWaitList,
|
|
||||||
C.CL_INVALID_VALUE: ErrInvalidValue,
|
|
||||||
C.CL_INVALID_DEVICE_TYPE: ErrInvalidDeviceType,
|
|
||||||
C.CL_INVALID_PLATFORM: ErrInvalidPlatform,
|
|
||||||
C.CL_INVALID_DEVICE: ErrInvalidDevice,
|
|
||||||
C.CL_INVALID_CONTEXT: ErrInvalidContext,
|
|
||||||
C.CL_INVALID_QUEUE_PROPERTIES: ErrInvalidQueueProperties,
|
|
||||||
C.CL_INVALID_COMMAND_QUEUE: ErrInvalidCommandQueue,
|
|
||||||
C.CL_INVALID_HOST_PTR: ErrInvalidHostPtr,
|
|
||||||
C.CL_INVALID_MEM_OBJECT: ErrInvalidMemObject,
|
|
||||||
C.CL_INVALID_IMAGE_FORMAT_DESCRIPTOR: ErrInvalidImageFormatDescriptor,
|
|
||||||
C.CL_INVALID_IMAGE_SIZE: ErrInvalidImageSize,
|
|
||||||
C.CL_INVALID_SAMPLER: ErrInvalidSampler,
|
|
||||||
C.CL_INVALID_BINARY: ErrInvalidBinary,
|
|
||||||
C.CL_INVALID_BUILD_OPTIONS: ErrInvalidBuildOptions,
|
|
||||||
C.CL_INVALID_PROGRAM: ErrInvalidProgram,
|
|
||||||
C.CL_INVALID_PROGRAM_EXECUTABLE: ErrInvalidProgramExecutable,
|
|
||||||
C.CL_INVALID_KERNEL_NAME: ErrInvalidKernelName,
|
|
||||||
C.CL_INVALID_KERNEL_DEFINITION: ErrInvalidKernelDefinition,
|
|
||||||
C.CL_INVALID_KERNEL: ErrInvalidKernel,
|
|
||||||
C.CL_INVALID_ARG_INDEX: ErrInvalidArgIndex,
|
|
||||||
C.CL_INVALID_ARG_VALUE: ErrInvalidArgValue,
|
|
||||||
C.CL_INVALID_ARG_SIZE: ErrInvalidArgSize,
|
|
||||||
C.CL_INVALID_KERNEL_ARGS: ErrInvalidKernelArgs,
|
|
||||||
C.CL_INVALID_WORK_DIMENSION: ErrInvalidWorkDimension,
|
|
||||||
C.CL_INVALID_WORK_GROUP_SIZE: ErrInvalidWorkGroupSize,
|
|
||||||
C.CL_INVALID_WORK_ITEM_SIZE: ErrInvalidWorkItemSize,
|
|
||||||
C.CL_INVALID_GLOBAL_OFFSET: ErrInvalidGlobalOffset,
|
|
||||||
C.CL_INVALID_EVENT_WAIT_LIST: ErrInvalidEventWaitList,
|
|
||||||
C.CL_INVALID_EVENT: ErrInvalidEvent,
|
|
||||||
C.CL_INVALID_OPERATION: ErrInvalidOperation,
|
|
||||||
C.CL_INVALID_GL_OBJECT: ErrInvalidGlObject,
|
|
||||||
C.CL_INVALID_BUFFER_SIZE: ErrInvalidBufferSize,
|
|
||||||
C.CL_INVALID_MIP_LEVEL: ErrInvalidMipLevel,
|
|
||||||
C.CL_INVALID_GLOBAL_WORK_SIZE: ErrInvalidGlobalWorkSize,
|
|
||||||
C.CL_INVALID_PROPERTY: ErrInvalidProperty,
|
|
||||||
}
|
|
||||||
|
|
||||||
func toError(code C.cl_int) error {
|
|
||||||
if err, ok := errorMap[code]; ok {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return ErrOther(code)
|
|
||||||
}
|
|
||||||
|
|
||||||
type LocalMemType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
LocalMemTypeNone LocalMemType = C.CL_NONE
|
|
||||||
LocalMemTypeGlobal LocalMemType = C.CL_GLOBAL
|
|
||||||
LocalMemTypeLocal LocalMemType = C.CL_LOCAL
|
|
||||||
)
|
|
||||||
|
|
||||||
var localMemTypeMap = map[LocalMemType]string{
|
|
||||||
LocalMemTypeNone: "None",
|
|
||||||
LocalMemTypeGlobal: "Global",
|
|
||||||
LocalMemTypeLocal: "Local",
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t LocalMemType) String() string {
|
|
||||||
name := localMemTypeMap[t]
|
|
||||||
if name == "" {
|
|
||||||
name = "Unknown"
|
|
||||||
}
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
type ExecCapability int
|
|
||||||
|
|
||||||
const (
|
|
||||||
ExecCapabilityKernel ExecCapability = C.CL_EXEC_KERNEL // The OpenCL device can execute OpenCL kernels.
|
|
||||||
ExecCapabilityNativeKernel ExecCapability = C.CL_EXEC_NATIVE_KERNEL // The OpenCL device can execute native kernels.
|
|
||||||
)
|
|
||||||
|
|
||||||
func (ec ExecCapability) String() string {
|
|
||||||
var parts []string
|
|
||||||
if ec&ExecCapabilityKernel != 0 {
|
|
||||||
parts = append(parts, "Kernel")
|
|
||||||
}
|
|
||||||
if ec&ExecCapabilityNativeKernel != 0 {
|
|
||||||
parts = append(parts, "NativeKernel")
|
|
||||||
}
|
|
||||||
if parts == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return strings.Join(parts, "|")
|
|
||||||
}
|
|
||||||
|
|
||||||
type MemCacheType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
MemCacheTypeNone MemCacheType = C.CL_NONE
|
|
||||||
MemCacheTypeReadOnlyCache MemCacheType = C.CL_READ_ONLY_CACHE
|
|
||||||
MemCacheTypeReadWriteCache MemCacheType = C.CL_READ_WRITE_CACHE
|
|
||||||
)
|
|
||||||
|
|
||||||
func (ct MemCacheType) String() string {
|
|
||||||
switch ct {
|
|
||||||
case MemCacheTypeNone:
|
|
||||||
return "None"
|
|
||||||
case MemCacheTypeReadOnlyCache:
|
|
||||||
return "ReadOnly"
|
|
||||||
case MemCacheTypeReadWriteCache:
|
|
||||||
return "ReadWrite"
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("Unknown(%x)", int(ct))
|
|
||||||
}
|
|
||||||
|
|
||||||
type MemFlag int
|
|
||||||
|
|
||||||
const (
|
|
||||||
MemReadWrite MemFlag = C.CL_MEM_READ_WRITE
|
|
||||||
MemWriteOnly MemFlag = C.CL_MEM_WRITE_ONLY
|
|
||||||
MemReadOnly MemFlag = C.CL_MEM_READ_ONLY
|
|
||||||
MemUseHostPtr MemFlag = C.CL_MEM_USE_HOST_PTR
|
|
||||||
MemAllocHostPtr MemFlag = C.CL_MEM_ALLOC_HOST_PTR
|
|
||||||
MemCopyHostPtr MemFlag = C.CL_MEM_COPY_HOST_PTR
|
|
||||||
|
|
||||||
MemWriteOnlyHost MemFlag = C.CL_MEM_HOST_WRITE_ONLY
|
|
||||||
MemReadOnlyHost MemFlag = C.CL_MEM_HOST_READ_ONLY
|
|
||||||
MemNoAccessHost MemFlag = C.CL_MEM_HOST_NO_ACCESS
|
|
||||||
)
|
|
||||||
|
|
||||||
type MemObjectType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
MemObjectTypeBuffer MemObjectType = C.CL_MEM_OBJECT_BUFFER
|
|
||||||
MemObjectTypeImage2D MemObjectType = C.CL_MEM_OBJECT_IMAGE2D
|
|
||||||
MemObjectTypeImage3D MemObjectType = C.CL_MEM_OBJECT_IMAGE3D
|
|
||||||
)
|
|
||||||
|
|
||||||
type MapFlag int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// This flag specifies that the region being mapped in the memory object is being mapped for reading.
|
|
||||||
MapFlagRead MapFlag = C.CL_MAP_READ
|
|
||||||
MapFlagWrite MapFlag = C.CL_MAP_WRITE
|
|
||||||
MapFlagWriteInvalidateRegion MapFlag = C.CL_MAP_WRITE_INVALIDATE_REGION
|
|
||||||
)
|
|
||||||
|
|
||||||
func (mf MapFlag) toCl() C.cl_map_flags {
|
|
||||||
return C.cl_map_flags(mf)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ChannelOrder int
|
|
||||||
|
|
||||||
const (
|
|
||||||
ChannelOrderR ChannelOrder = C.CL_R
|
|
||||||
ChannelOrderA ChannelOrder = C.CL_A
|
|
||||||
ChannelOrderRG ChannelOrder = C.CL_RG
|
|
||||||
ChannelOrderRA ChannelOrder = C.CL_RA
|
|
||||||
ChannelOrderRGB ChannelOrder = C.CL_RGB
|
|
||||||
ChannelOrderRGBA ChannelOrder = C.CL_RGBA
|
|
||||||
ChannelOrderBGRA ChannelOrder = C.CL_BGRA
|
|
||||||
ChannelOrderARGB ChannelOrder = C.CL_ARGB
|
|
||||||
ChannelOrderIntensity ChannelOrder = C.CL_INTENSITY
|
|
||||||
ChannelOrderLuminance ChannelOrder = C.CL_LUMINANCE
|
|
||||||
ChannelOrderRx ChannelOrder = C.CL_Rx
|
|
||||||
ChannelOrderRGx ChannelOrder = C.CL_RGx
|
|
||||||
ChannelOrderRGBx ChannelOrder = C.CL_RGBx
|
|
||||||
)
|
|
||||||
|
|
||||||
var channelOrderNameMap = map[ChannelOrder]string{
|
|
||||||
ChannelOrderR: "R",
|
|
||||||
ChannelOrderA: "A",
|
|
||||||
ChannelOrderRG: "RG",
|
|
||||||
ChannelOrderRA: "RA",
|
|
||||||
ChannelOrderRGB: "RGB",
|
|
||||||
ChannelOrderRGBA: "RGBA",
|
|
||||||
ChannelOrderBGRA: "BGRA",
|
|
||||||
ChannelOrderARGB: "ARGB",
|
|
||||||
ChannelOrderIntensity: "Intensity",
|
|
||||||
ChannelOrderLuminance: "Luminance",
|
|
||||||
ChannelOrderRx: "Rx",
|
|
||||||
ChannelOrderRGx: "RGx",
|
|
||||||
ChannelOrderRGBx: "RGBx",
|
|
||||||
}
|
|
||||||
|
|
||||||
func (co ChannelOrder) String() string {
|
|
||||||
name := channelOrderNameMap[co]
|
|
||||||
if name == "" {
|
|
||||||
name = fmt.Sprintf("Unknown(%x)", int(co))
|
|
||||||
}
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
type ChannelDataType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
ChannelDataTypeSNormInt8 ChannelDataType = C.CL_SNORM_INT8
|
|
||||||
ChannelDataTypeSNormInt16 ChannelDataType = C.CL_SNORM_INT16
|
|
||||||
ChannelDataTypeUNormInt8 ChannelDataType = C.CL_UNORM_INT8
|
|
||||||
ChannelDataTypeUNormInt16 ChannelDataType = C.CL_UNORM_INT16
|
|
||||||
ChannelDataTypeUNormShort565 ChannelDataType = C.CL_UNORM_SHORT_565
|
|
||||||
ChannelDataTypeUNormShort555 ChannelDataType = C.CL_UNORM_SHORT_555
|
|
||||||
ChannelDataTypeUNormInt101010 ChannelDataType = C.CL_UNORM_INT_101010
|
|
||||||
ChannelDataTypeSignedInt8 ChannelDataType = C.CL_SIGNED_INT8
|
|
||||||
ChannelDataTypeSignedInt16 ChannelDataType = C.CL_SIGNED_INT16
|
|
||||||
ChannelDataTypeSignedInt32 ChannelDataType = C.CL_SIGNED_INT32
|
|
||||||
ChannelDataTypeUnsignedInt8 ChannelDataType = C.CL_UNSIGNED_INT8
|
|
||||||
ChannelDataTypeUnsignedInt16 ChannelDataType = C.CL_UNSIGNED_INT16
|
|
||||||
ChannelDataTypeUnsignedInt32 ChannelDataType = C.CL_UNSIGNED_INT32
|
|
||||||
ChannelDataTypeHalfFloat ChannelDataType = C.CL_HALF_FLOAT
|
|
||||||
ChannelDataTypeFloat ChannelDataType = C.CL_FLOAT
|
|
||||||
)
|
|
||||||
|
|
||||||
var channelDataTypeNameMap = map[ChannelDataType]string{
|
|
||||||
ChannelDataTypeSNormInt8: "SNormInt8",
|
|
||||||
ChannelDataTypeSNormInt16: "SNormInt16",
|
|
||||||
ChannelDataTypeUNormInt8: "UNormInt8",
|
|
||||||
ChannelDataTypeUNormInt16: "UNormInt16",
|
|
||||||
ChannelDataTypeUNormShort565: "UNormShort565",
|
|
||||||
ChannelDataTypeUNormShort555: "UNormShort555",
|
|
||||||
ChannelDataTypeUNormInt101010: "UNormInt101010",
|
|
||||||
ChannelDataTypeSignedInt8: "SignedInt8",
|
|
||||||
ChannelDataTypeSignedInt16: "SignedInt16",
|
|
||||||
ChannelDataTypeSignedInt32: "SignedInt32",
|
|
||||||
ChannelDataTypeUnsignedInt8: "UnsignedInt8",
|
|
||||||
ChannelDataTypeUnsignedInt16: "UnsignedInt16",
|
|
||||||
ChannelDataTypeUnsignedInt32: "UnsignedInt32",
|
|
||||||
ChannelDataTypeHalfFloat: "HalfFloat",
|
|
||||||
ChannelDataTypeFloat: "Float",
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ct ChannelDataType) String() string {
|
|
||||||
name := channelDataTypeNameMap[ct]
|
|
||||||
if name == "" {
|
|
||||||
name = fmt.Sprintf("Unknown(%x)", int(ct))
|
|
||||||
}
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
type ImageFormat struct {
|
|
||||||
ChannelOrder ChannelOrder
|
|
||||||
ChannelDataType ChannelDataType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f ImageFormat) toCl() C.cl_image_format {
|
|
||||||
var format C.cl_image_format
|
|
||||||
format.image_channel_order = C.cl_channel_order(f.ChannelOrder)
|
|
||||||
format.image_channel_data_type = C.cl_channel_type(f.ChannelDataType)
|
|
||||||
return format
|
|
||||||
}
|
|
||||||
|
|
||||||
type ProfilingInfo int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// A 64-bit value that describes the current device time counter in
|
|
||||||
// nanoseconds when the command identified by event is enqueued in
|
|
||||||
// a command-queue by the host.
|
|
||||||
ProfilingInfoCommandQueued ProfilingInfo = C.CL_PROFILING_COMMAND_QUEUED
|
|
||||||
// A 64-bit value that describes the current device time counter in
|
|
||||||
// nanoseconds when the command identified by event that has been
|
|
||||||
// enqueued is submitted by the host to the device associated with the command-queue.
|
|
||||||
ProfilingInfoCommandSubmit ProfilingInfo = C.CL_PROFILING_COMMAND_SUBMIT
|
|
||||||
// A 64-bit value that describes the current device time counter in
|
|
||||||
// nanoseconds when the command identified by event starts execution on the device.
|
|
||||||
ProfilingInfoCommandStart ProfilingInfo = C.CL_PROFILING_COMMAND_START
|
|
||||||
// A 64-bit value that describes the current device time counter in
|
|
||||||
// nanoseconds when the command identified by event has finished
|
|
||||||
// execution on the device.
|
|
||||||
ProfilingInfoCommandEnd ProfilingInfo = C.CL_PROFILING_COMMAND_END
|
|
||||||
)
|
|
||||||
|
|
||||||
type CommmandExecStatus int
|
|
||||||
|
|
||||||
const (
|
|
||||||
CommmandExecStatusComplete CommmandExecStatus = C.CL_COMPLETE
|
|
||||||
CommmandExecStatusRunning CommmandExecStatus = C.CL_RUNNING
|
|
||||||
CommmandExecStatusSubmitted CommmandExecStatus = C.CL_SUBMITTED
|
|
||||||
CommmandExecStatusQueued CommmandExecStatus = C.CL_QUEUED
|
|
||||||
)
|
|
||||||
|
|
||||||
type Event struct {
|
|
||||||
clEvent C.cl_event
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseEvent(ev *Event) {
|
|
||||||
if ev.clEvent != nil {
|
|
||||||
C.clReleaseEvent(ev.clEvent)
|
|
||||||
ev.clEvent = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Event) Release() {
|
|
||||||
releaseEvent(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Event) GetEventProfilingInfo(paramName ProfilingInfo) (int64, error) {
|
|
||||||
var paramValue C.cl_ulong
|
|
||||||
if err := C.clGetEventProfilingInfo(e.clEvent, C.cl_profiling_info(paramName), C.size_t(unsafe.Sizeof(paramValue)), unsafe.Pointer(¶mValue), nil); err != C.CL_SUCCESS {
|
|
||||||
return 0, toError(err)
|
|
||||||
}
|
|
||||||
return int64(paramValue), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets the execution status of a user event object.
|
|
||||||
//
|
|
||||||
// `status` specifies the new execution status to be set and
|
|
||||||
// can be CL_COMPLETE or a negative integer value to indicate
|
|
||||||
// an error. A negative integer value causes all enqueued commands
|
|
||||||
// that wait on this user event to be terminated. clSetUserEventStatus
|
|
||||||
// can only be called once to change the execution status of event.
|
|
||||||
func (e *Event) SetUserEventStatus(status int) error {
|
|
||||||
return toError(C.clSetUserEventStatus(e.clEvent, C.cl_int(status)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Waits on the host thread for commands identified by event objects in
|
|
||||||
// events to complete. A command is considered complete if its execution
|
|
||||||
// status is CL_COMPLETE or a negative value. The events specified in
|
|
||||||
// event_list act as synchronization points.
|
|
||||||
//
|
|
||||||
// If the cl_khr_gl_event extension is enabled, event objects can also be
|
|
||||||
// used to reflect the status of an OpenGL sync object. The sync object
|
|
||||||
// in turn refers to a fence command executing in an OpenGL command
|
|
||||||
// stream. This provides another method of coordinating sharing of buffers
|
|
||||||
// and images between OpenGL and OpenCL.
|
|
||||||
func WaitForEvents(events []*Event) error {
|
|
||||||
return toError(C.clWaitForEvents(C.cl_uint(len(events)), eventListPtr(events)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func newEvent(clEvent C.cl_event) *Event {
|
|
||||||
ev := &Event{clEvent: clEvent}
|
|
||||||
runtime.SetFinalizer(ev, releaseEvent)
|
|
||||||
return ev
|
|
||||||
}
|
|
||||||
|
|
||||||
func eventListPtr(el []*Event) *C.cl_event {
|
|
||||||
if el == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
elist := make([]C.cl_event, len(el))
|
|
||||||
for i, e := range el {
|
|
||||||
elist[i] = e.clEvent
|
|
||||||
}
|
|
||||||
return (*C.cl_event)(&elist[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
func clBool(b bool) C.cl_bool {
|
|
||||||
if b {
|
|
||||||
return C.CL_TRUE
|
|
||||||
}
|
|
||||||
return C.CL_FALSE
|
|
||||||
}
|
|
||||||
|
|
||||||
func sizeT3(i3 [3]int) [3]C.size_t {
|
|
||||||
var val [3]C.size_t
|
|
||||||
val[0] = C.size_t(i3[0])
|
|
||||||
val[1] = C.size_t(i3[1])
|
|
||||||
val[2] = C.size_t(i3[2])
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
type MappedMemObject struct {
|
|
||||||
ptr unsafe.Pointer
|
|
||||||
size int
|
|
||||||
rowPitch int
|
|
||||||
slicePitch int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mb *MappedMemObject) ByteSlice() []byte {
|
|
||||||
var byteSlice []byte
|
|
||||||
sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&byteSlice))
|
|
||||||
sliceHeader.Cap = mb.size
|
|
||||||
sliceHeader.Len = mb.size
|
|
||||||
sliceHeader.Data = uintptr(mb.ptr)
|
|
||||||
return byteSlice
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mb *MappedMemObject) Ptr() unsafe.Pointer {
|
|
||||||
return mb.ptr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mb *MappedMemObject) Size() int {
|
|
||||||
return mb.size
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mb *MappedMemObject) RowPitch() int {
|
|
||||||
return mb.rowPitch
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mb *MappedMemObject) SlicePitch() int {
|
|
||||||
return mb.slicePitch
|
|
||||||
}
|
|
||||||
71
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/types12.go
generated
vendored
71
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/types12.go
generated
vendored
@@ -1,71 +0,0 @@
|
|||||||
// +build cl12
|
|
||||||
|
|
||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
const (
|
|
||||||
ChannelDataTypeUNormInt24 ChannelDataType = C.CL_UNORM_INT24
|
|
||||||
ChannelOrderDepth ChannelOrder = C.CL_DEPTH
|
|
||||||
ChannelOrderDepthStencil ChannelOrder = C.CL_DEPTH_STENCIL
|
|
||||||
MemHostNoAccess MemFlag = C.CL_MEM_HOST_NO_ACCESS // OpenCL 1.2
|
|
||||||
MemHostReadOnly MemFlag = C.CL_MEM_HOST_READ_ONLY // OpenCL 1.2
|
|
||||||
MemHostWriteOnly MemFlag = C.CL_MEM_HOST_WRITE_ONLY // OpenCL 1.2
|
|
||||||
MemObjectTypeImage1D MemObjectType = C.CL_MEM_OBJECT_IMAGE1D
|
|
||||||
MemObjectTypeImage1DArray MemObjectType = C.CL_MEM_OBJECT_IMAGE1D_ARRAY
|
|
||||||
MemObjectTypeImage1DBuffer MemObjectType = C.CL_MEM_OBJECT_IMAGE1D_BUFFER
|
|
||||||
MemObjectTypeImage2DArray MemObjectType = C.CL_MEM_OBJECT_IMAGE2D_ARRAY
|
|
||||||
// This flag specifies that the region being mapped in the memory object is being mapped for writing.
|
|
||||||
//
|
|
||||||
// The contents of the region being mapped are to be discarded. This is typically the case when the
|
|
||||||
// region being mapped is overwritten by the host. This flag allows the implementation to no longer
|
|
||||||
// guarantee that the pointer returned by clEnqueueMapBuffer or clEnqueueMapImage contains the
|
|
||||||
// latest bits in the region being mapped which can be a significant performance enhancement.
|
|
||||||
MapFlagWriteInvalidateRegion MapFlag = C.CL_MAP_WRITE_INVALIDATE_REGION
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
errorMap[C.CL_COMPILE_PROGRAM_FAILURE] = ErrCompileProgramFailure
|
|
||||||
errorMap[C.CL_DEVICE_PARTITION_FAILED] = ErrDevicePartitionFailed
|
|
||||||
errorMap[C.CL_INVALID_COMPILER_OPTIONS] = ErrInvalidCompilerOptions
|
|
||||||
errorMap[C.CL_INVALID_DEVICE_PARTITION_COUNT] = ErrInvalidDevicePartitionCount
|
|
||||||
errorMap[C.CL_INVALID_IMAGE_DESCRIPTOR] = ErrInvalidImageDescriptor
|
|
||||||
errorMap[C.CL_INVALID_LINKER_OPTIONS] = ErrInvalidLinkerOptions
|
|
||||||
errorMap[C.CL_KERNEL_ARG_INFO_NOT_AVAILABLE] = ErrKernelArgInfoNotAvailable
|
|
||||||
errorMap[C.CL_LINK_PROGRAM_FAILURE] = ErrLinkProgramFailure
|
|
||||||
errorMap[C.CL_LINKER_NOT_AVAILABLE] = ErrLinkerNotAvailable
|
|
||||||
channelOrderNameMap[ChannelOrderDepth] = "Depth"
|
|
||||||
channelOrderNameMap[ChannelOrderDepthStencil] = "DepthStencil"
|
|
||||||
channelDataTypeNameMap[ChannelDataTypeUNormInt24] = "UNormInt24"
|
|
||||||
}
|
|
||||||
|
|
||||||
type ImageDescription struct {
|
|
||||||
Type MemObjectType
|
|
||||||
Width, Height, Depth int
|
|
||||||
ArraySize, RowPitch, SlicePitch int
|
|
||||||
NumMipLevels, NumSamples int
|
|
||||||
Buffer *MemObject
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d ImageDescription) toCl() C.cl_image_desc {
|
|
||||||
var desc C.cl_image_desc
|
|
||||||
desc.image_type = C.cl_mem_object_type(d.Type)
|
|
||||||
desc.image_width = C.size_t(d.Width)
|
|
||||||
desc.image_height = C.size_t(d.Height)
|
|
||||||
desc.image_depth = C.size_t(d.Depth)
|
|
||||||
desc.image_array_size = C.size_t(d.ArraySize)
|
|
||||||
desc.image_row_pitch = C.size_t(d.RowPitch)
|
|
||||||
desc.image_slice_pitch = C.size_t(d.SlicePitch)
|
|
||||||
desc.num_mip_levels = C.cl_uint(d.NumMipLevels)
|
|
||||||
desc.num_samples = C.cl_uint(d.NumSamples)
|
|
||||||
desc.buffer = nil
|
|
||||||
if d.Buffer != nil {
|
|
||||||
desc.buffer = d.Buffer.clMem
|
|
||||||
}
|
|
||||||
return desc
|
|
||||||
}
|
|
||||||
45
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/types_darwin.go
generated
vendored
45
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/types_darwin.go
generated
vendored
@@ -1,45 +0,0 @@
|
|||||||
package cl
|
|
||||||
|
|
||||||
// #ifdef __APPLE__
|
|
||||||
// #include "OpenCL/opencl.h"
|
|
||||||
// #else
|
|
||||||
// #include "cl.h"
|
|
||||||
// #endif
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
// Extension: cl_APPLE_fixed_alpha_channel_orders
|
|
||||||
//
|
|
||||||
// These selectors may be passed to clCreateImage2D() in the cl_image_format.image_channel_order field.
|
|
||||||
// They are like CL_BGRA and CL_ARGB except that the alpha channel to be ignored. On calls to read_imagef,
|
|
||||||
// the alpha will be 0xff (1.0f) if the sample falls in the image and 0 if it does not fall in the image.
|
|
||||||
// On calls to write_imagef, the alpha value is ignored and 0xff (1.0f) is written. These formats are
|
|
||||||
// currently only available for the CL_UNORM_INT8 cl_channel_type. They are intended to support legacy
|
|
||||||
// image formats.
|
|
||||||
const (
|
|
||||||
ChannelOrder1RGBApple ChannelOrder = C.CL_1RGB_APPLE // Introduced in MacOS X.7.
|
|
||||||
ChannelOrderBGR1Apple ChannelOrder = C.CL_BGR1_APPLE // Introduced in MacOS X.7.
|
|
||||||
)
|
|
||||||
|
|
||||||
// Extension: cl_APPLE_biased_fixed_point_image_formats
|
|
||||||
//
|
|
||||||
// This selector may be passed to clCreateImage2D() in the cl_image_format.image_channel_data_type field.
|
|
||||||
// It defines a biased signed 1.14 fixed point storage format, with range [-1, 3). The conversion from
|
|
||||||
// float to this fixed point format is defined as follows:
|
|
||||||
//
|
|
||||||
// ushort float_to_sfixed14( float x ){
|
|
||||||
// int i = convert_int_sat_rte( x * 0x1.0p14f ); // scale [-1, 3.0) to [-16384, 3*16384), round to nearest integer
|
|
||||||
// i = add_sat( i, 0x4000 ); // apply bias, to convert to [0, 65535) range
|
|
||||||
// return convert_ushort_sat(i); // clamp to destination size
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// The inverse conversion is the reverse process. The formats are currently only available on the CPU with
|
|
||||||
// the CL_RGBA channel layout.
|
|
||||||
const (
|
|
||||||
ChannelDataTypeSFixed14Apple ChannelDataType = C.CL_SFIXED14_APPLE // Introduced in MacOS X.7.
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
channelOrderNameMap[ChannelOrder1RGBApple] = "1RGBApple"
|
|
||||||
channelOrderNameMap[ChannelOrderBGR1Apple] = "RGB1Apple"
|
|
||||||
channelDataTypeNameMap[ChannelDataTypeSFixed14Apple] = "SFixed14Apple"
|
|
||||||
}
|
|
||||||
12
Godeps/_workspace/src/github.com/ethereum/ethash/.gitignore
generated
vendored
12
Godeps/_workspace/src/github.com/ethereum/ethash/.gitignore
generated
vendored
@@ -1,12 +0,0 @@
|
|||||||
.idea/
|
|
||||||
.DS_Store
|
|
||||||
*/**/*un~
|
|
||||||
.vagrant/
|
|
||||||
*.pyc
|
|
||||||
build/
|
|
||||||
pyethash.egg-info/
|
|
||||||
*.so
|
|
||||||
*~
|
|
||||||
*.swp
|
|
||||||
MANIFEST
|
|
||||||
dist/
|
|
||||||
23
Godeps/_workspace/src/github.com/ethereum/ethash/.travis.yml
generated
vendored
23
Godeps/_workspace/src/github.com/ethereum/ethash/.travis.yml
generated
vendored
@@ -1,23 +0,0 @@
|
|||||||
language: go
|
|
||||||
go:
|
|
||||||
- 1.4.2
|
|
||||||
|
|
||||||
before_install:
|
|
||||||
# for g++4.8 and C++11
|
|
||||||
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
|
||||||
|
|
||||||
# Set up go-ethereum
|
|
||||||
- sudo apt-get update -y -qq
|
|
||||||
- sudo apt-get install -yqq libgmp3-dev
|
|
||||||
- git clone --depth=10 https://github.com/ethereum/go-ethereum ${GOPATH}/src/github.com/ethereum/go-ethereum
|
|
||||||
# use canned dependencies from the go-ethereum repository
|
|
||||||
- export GOPATH=$GOPATH:$GOPATH/src/github.com/ethereum/go-ethereum/Godeps/_workspace/
|
|
||||||
- echo $GOPATH
|
|
||||||
|
|
||||||
install:
|
|
||||||
# need to explicitly request version 1.48 since by default we get 1.46 which does not work with C++11
|
|
||||||
- sudo apt-get install -qq --yes --force-yes g++-4.8
|
|
||||||
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 50
|
|
||||||
- sudo apt-get install -qq wget cmake bash libboost-test1.48-dev libboost-system1.48-dev libboost-filesystem1.48-dev nodejs python-pip python-dev valgrind
|
|
||||||
- sudo pip install virtualenv -q
|
|
||||||
script: "./test/test.sh"
|
|
||||||
14
Godeps/_workspace/src/github.com/ethereum/ethash/CMakeLists.txt
generated
vendored
14
Godeps/_workspace/src/github.com/ethereum/ethash/CMakeLists.txt
generated
vendored
@@ -1,14 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 2.8.7)
|
|
||||||
project(ethash)
|
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")
|
|
||||||
set(ETHHASH_LIBS ethash)
|
|
||||||
|
|
||||||
if (WIN32 AND WANT_CRYPTOPP)
|
|
||||||
add_subdirectory(cryptopp)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_subdirectory(src/libethash)
|
|
||||||
|
|
||||||
add_subdirectory(src/benchmark EXCLUDE_FROM_ALL)
|
|
||||||
add_subdirectory(test/c)
|
|
||||||
17
Godeps/_workspace/src/github.com/ethereum/ethash/MANIFEST.in
generated
vendored
17
Godeps/_workspace/src/github.com/ethereum/ethash/MANIFEST.in
generated
vendored
@@ -1,17 +0,0 @@
|
|||||||
include setup.py
|
|
||||||
|
|
||||||
# C sources
|
|
||||||
include src/libethash/internal.c
|
|
||||||
include src/libethash/sha3.c
|
|
||||||
include src/libethash/util.c
|
|
||||||
include src/python/core.c
|
|
||||||
|
|
||||||
# Headers
|
|
||||||
include src/libethash/compiler.h
|
|
||||||
include src/libethash/data_sizes.h
|
|
||||||
include src/libethash/endian.h
|
|
||||||
include src/libethash/ethash.h
|
|
||||||
include src/libethash/fnv.h
|
|
||||||
include src/libethash/internal.h
|
|
||||||
include src/libethash/sha3.h
|
|
||||||
include src/libethash/util.h
|
|
||||||
6
Godeps/_workspace/src/github.com/ethereum/ethash/Makefile
generated
vendored
6
Godeps/_workspace/src/github.com/ethereum/ethash/Makefile
generated
vendored
@@ -1,6 +0,0 @@
|
|||||||
.PHONY: clean test
|
|
||||||
test:
|
|
||||||
./test/test.sh
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf *.so pyethash.egg-info/ build/ test/python/python-virtual-env/ test/c/build/ pyethash.so test/python/*.pyc dist/ MANIFEST
|
|
||||||
22
Godeps/_workspace/src/github.com/ethereum/ethash/README.md
generated
vendored
22
Godeps/_workspace/src/github.com/ethereum/ethash/README.md
generated
vendored
@@ -1,22 +0,0 @@
|
|||||||
[](https://travis-ci.org/ethereum/ethash)
|
|
||||||
[](https://ci.appveyor.com/project/debris/ethash-nr37r/branch/master)
|
|
||||||
|
|
||||||
# Ethash
|
|
||||||
|
|
||||||
For details on this project, please see the Ethereum wiki:
|
|
||||||
https://github.com/ethereum/wiki/wiki/Ethash
|
|
||||||
|
|
||||||
### Coding Style for C++ code:
|
|
||||||
|
|
||||||
Follow the same exact style as in [cpp-ethereum](https://github.com/ethereum/cpp-ethereum/blob/develop/CodingStandards.txt)
|
|
||||||
|
|
||||||
### Coding Style for C code:
|
|
||||||
|
|
||||||
The main thing above all is code consistency.
|
|
||||||
|
|
||||||
- Tabs for indentation. A tab is 4 spaces
|
|
||||||
- Try to stick to the [K&R](http://en.wikipedia.org/wiki/Indent_style#K.26R_style),
|
|
||||||
especially for the C code.
|
|
||||||
- Keep the line lengths reasonable. No hard limit on 80 characters but don't go further
|
|
||||||
than 110. Some people work with multiple buffers next to each other.
|
|
||||||
Make them like you :)
|
|
||||||
7
Godeps/_workspace/src/github.com/ethereum/ethash/Vagrantfile
generated
vendored
7
Godeps/_workspace/src/github.com/ethereum/ethash/Vagrantfile
generated
vendored
@@ -1,7 +0,0 @@
|
|||||||
# -*- mode: ruby -*-
|
|
||||||
# vi: set ft=ruby :
|
|
||||||
|
|
||||||
Vagrant.configure(2) do |config|
|
|
||||||
config.vm.box = "Ubuntu 12.04"
|
|
||||||
config.vm.box_url = "https://cloud-images.ubuntu.com/vagrant/precise/current/precise-server-cloudimg-amd64-vagrant-disk1.box"
|
|
||||||
end
|
|
||||||
43
Godeps/_workspace/src/github.com/ethereum/ethash/appveyor.yml
generated
vendored
43
Godeps/_workspace/src/github.com/ethereum/ethash/appveyor.yml
generated
vendored
@@ -1,43 +0,0 @@
|
|||||||
version: 1.0.0.{build}
|
|
||||||
|
|
||||||
environment:
|
|
||||||
BOOST_ROOT: "c:/projects/ethash/deps/boost"
|
|
||||||
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
|
|
||||||
os: Windows Server 2012 R2
|
|
||||||
|
|
||||||
clone_folder: c:\projects\ethash
|
|
||||||
|
|
||||||
#platform: Any CPU
|
|
||||||
#configuration: Debug
|
|
||||||
|
|
||||||
install:
|
|
||||||
# by default, all script lines are interpreted as batch
|
|
||||||
|
|
||||||
# scripts to run before build
|
|
||||||
before_build:
|
|
||||||
- echo "Downloading boost..."
|
|
||||||
- mkdir c:\projects\ethash\deps
|
|
||||||
- cd c:\projects\ethash\deps
|
|
||||||
- curl -O https://build.ethdev.com/builds/windows-precompiled/boost.tar.gz
|
|
||||||
- echo "Unzipping boost..."
|
|
||||||
- 7z x boost.tar.gz > nul
|
|
||||||
- 7z x boost.tar > nul
|
|
||||||
- ls
|
|
||||||
- echo "Running cmake..."
|
|
||||||
- cd c:\projects\ethash
|
|
||||||
- cmake .
|
|
||||||
|
|
||||||
build:
|
|
||||||
project: ALL_BUILD.vcxproj # path to Visual Studio solution or project
|
|
||||||
|
|
||||||
after_build:
|
|
||||||
- echo "Running tests..."
|
|
||||||
- cd c:\projects\ethash\test\c\Debug
|
|
||||||
- Test.exe
|
|
||||||
- echo "Finished!"
|
|
||||||
|
|
||||||
441
Godeps/_workspace/src/github.com/ethereum/ethash/ethash.go
generated
vendored
441
Godeps/_workspace/src/github.com/ethereum/ethash/ethash.go
generated
vendored
@@ -1,441 +0,0 @@
|
|||||||
// Copyright 2015 The go-ethereum Authors
|
|
||||||
// Copyright 2015 Lefteris Karapetsas <lefteris@refu.co>
|
|
||||||
// Copyright 2015 Matthew Wampler-Doty <matthew.wampler.doty@gmail.com>
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package ethash
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include "src/libethash/internal.h"
|
|
||||||
|
|
||||||
int ethashGoCallback_cgo(unsigned);
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"math/big"
|
|
||||||
"math/rand"
|
|
||||||
"os"
|
|
||||||
"os/user"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
|
||||||
"github.com/ethereum/go-ethereum/pow"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
maxUint256 = new(big.Int).Exp(big.NewInt(2), big.NewInt(256), big.NewInt(0))
|
|
||||||
sharedLight = new(Light)
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
epochLength uint64 = 30000
|
|
||||||
cacheSizeForTesting C.uint64_t = 1024
|
|
||||||
dagSizeForTesting C.uint64_t = 1024 * 32
|
|
||||||
)
|
|
||||||
|
|
||||||
var DefaultDir = defaultDir()
|
|
||||||
|
|
||||||
func defaultDir() string {
|
|
||||||
home := os.Getenv("HOME")
|
|
||||||
if user, err := user.Current(); err == nil {
|
|
||||||
home = user.HomeDir
|
|
||||||
}
|
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
return filepath.Join(home, "AppData", "Ethash")
|
|
||||||
}
|
|
||||||
return filepath.Join(home, ".ethash")
|
|
||||||
}
|
|
||||||
|
|
||||||
// cache wraps an ethash_light_t with some metadata
|
|
||||||
// and automatic memory management.
|
|
||||||
type cache struct {
|
|
||||||
epoch uint64
|
|
||||||
used time.Time
|
|
||||||
test bool
|
|
||||||
|
|
||||||
gen sync.Once // ensures cache is only generated once.
|
|
||||||
ptr *C.struct_ethash_light
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate creates the actual cache. it can be called from multiple
|
|
||||||
// goroutines. the first call will generate the cache, subsequent
|
|
||||||
// calls wait until it is generated.
|
|
||||||
func (cache *cache) generate() {
|
|
||||||
cache.gen.Do(func() {
|
|
||||||
started := time.Now()
|
|
||||||
seedHash := makeSeedHash(cache.epoch)
|
|
||||||
glog.V(logger.Debug).Infof("Generating cache for epoch %d (%x)", cache.epoch, seedHash)
|
|
||||||
size := C.ethash_get_cachesize(C.uint64_t(cache.epoch * epochLength))
|
|
||||||
if cache.test {
|
|
||||||
size = cacheSizeForTesting
|
|
||||||
}
|
|
||||||
cache.ptr = C.ethash_light_new_internal(size, (*C.ethash_h256_t)(unsafe.Pointer(&seedHash[0])))
|
|
||||||
runtime.SetFinalizer(cache, freeCache)
|
|
||||||
glog.V(logger.Debug).Infof("Done generating cache for epoch %d, it took %v", cache.epoch, time.Since(started))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func freeCache(cache *cache) {
|
|
||||||
C.ethash_light_delete(cache.ptr)
|
|
||||||
cache.ptr = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cache *cache) compute(dagSize uint64, hash common.Hash, nonce uint64) (ok bool, mixDigest, result common.Hash) {
|
|
||||||
ret := C.ethash_light_compute_internal(cache.ptr, C.uint64_t(dagSize), hashToH256(hash), C.uint64_t(nonce))
|
|
||||||
// Make sure cache is live until after the C call.
|
|
||||||
// This is important because a GC might happen and execute
|
|
||||||
// the finalizer before the call completes.
|
|
||||||
_ = cache
|
|
||||||
return bool(ret.success), h256ToHash(ret.mix_hash), h256ToHash(ret.result)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Light implements the Verify half of the proof of work. It uses a few small
|
|
||||||
// in-memory caches to verify the nonces found by Full.
|
|
||||||
type Light struct {
|
|
||||||
test bool // If set, use a smaller cache size
|
|
||||||
|
|
||||||
mu sync.Mutex // Protects the per-epoch map of verification caches
|
|
||||||
caches map[uint64]*cache // Currently maintained verification caches
|
|
||||||
future *cache // Pre-generated cache for the estimated future DAG
|
|
||||||
|
|
||||||
NumCaches int // Maximum number of caches to keep before eviction (only init, don't modify)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify checks whether the block's nonce is valid.
|
|
||||||
func (l *Light) Verify(block pow.Block) bool {
|
|
||||||
// TODO: do ethash_quick_verify before getCache in order
|
|
||||||
// to prevent DOS attacks.
|
|
||||||
blockNum := block.NumberU64()
|
|
||||||
if blockNum >= epochLength*2048 {
|
|
||||||
glog.V(logger.Debug).Infof("block number %d too high, limit is %d", epochLength*2048)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
difficulty := block.Difficulty()
|
|
||||||
/* Cannot happen if block header diff is validated prior to PoW, but can
|
|
||||||
happen if PoW is checked first due to parallel PoW checking.
|
|
||||||
We could check the minimum valid difficulty but for SoC we avoid (duplicating)
|
|
||||||
Ethereum protocol consensus rules here which are not in scope of Ethash
|
|
||||||
*/
|
|
||||||
if difficulty.Cmp(common.Big0) == 0 {
|
|
||||||
glog.V(logger.Debug).Infof("invalid block difficulty")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
cache := l.getCache(blockNum)
|
|
||||||
dagSize := C.ethash_get_datasize(C.uint64_t(blockNum))
|
|
||||||
if l.test {
|
|
||||||
dagSize = dagSizeForTesting
|
|
||||||
}
|
|
||||||
// Recompute the hash using the cache.
|
|
||||||
ok, mixDigest, result := cache.compute(uint64(dagSize), block.HashNoNonce(), block.Nonce())
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// avoid mixdigest malleability as it's not included in a block's "hashNononce"
|
|
||||||
if block.MixDigest() != mixDigest {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// The actual check.
|
|
||||||
target := new(big.Int).Div(maxUint256, difficulty)
|
|
||||||
return result.Big().Cmp(target) <= 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func h256ToHash(in C.ethash_h256_t) common.Hash {
|
|
||||||
return *(*common.Hash)(unsafe.Pointer(&in.b))
|
|
||||||
}
|
|
||||||
|
|
||||||
func hashToH256(in common.Hash) C.ethash_h256_t {
|
|
||||||
return C.ethash_h256_t{b: *(*[32]C.uint8_t)(unsafe.Pointer(&in[0]))}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Light) getCache(blockNum uint64) *cache {
|
|
||||||
var c *cache
|
|
||||||
epoch := blockNum / epochLength
|
|
||||||
|
|
||||||
// If we have a PoW for that epoch, use that
|
|
||||||
l.mu.Lock()
|
|
||||||
if l.caches == nil {
|
|
||||||
l.caches = make(map[uint64]*cache)
|
|
||||||
}
|
|
||||||
if l.NumCaches == 0 {
|
|
||||||
l.NumCaches = 3
|
|
||||||
}
|
|
||||||
c = l.caches[epoch]
|
|
||||||
if c == nil {
|
|
||||||
// No cached DAG, evict the oldest if the cache limit was reached
|
|
||||||
if len(l.caches) >= l.NumCaches {
|
|
||||||
var evict *cache
|
|
||||||
for _, cache := range l.caches {
|
|
||||||
if evict == nil || evict.used.After(cache.used) {
|
|
||||||
evict = cache
|
|
||||||
}
|
|
||||||
}
|
|
||||||
glog.V(logger.Debug).Infof("Evicting DAG for epoch %d in favour of epoch %d", evict.epoch, epoch)
|
|
||||||
delete(l.caches, evict.epoch)
|
|
||||||
}
|
|
||||||
// If we have the new DAG pre-generated, use that, otherwise create a new one
|
|
||||||
if l.future != nil && l.future.epoch == epoch {
|
|
||||||
glog.V(logger.Debug).Infof("Using pre-generated DAG for epoch %d", epoch)
|
|
||||||
c, l.future = l.future, nil
|
|
||||||
} else {
|
|
||||||
glog.V(logger.Debug).Infof("No pre-generated DAG available, creating new for epoch %d", epoch)
|
|
||||||
c = &cache{epoch: epoch, test: l.test}
|
|
||||||
}
|
|
||||||
l.caches[epoch] = c
|
|
||||||
|
|
||||||
// If we just used up the future cache, or need a refresh, regenerate
|
|
||||||
if l.future == nil || l.future.epoch <= epoch {
|
|
||||||
glog.V(logger.Debug).Infof("Pre-generating DAG for epoch %d", epoch+1)
|
|
||||||
l.future = &cache{epoch: epoch + 1, test: l.test}
|
|
||||||
go l.future.generate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.used = time.Now()
|
|
||||||
l.mu.Unlock()
|
|
||||||
|
|
||||||
// Wait for generation finish and return the cache
|
|
||||||
c.generate()
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// dag wraps an ethash_full_t with some metadata
|
|
||||||
// and automatic memory management.
|
|
||||||
type dag struct {
|
|
||||||
epoch uint64
|
|
||||||
test bool
|
|
||||||
dir string
|
|
||||||
|
|
||||||
gen sync.Once // ensures DAG is only generated once.
|
|
||||||
ptr *C.struct_ethash_full
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate creates the actual DAG. it can be called from multiple
|
|
||||||
// goroutines. the first call will generate the DAG, subsequent
|
|
||||||
// calls wait until it is generated.
|
|
||||||
func (d *dag) generate() {
|
|
||||||
d.gen.Do(func() {
|
|
||||||
var (
|
|
||||||
started = time.Now()
|
|
||||||
seedHash = makeSeedHash(d.epoch)
|
|
||||||
blockNum = C.uint64_t(d.epoch * epochLength)
|
|
||||||
cacheSize = C.ethash_get_cachesize(blockNum)
|
|
||||||
dagSize = C.ethash_get_datasize(blockNum)
|
|
||||||
)
|
|
||||||
if d.test {
|
|
||||||
cacheSize = cacheSizeForTesting
|
|
||||||
dagSize = dagSizeForTesting
|
|
||||||
}
|
|
||||||
if d.dir == "" {
|
|
||||||
d.dir = DefaultDir
|
|
||||||
}
|
|
||||||
glog.V(logger.Info).Infof("Generating DAG for epoch %d (size %d) (%x)", d.epoch, dagSize, seedHash)
|
|
||||||
// Generate a temporary cache.
|
|
||||||
// TODO: this could share the cache with Light
|
|
||||||
cache := C.ethash_light_new_internal(cacheSize, (*C.ethash_h256_t)(unsafe.Pointer(&seedHash[0])))
|
|
||||||
defer C.ethash_light_delete(cache)
|
|
||||||
// Generate the actual DAG.
|
|
||||||
d.ptr = C.ethash_full_new_internal(
|
|
||||||
C.CString(d.dir),
|
|
||||||
hashToH256(seedHash),
|
|
||||||
dagSize,
|
|
||||||
cache,
|
|
||||||
(C.ethash_callback_t)(unsafe.Pointer(C.ethashGoCallback_cgo)),
|
|
||||||
)
|
|
||||||
if d.ptr == nil {
|
|
||||||
panic("ethash_full_new IO or memory error")
|
|
||||||
}
|
|
||||||
runtime.SetFinalizer(d, freeDAG)
|
|
||||||
glog.V(logger.Info).Infof("Done generating DAG for epoch %d, it took %v", d.epoch, time.Since(started))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func freeDAG(d *dag) {
|
|
||||||
C.ethash_full_delete(d.ptr)
|
|
||||||
d.ptr = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *dag) Ptr() unsafe.Pointer {
|
|
||||||
return unsafe.Pointer(d.ptr.data)
|
|
||||||
}
|
|
||||||
|
|
||||||
//export ethashGoCallback
|
|
||||||
func ethashGoCallback(percent C.unsigned) C.int {
|
|
||||||
glog.V(logger.Info).Infof("Generating DAG: %d%%", percent)
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeDAG pre-generates a DAG file for the given block number in the
|
|
||||||
// given directory. If dir is the empty string, the default directory
|
|
||||||
// is used.
|
|
||||||
func MakeDAG(blockNum uint64, dir string) error {
|
|
||||||
d := &dag{epoch: blockNum / epochLength, dir: dir}
|
|
||||||
if blockNum >= epochLength*2048 {
|
|
||||||
return fmt.Errorf("block number too high, limit is %d", epochLength*2048)
|
|
||||||
}
|
|
||||||
d.generate()
|
|
||||||
if d.ptr == nil {
|
|
||||||
return errors.New("failed")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Full implements the Search half of the proof of work.
|
|
||||||
type Full struct {
|
|
||||||
Dir string // use this to specify a non-default DAG directory
|
|
||||||
|
|
||||||
test bool // if set use a smaller DAG size
|
|
||||||
turbo bool
|
|
||||||
hashRate int32
|
|
||||||
|
|
||||||
mu sync.Mutex // protects dag
|
|
||||||
current *dag // current full DAG
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pow *Full) getDAG(blockNum uint64) (d *dag) {
|
|
||||||
epoch := blockNum / epochLength
|
|
||||||
pow.mu.Lock()
|
|
||||||
if pow.current != nil && pow.current.epoch == epoch {
|
|
||||||
d = pow.current
|
|
||||||
} else {
|
|
||||||
d = &dag{epoch: epoch, test: pow.test, dir: pow.Dir}
|
|
||||||
pow.current = d
|
|
||||||
}
|
|
||||||
pow.mu.Unlock()
|
|
||||||
// wait for it to finish generating.
|
|
||||||
d.generate()
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pow *Full) Search(block pow.Block, stop <-chan struct{}, index int) (nonce uint64, mixDigest []byte) {
|
|
||||||
dag := pow.getDAG(block.NumberU64())
|
|
||||||
|
|
||||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
||||||
diff := block.Difficulty()
|
|
||||||
|
|
||||||
i := int64(0)
|
|
||||||
starti := i
|
|
||||||
start := time.Now().UnixNano()
|
|
||||||
previousHashrate := int32(0)
|
|
||||||
|
|
||||||
nonce = uint64(r.Int63())
|
|
||||||
hash := hashToH256(block.HashNoNonce())
|
|
||||||
target := new(big.Int).Div(maxUint256, diff)
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-stop:
|
|
||||||
atomic.AddInt32(&pow.hashRate, -previousHashrate)
|
|
||||||
return 0, nil
|
|
||||||
default:
|
|
||||||
i++
|
|
||||||
|
|
||||||
// we don't have to update hash rate on every nonce, so update after
|
|
||||||
// first nonce check and then after 2^X nonces
|
|
||||||
if i == 2 || ((i % (1 << 16)) == 0) {
|
|
||||||
elapsed := time.Now().UnixNano() - start
|
|
||||||
hashes := (float64(1e9) / float64(elapsed)) * float64(i-starti)
|
|
||||||
hashrateDiff := int32(hashes) - previousHashrate
|
|
||||||
previousHashrate = int32(hashes)
|
|
||||||
atomic.AddInt32(&pow.hashRate, hashrateDiff)
|
|
||||||
}
|
|
||||||
|
|
||||||
ret := C.ethash_full_compute(dag.ptr, hash, C.uint64_t(nonce))
|
|
||||||
result := h256ToHash(ret.result).Big()
|
|
||||||
|
|
||||||
// TODO: disagrees with the spec https://github.com/ethereum/wiki/wiki/Ethash#mining
|
|
||||||
if ret.success && result.Cmp(target) <= 0 {
|
|
||||||
mixDigest = C.GoBytes(unsafe.Pointer(&ret.mix_hash), C.int(32))
|
|
||||||
atomic.AddInt32(&pow.hashRate, -previousHashrate)
|
|
||||||
return nonce, mixDigest
|
|
||||||
}
|
|
||||||
nonce += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pow.turbo {
|
|
||||||
time.Sleep(20 * time.Microsecond)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pow *Full) GetHashrate() int64 {
|
|
||||||
return int64(atomic.LoadInt32(&pow.hashRate))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pow *Full) Turbo(on bool) {
|
|
||||||
// TODO: this needs to use an atomic operation.
|
|
||||||
pow.turbo = on
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ethash combines block verification with Light and
|
|
||||||
// nonce searching with Full into a single proof of work.
|
|
||||||
type Ethash struct {
|
|
||||||
*Light
|
|
||||||
*Full
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates an instance of the proof of work.
|
|
||||||
func New() *Ethash {
|
|
||||||
return &Ethash{new(Light), &Full{turbo: true}}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewShared creates an instance of the proof of work., where a single instance
|
|
||||||
// of the Light cache is shared across all instances created with NewShared.
|
|
||||||
func NewShared() *Ethash {
|
|
||||||
return &Ethash{sharedLight, &Full{turbo: true}}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewForTesting creates a proof of work for use in unit tests.
|
|
||||||
// It uses a smaller DAG and cache size to keep test times low.
|
|
||||||
// DAG files are stored in a temporary directory.
|
|
||||||
//
|
|
||||||
// Nonces found by a testing instance are not verifiable with a
|
|
||||||
// regular-size cache.
|
|
||||||
func NewForTesting() (*Ethash, error) {
|
|
||||||
dir, err := ioutil.TempDir("", "ethash-test")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Ethash{&Light{test: true}, &Full{Dir: dir, test: true}}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetSeedHash(blockNum uint64) ([]byte, error) {
|
|
||||||
if blockNum >= epochLength*2048 {
|
|
||||||
return nil, fmt.Errorf("block number too high, limit is %d", epochLength*2048)
|
|
||||||
}
|
|
||||||
sh := makeSeedHash(blockNum / epochLength)
|
|
||||||
return sh[:], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeSeedHash(epoch uint64) (sh common.Hash) {
|
|
||||||
for ; epoch > 0; epoch-- {
|
|
||||||
sh = crypto.Sha3Hash(sh[:])
|
|
||||||
}
|
|
||||||
return sh
|
|
||||||
}
|
|
||||||
628
Godeps/_workspace/src/github.com/ethereum/ethash/ethash_opencl.go
generated
vendored
628
Godeps/_workspace/src/github.com/ethereum/ethash/ethash_opencl.go
generated
vendored
@@ -1,628 +0,0 @@
|
|||||||
// Copyright 2014 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// +build opencl
|
|
||||||
|
|
||||||
package ethash
|
|
||||||
|
|
||||||
//#cgo LDFLAGS: -w
|
|
||||||
//#include <stdint.h>
|
|
||||||
//#include <string.h>
|
|
||||||
//#include "src/libethash/internal.h"
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
|
||||||
crand "crypto/rand"
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
|
||||||
"math"
|
|
||||||
"math/big"
|
|
||||||
mrand "math/rand"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/Gustav-Simonsson/go-opencl/cl"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/pow"
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This code have two main entry points:
|
|
||||||
|
|
||||||
1. The initCL(...) function configures one or more OpenCL device
|
|
||||||
(for now only GPU) and loads the Ethash DAG onto device memory
|
|
||||||
|
|
||||||
2. The Search(...) function loads a Ethash nonce into device(s) memory and
|
|
||||||
executes the Ethash OpenCL kernel.
|
|
||||||
|
|
||||||
Throughout the code, we refer to "host memory" and "device memory".
|
|
||||||
For most systems (e.g. regular PC GPU miner) the host memory is RAM and
|
|
||||||
device memory is the GPU global memory (e.g. GDDR5).
|
|
||||||
|
|
||||||
References mentioned in code comments:
|
|
||||||
|
|
||||||
1. https://github.com/ethereum/wiki/wiki/Ethash
|
|
||||||
2. https://github.com/ethereum/cpp-ethereum/blob/develop/libethash-cl/ethash_cl_miner.cpp
|
|
||||||
3. https://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/
|
|
||||||
4. http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/12/AMD_OpenCL_Programming_User_Guide.pdf
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
type OpenCLDevice struct {
|
|
||||||
deviceId int
|
|
||||||
device *cl.Device
|
|
||||||
openCL11 bool // OpenCL version 1.1 and 1.2 are handled a bit different
|
|
||||||
openCL12 bool
|
|
||||||
|
|
||||||
dagBuf *cl.MemObject // Ethash full DAG in device mem
|
|
||||||
headerBuf *cl.MemObject // Hash of block-to-mine in device mem
|
|
||||||
searchBuffers []*cl.MemObject
|
|
||||||
|
|
||||||
searchKernel *cl.Kernel
|
|
||||||
hashKernel *cl.Kernel
|
|
||||||
|
|
||||||
queue *cl.CommandQueue
|
|
||||||
ctx *cl.Context
|
|
||||||
workGroupSize int
|
|
||||||
|
|
||||||
nonceRand *mrand.Rand // seeded by crypto/rand, see comments where it's initialised
|
|
||||||
result common.Hash
|
|
||||||
}
|
|
||||||
|
|
||||||
type OpenCLMiner struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
|
|
||||||
ethash *Ethash // Ethash full DAG & cache in host mem
|
|
||||||
|
|
||||||
deviceIds []int
|
|
||||||
devices []*OpenCLDevice
|
|
||||||
|
|
||||||
dagSize uint64
|
|
||||||
|
|
||||||
hashRate int32 // Go atomics & uint64 have some issues; int32 is supported on all platforms
|
|
||||||
}
|
|
||||||
|
|
||||||
type pendingSearch struct {
|
|
||||||
bufIndex uint32
|
|
||||||
startNonce uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
SIZEOF_UINT32 = 4
|
|
||||||
|
|
||||||
// See [1]
|
|
||||||
ethashMixBytesLen = 128
|
|
||||||
ethashAccesses = 64
|
|
||||||
|
|
||||||
// See [4]
|
|
||||||
workGroupSize = 32 // must be multiple of 8
|
|
||||||
maxSearchResults = 63
|
|
||||||
searchBufSize = 2
|
|
||||||
globalWorkSize = 1024 * 256
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewCL(deviceIds []int) *OpenCLMiner {
|
|
||||||
ids := make([]int, len(deviceIds))
|
|
||||||
copy(ids, deviceIds)
|
|
||||||
return &OpenCLMiner{
|
|
||||||
ethash: New(),
|
|
||||||
dagSize: 0, // to see if we need to update DAG.
|
|
||||||
deviceIds: ids,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PrintDevices() {
|
|
||||||
fmt.Println("=============================================")
|
|
||||||
fmt.Println("============ OpenCL Device Info =============")
|
|
||||||
fmt.Println("=============================================")
|
|
||||||
|
|
||||||
var found []*cl.Device
|
|
||||||
|
|
||||||
platforms, err := cl.GetPlatforms()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Plaform error (check your OpenCL installation):", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, p := range platforms {
|
|
||||||
fmt.Println("Platform id ", i)
|
|
||||||
fmt.Println("Platform Name ", p.Name())
|
|
||||||
fmt.Println("Platform Vendor ", p.Vendor())
|
|
||||||
fmt.Println("Platform Version ", p.Version())
|
|
||||||
fmt.Println("Platform Extensions ", p.Extensions())
|
|
||||||
fmt.Println("Platform Profile ", p.Profile())
|
|
||||||
fmt.Println("")
|
|
||||||
|
|
||||||
devices, err := cl.GetDevices(p, cl.DeviceTypeGPU)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Device error (check your GPU drivers) :", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, d := range devices {
|
|
||||||
fmt.Println("Device OpenCL id ", i)
|
|
||||||
fmt.Println("Device id for mining ", len(found))
|
|
||||||
fmt.Println("Device Name ", d.Name())
|
|
||||||
fmt.Println("Vendor ", d.Vendor())
|
|
||||||
fmt.Println("Version ", d.Version())
|
|
||||||
fmt.Println("Driver version ", d.DriverVersion())
|
|
||||||
fmt.Println("Address bits ", d.AddressBits())
|
|
||||||
fmt.Println("Max clock freq ", d.MaxClockFrequency())
|
|
||||||
fmt.Println("Global mem size ", d.GlobalMemSize())
|
|
||||||
fmt.Println("Max constant buffer size", d.MaxConstantBufferSize())
|
|
||||||
fmt.Println("Max mem alloc size ", d.MaxMemAllocSize())
|
|
||||||
fmt.Println("Max compute units ", d.MaxComputeUnits())
|
|
||||||
fmt.Println("Max work group size ", d.MaxWorkGroupSize())
|
|
||||||
fmt.Println("Max work item sizes ", d.MaxWorkItemSizes())
|
|
||||||
fmt.Println("=============================================")
|
|
||||||
|
|
||||||
found = append(found, d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(found) == 0 {
|
|
||||||
fmt.Println("Found no GPU(s). Check that your OS can see the GPU(s)")
|
|
||||||
} else {
|
|
||||||
var idsFormat string
|
|
||||||
for i := 0; i < len(found); i++ {
|
|
||||||
idsFormat += strconv.Itoa(i)
|
|
||||||
if i != len(found)-1 {
|
|
||||||
idsFormat += ","
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fmt.Printf("Found %v devices. Benchmark first GPU: geth gpubench 0\n", len(found))
|
|
||||||
fmt.Printf("Mine using all GPUs: geth --minegpu %v\n", idsFormat)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// See [2]. We basically do the same here, but the Go OpenCL bindings
|
|
||||||
// are at a slightly higher abtraction level.
|
|
||||||
func InitCL(blockNum uint64, c *OpenCLMiner) error {
|
|
||||||
platforms, err := cl.GetPlatforms()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Plaform error: %v\nCheck your OpenCL installation and then run geth gpuinfo", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var devices []*cl.Device
|
|
||||||
for _, p := range platforms {
|
|
||||||
ds, err := cl.GetDevices(p, cl.DeviceTypeGPU)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Devices error: %v\nCheck your GPU drivers and then run geth gpuinfo", err)
|
|
||||||
}
|
|
||||||
for _, d := range ds {
|
|
||||||
devices = append(devices, d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pow := New()
|
|
||||||
_ = pow.getDAG(blockNum) // generates DAG if we don't have it
|
|
||||||
pow.Light.getCache(blockNum) // and cache
|
|
||||||
|
|
||||||
c.ethash = pow
|
|
||||||
dagSize := uint64(C.ethash_get_datasize(C.uint64_t(blockNum)))
|
|
||||||
c.dagSize = dagSize
|
|
||||||
|
|
||||||
for _, id := range c.deviceIds {
|
|
||||||
if id > len(devices)-1 {
|
|
||||||
return fmt.Errorf("Device id not found. See available device ids with: geth gpuinfo")
|
|
||||||
} else {
|
|
||||||
err := initCLDevice(id, devices[id], c)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(c.devices) == 0 {
|
|
||||||
return fmt.Errorf("No GPU devices found")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func initCLDevice(deviceId int, device *cl.Device, c *OpenCLMiner) error {
|
|
||||||
devMaxAlloc := uint64(device.MaxMemAllocSize())
|
|
||||||
devGlobalMem := uint64(device.GlobalMemSize())
|
|
||||||
|
|
||||||
// TODO: more fine grained version logic
|
|
||||||
if device.Version() == "OpenCL 1.0" {
|
|
||||||
fmt.Println("Device OpenCL version not supported: ", device.Version())
|
|
||||||
return fmt.Errorf("opencl version not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
var cl11, cl12 bool
|
|
||||||
if device.Version() == "OpenCL 1.1" {
|
|
||||||
cl11 = true
|
|
||||||
}
|
|
||||||
if device.Version() == "OpenCL 1.2" {
|
|
||||||
cl12 = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// log warnings but carry on; some device drivers report inaccurate values
|
|
||||||
if c.dagSize > devGlobalMem {
|
|
||||||
fmt.Printf("WARNING: device memory may be insufficient: %v. DAG size: %v.\n", devGlobalMem, c.dagSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.dagSize > devMaxAlloc {
|
|
||||||
fmt.Printf("WARNING: DAG size (%v) larger than device max memory allocation size (%v).\n", c.dagSize, devMaxAlloc)
|
|
||||||
fmt.Printf("You probably have to export GPU_MAX_ALLOC_PERCENT=95\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Initialising device %v: %v\n", deviceId, device.Name())
|
|
||||||
|
|
||||||
context, err := cl.CreateContext([]*cl.Device{device})
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed creating context: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: test running with CL_QUEUE_PROFILING_ENABLE for profiling?
|
|
||||||
queue, err := context.CreateCommandQueue(device, 0)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("command queue err: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// See [4] section 3.2 and [3] "clBuildProgram".
|
|
||||||
// The OpenCL kernel code is compiled at run-time.
|
|
||||||
kvs := make(map[string]string, 4)
|
|
||||||
kvs["GROUP_SIZE"] = strconv.FormatUint(workGroupSize, 10)
|
|
||||||
kvs["DAG_SIZE"] = strconv.FormatUint(c.dagSize/ethashMixBytesLen, 10)
|
|
||||||
kvs["ACCESSES"] = strconv.FormatUint(ethashAccesses, 10)
|
|
||||||
kvs["MAX_OUTPUTS"] = strconv.FormatUint(maxSearchResults, 10)
|
|
||||||
kernelCode := replaceWords(kernel, kvs)
|
|
||||||
|
|
||||||
program, err := context.CreateProgramWithSource([]string{kernelCode})
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("program err: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if using AMD OpenCL impl, you can set this to debug on x86 CPU device.
|
|
||||||
see AMD OpenCL programming guide section 4.2
|
|
||||||
|
|
||||||
export in shell before running:
|
|
||||||
export AMD_OCL_BUILD_OPTIONS_APPEND="-g -O0"
|
|
||||||
export CPU_MAX_COMPUTE_UNITS=1
|
|
||||||
|
|
||||||
buildOpts := "-g -cl-opt-disable"
|
|
||||||
|
|
||||||
*/
|
|
||||||
buildOpts := ""
|
|
||||||
err = program.BuildProgram([]*cl.Device{device}, buildOpts)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("program build err: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var searchKernelName, hashKernelName string
|
|
||||||
searchKernelName = "ethash_search"
|
|
||||||
hashKernelName = "ethash_hash"
|
|
||||||
|
|
||||||
searchKernel, err := program.CreateKernel(searchKernelName)
|
|
||||||
hashKernel, err := program.CreateKernel(hashKernelName)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("kernel err: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: when this DAG size appears, patch the Go bindings
|
|
||||||
// (context.go) to work with uint64 as size_t
|
|
||||||
if c.dagSize > math.MaxInt32 {
|
|
||||||
fmt.Println("DAG too large for allocation.")
|
|
||||||
return fmt.Errorf("DAG too large for alloc")
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: patch up Go bindings to work with size_t, will overflow if > maxint32
|
|
||||||
// TODO: fuck. shit's gonna overflow around 2017-06-09 12:17:02
|
|
||||||
dagBuf := *(new(*cl.MemObject))
|
|
||||||
dagBuf, err = context.CreateEmptyBuffer(cl.MemReadOnly, int(c.dagSize))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("allocating dag buf failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// write DAG to device mem
|
|
||||||
dagPtr := unsafe.Pointer(c.ethash.Full.current.ptr.data)
|
|
||||||
_, err = queue.EnqueueWriteBuffer(dagBuf, true, 0, int(c.dagSize), dagPtr, nil)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("writing to dag buf failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
searchBuffers := make([]*cl.MemObject, searchBufSize)
|
|
||||||
for i := 0; i < searchBufSize; i++ {
|
|
||||||
searchBuff, err := context.CreateEmptyBuffer(cl.MemWriteOnly, (1+maxSearchResults)*SIZEOF_UINT32)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("search buffer err: %v", err)
|
|
||||||
}
|
|
||||||
searchBuffers[i] = searchBuff
|
|
||||||
}
|
|
||||||
|
|
||||||
headerBuf, err := context.CreateEmptyBuffer(cl.MemReadOnly, 32)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("header buffer err: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unique, random nonces are crucial for mining efficieny.
|
|
||||||
// While we do not need cryptographically secure PRNG for nonces,
|
|
||||||
// we want to have uniform distribution and minimal repetition of nonces.
|
|
||||||
// We could guarantee strict uniqueness of nonces by generating unique ranges,
|
|
||||||
// but a int64 seed from crypto/rand should be good enough.
|
|
||||||
// we then use math/rand for speed and to avoid draining OS entropy pool
|
|
||||||
seed, err := crand.Int(crand.Reader, big.NewInt(math.MaxInt64))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
nonceRand := mrand.New(mrand.NewSource(seed.Int64()))
|
|
||||||
|
|
||||||
deviceStruct := &OpenCLDevice{
|
|
||||||
deviceId: deviceId,
|
|
||||||
device: device,
|
|
||||||
openCL11: cl11,
|
|
||||||
openCL12: cl12,
|
|
||||||
|
|
||||||
dagBuf: dagBuf,
|
|
||||||
headerBuf: headerBuf,
|
|
||||||
searchBuffers: searchBuffers,
|
|
||||||
|
|
||||||
searchKernel: searchKernel,
|
|
||||||
hashKernel: hashKernel,
|
|
||||||
|
|
||||||
queue: queue,
|
|
||||||
ctx: context,
|
|
||||||
|
|
||||||
workGroupSize: workGroupSize,
|
|
||||||
|
|
||||||
nonceRand: nonceRand,
|
|
||||||
}
|
|
||||||
c.devices = append(c.devices, deviceStruct)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OpenCLMiner) Search(block pow.Block, stop <-chan struct{}, index int) (uint64, []byte) {
|
|
||||||
c.mu.Lock()
|
|
||||||
newDagSize := uint64(C.ethash_get_datasize(C.uint64_t(block.NumberU64())))
|
|
||||||
if newDagSize > c.dagSize {
|
|
||||||
// TODO: clean up buffers from previous DAG?
|
|
||||||
err := InitCL(block.NumberU64(), c)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("OpenCL init error: ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
defer c.mu.Unlock()
|
|
||||||
|
|
||||||
// Avoid unneeded OpenCL initialisation if we received stop while running InitCL
|
|
||||||
select {
|
|
||||||
case <-stop:
|
|
||||||
return 0, []byte{0}
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
headerHash := block.HashNoNonce()
|
|
||||||
diff := block.Difficulty()
|
|
||||||
target256 := new(big.Int).Div(maxUint256, diff)
|
|
||||||
target64 := new(big.Int).Rsh(target256, 192).Uint64()
|
|
||||||
var zero uint32 = 0
|
|
||||||
|
|
||||||
d := c.devices[index]
|
|
||||||
|
|
||||||
_, err := d.queue.EnqueueWriteBuffer(d.headerBuf, false, 0, 32, unsafe.Pointer(&headerHash[0]), nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clEnqueueWriterBuffer : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < searchBufSize; i++ {
|
|
||||||
_, err := d.queue.EnqueueWriteBuffer(d.searchBuffers[i], false, 0, 4, unsafe.Pointer(&zero), nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clEnqueueWriterBuffer : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait for all search buffers to complete
|
|
||||||
err = d.queue.Finish()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clFinish : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = d.searchKernel.SetArg(1, d.headerBuf)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clSetKernelArg : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = d.searchKernel.SetArg(2, d.dagBuf)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clSetKernelArg : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = d.searchKernel.SetArg(4, target64)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clSetKernelArg : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
err = d.searchKernel.SetArg(5, uint32(math.MaxUint32))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clSetKernelArg : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait on this before returning
|
|
||||||
var preReturnEvent *cl.Event
|
|
||||||
if d.openCL12 {
|
|
||||||
preReturnEvent, err = d.ctx.CreateUserEvent()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search create CL user event : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pending := make([]pendingSearch, 0, searchBufSize)
|
|
||||||
var p *pendingSearch
|
|
||||||
searchBufIndex := uint32(0)
|
|
||||||
var checkNonce uint64
|
|
||||||
loops := int64(0)
|
|
||||||
prevHashRate := int32(0)
|
|
||||||
start := time.Now().UnixNano()
|
|
||||||
// we grab a single random nonce and sets this as argument to the kernel search function
|
|
||||||
// the device will then add each local threads gid to the nonce, creating a unique nonce
|
|
||||||
// for each device computing unit executing in parallel
|
|
||||||
initNonce := uint64(d.nonceRand.Int63())
|
|
||||||
for nonce := initNonce; ; nonce += uint64(globalWorkSize) {
|
|
||||||
select {
|
|
||||||
case <-stop:
|
|
||||||
|
|
||||||
/*
|
|
||||||
if d.openCL12 {
|
|
||||||
err = cl.WaitForEvents([]*cl.Event{preReturnEvent})
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search WaitForEvents: ", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
atomic.AddInt32(&c.hashRate, -prevHashRate)
|
|
||||||
return 0, []byte{0}
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loops % (1 << 7)) == 0 {
|
|
||||||
elapsed := time.Now().UnixNano() - start
|
|
||||||
// TODO: verify if this is correct hash rate calculation
|
|
||||||
hashes := (float64(1e9) / float64(elapsed)) * float64(loops*1024*256)
|
|
||||||
hashrateDiff := int32(hashes) - prevHashRate
|
|
||||||
prevHashRate = int32(hashes)
|
|
||||||
atomic.AddInt32(&c.hashRate, hashrateDiff)
|
|
||||||
}
|
|
||||||
loops++
|
|
||||||
|
|
||||||
err = d.searchKernel.SetArg(0, d.searchBuffers[searchBufIndex])
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clSetKernelArg : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
err = d.searchKernel.SetArg(3, nonce)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clSetKernelArg : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
// execute kernel
|
|
||||||
_, err := d.queue.EnqueueNDRangeKernel(
|
|
||||||
d.searchKernel,
|
|
||||||
[]int{0},
|
|
||||||
[]int{globalWorkSize},
|
|
||||||
[]int{d.workGroupSize},
|
|
||||||
nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clEnqueueNDRangeKernel : ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
pending = append(pending, pendingSearch{bufIndex: searchBufIndex, startNonce: nonce})
|
|
||||||
searchBufIndex = (searchBufIndex + 1) % searchBufSize
|
|
||||||
|
|
||||||
if len(pending) == searchBufSize {
|
|
||||||
p = &(pending[searchBufIndex])
|
|
||||||
cres, _, err := d.queue.EnqueueMapBuffer(d.searchBuffers[p.bufIndex], true,
|
|
||||||
cl.MapFlagRead, 0, (1+maxSearchResults)*SIZEOF_UINT32,
|
|
||||||
nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clEnqueueMapBuffer: ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
results := cres.ByteSlice()
|
|
||||||
nfound := binary.LittleEndian.Uint32(results)
|
|
||||||
nfound = uint32(math.Min(float64(nfound), float64(maxSearchResults)))
|
|
||||||
// OpenCL returns the offsets from the start nonce
|
|
||||||
for i := uint32(0); i < nfound; i++ {
|
|
||||||
lo := (i + 1) * SIZEOF_UINT32
|
|
||||||
hi := (i + 2) * SIZEOF_UINT32
|
|
||||||
upperNonce := uint64(binary.LittleEndian.Uint32(results[lo:hi]))
|
|
||||||
checkNonce = p.startNonce + upperNonce
|
|
||||||
if checkNonce != 0 {
|
|
||||||
// We verify that the nonce is indeed a solution by
|
|
||||||
// executing the Ethash verification function (on the CPU).
|
|
||||||
cache := c.ethash.Light.getCache(block.NumberU64())
|
|
||||||
ok, mixDigest, result := cache.compute(c.dagSize, headerHash, checkNonce)
|
|
||||||
|
|
||||||
// TODO: return result first
|
|
||||||
if ok && result.Big().Cmp(target256) <= 0 {
|
|
||||||
_, err = d.queue.EnqueueUnmapMemObject(d.searchBuffers[p.bufIndex], cres, nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clEnqueueUnmapMemObject: ", err)
|
|
||||||
}
|
|
||||||
if d.openCL12 {
|
|
||||||
err = cl.WaitForEvents([]*cl.Event{preReturnEvent})
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search WaitForEvents: ", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return checkNonce, mixDigest.Bytes()
|
|
||||||
}
|
|
||||||
_, err := d.queue.EnqueueWriteBuffer(d.searchBuffers[p.bufIndex], false, 0, 4, unsafe.Pointer(&zero), nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search cl: EnqueueWriteBuffer", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, err = d.queue.EnqueueUnmapMemObject(d.searchBuffers[p.bufIndex], cres, nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clEnqueueUnMapMemObject: ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
pending = append(pending[:searchBufIndex], pending[searchBufIndex+1:]...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if d.openCL12 {
|
|
||||||
err := cl.WaitForEvents([]*cl.Event{preReturnEvent})
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in Search clWaitForEvents: ", err)
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0, []byte{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OpenCLMiner) Verify(block pow.Block) bool {
|
|
||||||
return c.ethash.Light.Verify(block)
|
|
||||||
}
|
|
||||||
func (c *OpenCLMiner) GetHashrate() int64 {
|
|
||||||
return int64(atomic.LoadInt32(&c.hashRate))
|
|
||||||
}
|
|
||||||
func (c *OpenCLMiner) Turbo(on bool) {
|
|
||||||
// This is GPU mining. Always be turbo.
|
|
||||||
}
|
|
||||||
|
|
||||||
func replaceWords(text string, kvs map[string]string) string {
|
|
||||||
for k, v := range kvs {
|
|
||||||
text = strings.Replace(text, k, v, -1)
|
|
||||||
}
|
|
||||||
return text
|
|
||||||
}
|
|
||||||
|
|
||||||
func logErr(err error) {
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error in OpenCL call:", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func argErr(err error) error {
|
|
||||||
return fmt.Errorf("arg err: %v", err)
|
|
||||||
}
|
|
||||||
600
Godeps/_workspace/src/github.com/ethereum/ethash/ethash_opencl_kernel_go_str.go
generated
vendored
600
Godeps/_workspace/src/github.com/ethereum/ethash/ethash_opencl_kernel_go_str.go
generated
vendored
@@ -1,600 +0,0 @@
|
|||||||
package ethash
|
|
||||||
|
|
||||||
/* DO NOT EDIT!!!
|
|
||||||
|
|
||||||
This code is version controlled at
|
|
||||||
https://github.com/ethereum/cpp-ethereum/blob/develop/libethash-cl/ethash_cl_miner_kernel.cl
|
|
||||||
|
|
||||||
If needed change it there first, then copy over here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const kernel = `
|
|
||||||
// author Tim Hughes <tim@twistedfury.com>
|
|
||||||
// Tested on Radeon HD 7850
|
|
||||||
// Hashrate: 15940347 hashes/s
|
|
||||||
// Bandwidth: 124533 MB/s
|
|
||||||
// search kernel should fit in <= 84 VGPRS (3 wavefronts)
|
|
||||||
|
|
||||||
#define THREADS_PER_HASH (128 / 16)
|
|
||||||
#define HASHES_PER_LOOP (GROUP_SIZE / THREADS_PER_HASH)
|
|
||||||
|
|
||||||
#define FNV_PRIME 0x01000193
|
|
||||||
|
|
||||||
__constant uint2 const Keccak_f1600_RC[24] = {
|
|
||||||
(uint2)(0x00000001, 0x00000000),
|
|
||||||
(uint2)(0x00008082, 0x00000000),
|
|
||||||
(uint2)(0x0000808a, 0x80000000),
|
|
||||||
(uint2)(0x80008000, 0x80000000),
|
|
||||||
(uint2)(0x0000808b, 0x00000000),
|
|
||||||
(uint2)(0x80000001, 0x00000000),
|
|
||||||
(uint2)(0x80008081, 0x80000000),
|
|
||||||
(uint2)(0x00008009, 0x80000000),
|
|
||||||
(uint2)(0x0000008a, 0x00000000),
|
|
||||||
(uint2)(0x00000088, 0x00000000),
|
|
||||||
(uint2)(0x80008009, 0x00000000),
|
|
||||||
(uint2)(0x8000000a, 0x00000000),
|
|
||||||
(uint2)(0x8000808b, 0x00000000),
|
|
||||||
(uint2)(0x0000008b, 0x80000000),
|
|
||||||
(uint2)(0x00008089, 0x80000000),
|
|
||||||
(uint2)(0x00008003, 0x80000000),
|
|
||||||
(uint2)(0x00008002, 0x80000000),
|
|
||||||
(uint2)(0x00000080, 0x80000000),
|
|
||||||
(uint2)(0x0000800a, 0x00000000),
|
|
||||||
(uint2)(0x8000000a, 0x80000000),
|
|
||||||
(uint2)(0x80008081, 0x80000000),
|
|
||||||
(uint2)(0x00008080, 0x80000000),
|
|
||||||
(uint2)(0x80000001, 0x00000000),
|
|
||||||
(uint2)(0x80008008, 0x80000000),
|
|
||||||
};
|
|
||||||
|
|
||||||
void keccak_f1600_round(uint2* a, uint r, uint out_size)
|
|
||||||
{
|
|
||||||
#if !__ENDIAN_LITTLE__
|
|
||||||
for (uint i = 0; i != 25; ++i)
|
|
||||||
a[i] = a[i].yx;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint2 b[25];
|
|
||||||
uint2 t;
|
|
||||||
|
|
||||||
// Theta
|
|
||||||
b[0] = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20];
|
|
||||||
b[1] = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21];
|
|
||||||
b[2] = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22];
|
|
||||||
b[3] = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23];
|
|
||||||
b[4] = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24];
|
|
||||||
t = b[4] ^ (uint2)(b[1].x << 1 | b[1].y >> 31, b[1].y << 1 | b[1].x >> 31);
|
|
||||||
a[0] ^= t;
|
|
||||||
a[5] ^= t;
|
|
||||||
a[10] ^= t;
|
|
||||||
a[15] ^= t;
|
|
||||||
a[20] ^= t;
|
|
||||||
t = b[0] ^ (uint2)(b[2].x << 1 | b[2].y >> 31, b[2].y << 1 | b[2].x >> 31);
|
|
||||||
a[1] ^= t;
|
|
||||||
a[6] ^= t;
|
|
||||||
a[11] ^= t;
|
|
||||||
a[16] ^= t;
|
|
||||||
a[21] ^= t;
|
|
||||||
t = b[1] ^ (uint2)(b[3].x << 1 | b[3].y >> 31, b[3].y << 1 | b[3].x >> 31);
|
|
||||||
a[2] ^= t;
|
|
||||||
a[7] ^= t;
|
|
||||||
a[12] ^= t;
|
|
||||||
a[17] ^= t;
|
|
||||||
a[22] ^= t;
|
|
||||||
t = b[2] ^ (uint2)(b[4].x << 1 | b[4].y >> 31, b[4].y << 1 | b[4].x >> 31);
|
|
||||||
a[3] ^= t;
|
|
||||||
a[8] ^= t;
|
|
||||||
a[13] ^= t;
|
|
||||||
a[18] ^= t;
|
|
||||||
a[23] ^= t;
|
|
||||||
t = b[3] ^ (uint2)(b[0].x << 1 | b[0].y >> 31, b[0].y << 1 | b[0].x >> 31);
|
|
||||||
a[4] ^= t;
|
|
||||||
a[9] ^= t;
|
|
||||||
a[14] ^= t;
|
|
||||||
a[19] ^= t;
|
|
||||||
a[24] ^= t;
|
|
||||||
|
|
||||||
// Rho Pi
|
|
||||||
b[0] = a[0];
|
|
||||||
b[10] = (uint2)(a[1].x << 1 | a[1].y >> 31, a[1].y << 1 | a[1].x >> 31);
|
|
||||||
b[7] = (uint2)(a[10].x << 3 | a[10].y >> 29, a[10].y << 3 | a[10].x >> 29);
|
|
||||||
b[11] = (uint2)(a[7].x << 6 | a[7].y >> 26, a[7].y << 6 | a[7].x >> 26);
|
|
||||||
b[17] = (uint2)(a[11].x << 10 | a[11].y >> 22, a[11].y << 10 | a[11].x >> 22);
|
|
||||||
b[18] = (uint2)(a[17].x << 15 | a[17].y >> 17, a[17].y << 15 | a[17].x >> 17);
|
|
||||||
b[3] = (uint2)(a[18].x << 21 | a[18].y >> 11, a[18].y << 21 | a[18].x >> 11);
|
|
||||||
b[5] = (uint2)(a[3].x << 28 | a[3].y >> 4, a[3].y << 28 | a[3].x >> 4);
|
|
||||||
b[16] = (uint2)(a[5].y << 4 | a[5].x >> 28, a[5].x << 4 | a[5].y >> 28);
|
|
||||||
b[8] = (uint2)(a[16].y << 13 | a[16].x >> 19, a[16].x << 13 | a[16].y >> 19);
|
|
||||||
b[21] = (uint2)(a[8].y << 23 | a[8].x >> 9, a[8].x << 23 | a[8].y >> 9);
|
|
||||||
b[24] = (uint2)(a[21].x << 2 | a[21].y >> 30, a[21].y << 2 | a[21].x >> 30);
|
|
||||||
b[4] = (uint2)(a[24].x << 14 | a[24].y >> 18, a[24].y << 14 | a[24].x >> 18);
|
|
||||||
b[15] = (uint2)(a[4].x << 27 | a[4].y >> 5, a[4].y << 27 | a[4].x >> 5);
|
|
||||||
b[23] = (uint2)(a[15].y << 9 | a[15].x >> 23, a[15].x << 9 | a[15].y >> 23);
|
|
||||||
b[19] = (uint2)(a[23].y << 24 | a[23].x >> 8, a[23].x << 24 | a[23].y >> 8);
|
|
||||||
b[13] = (uint2)(a[19].x << 8 | a[19].y >> 24, a[19].y << 8 | a[19].x >> 24);
|
|
||||||
b[12] = (uint2)(a[13].x << 25 | a[13].y >> 7, a[13].y << 25 | a[13].x >> 7);
|
|
||||||
b[2] = (uint2)(a[12].y << 11 | a[12].x >> 21, a[12].x << 11 | a[12].y >> 21);
|
|
||||||
b[20] = (uint2)(a[2].y << 30 | a[2].x >> 2, a[2].x << 30 | a[2].y >> 2);
|
|
||||||
b[14] = (uint2)(a[20].x << 18 | a[20].y >> 14, a[20].y << 18 | a[20].x >> 14);
|
|
||||||
b[22] = (uint2)(a[14].y << 7 | a[14].x >> 25, a[14].x << 7 | a[14].y >> 25);
|
|
||||||
b[9] = (uint2)(a[22].y << 29 | a[22].x >> 3, a[22].x << 29 | a[22].y >> 3);
|
|
||||||
b[6] = (uint2)(a[9].x << 20 | a[9].y >> 12, a[9].y << 20 | a[9].x >> 12);
|
|
||||||
b[1] = (uint2)(a[6].y << 12 | a[6].x >> 20, a[6].x << 12 | a[6].y >> 20);
|
|
||||||
|
|
||||||
// Chi
|
|
||||||
a[0] = bitselect(b[0] ^ b[2], b[0], b[1]);
|
|
||||||
a[1] = bitselect(b[1] ^ b[3], b[1], b[2]);
|
|
||||||
a[2] = bitselect(b[2] ^ b[4], b[2], b[3]);
|
|
||||||
a[3] = bitselect(b[3] ^ b[0], b[3], b[4]);
|
|
||||||
if (out_size >= 4)
|
|
||||||
{
|
|
||||||
a[4] = bitselect(b[4] ^ b[1], b[4], b[0]);
|
|
||||||
a[5] = bitselect(b[5] ^ b[7], b[5], b[6]);
|
|
||||||
a[6] = bitselect(b[6] ^ b[8], b[6], b[7]);
|
|
||||||
a[7] = bitselect(b[7] ^ b[9], b[7], b[8]);
|
|
||||||
a[8] = bitselect(b[8] ^ b[5], b[8], b[9]);
|
|
||||||
if (out_size >= 8)
|
|
||||||
{
|
|
||||||
a[9] = bitselect(b[9] ^ b[6], b[9], b[5]);
|
|
||||||
a[10] = bitselect(b[10] ^ b[12], b[10], b[11]);
|
|
||||||
a[11] = bitselect(b[11] ^ b[13], b[11], b[12]);
|
|
||||||
a[12] = bitselect(b[12] ^ b[14], b[12], b[13]);
|
|
||||||
a[13] = bitselect(b[13] ^ b[10], b[13], b[14]);
|
|
||||||
a[14] = bitselect(b[14] ^ b[11], b[14], b[10]);
|
|
||||||
a[15] = bitselect(b[15] ^ b[17], b[15], b[16]);
|
|
||||||
a[16] = bitselect(b[16] ^ b[18], b[16], b[17]);
|
|
||||||
a[17] = bitselect(b[17] ^ b[19], b[17], b[18]);
|
|
||||||
a[18] = bitselect(b[18] ^ b[15], b[18], b[19]);
|
|
||||||
a[19] = bitselect(b[19] ^ b[16], b[19], b[15]);
|
|
||||||
a[20] = bitselect(b[20] ^ b[22], b[20], b[21]);
|
|
||||||
a[21] = bitselect(b[21] ^ b[23], b[21], b[22]);
|
|
||||||
a[22] = bitselect(b[22] ^ b[24], b[22], b[23]);
|
|
||||||
a[23] = bitselect(b[23] ^ b[20], b[23], b[24]);
|
|
||||||
a[24] = bitselect(b[24] ^ b[21], b[24], b[20]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iota
|
|
||||||
a[0] ^= Keccak_f1600_RC[r];
|
|
||||||
|
|
||||||
#if !__ENDIAN_LITTLE__
|
|
||||||
for (uint i = 0; i != 25; ++i)
|
|
||||||
a[i] = a[i].yx;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void keccak_f1600_no_absorb(ulong* a, uint in_size, uint out_size, uint isolate)
|
|
||||||
{
|
|
||||||
for (uint i = in_size; i != 25; ++i)
|
|
||||||
{
|
|
||||||
a[i] = 0;
|
|
||||||
}
|
|
||||||
#if __ENDIAN_LITTLE__
|
|
||||||
a[in_size] ^= 0x0000000000000001;
|
|
||||||
a[24-out_size*2] ^= 0x8000000000000000;
|
|
||||||
#else
|
|
||||||
a[in_size] ^= 0x0100000000000000;
|
|
||||||
a[24-out_size*2] ^= 0x0000000000000080;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Originally I unrolled the first and last rounds to interface
|
|
||||||
// better with surrounding code, however I haven't done this
|
|
||||||
// without causing the AMD compiler to blow up the VGPR usage.
|
|
||||||
uint r = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// This dynamic branch stops the AMD compiler unrolling the loop
|
|
||||||
// and additionally saves about 33% of the VGPRs, enough to gain another
|
|
||||||
// wavefront. Ideally we'd get 4 in flight, but 3 is the best I can
|
|
||||||
// massage out of the compiler. It doesn't really seem to matter how
|
|
||||||
// much we try and help the compiler save VGPRs because it seems to throw
|
|
||||||
// that information away, hence the implementation of keccak here
|
|
||||||
// doesn't bother.
|
|
||||||
if (isolate)
|
|
||||||
{
|
|
||||||
keccak_f1600_round((uint2*)a, r++, 25);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (r < 23);
|
|
||||||
|
|
||||||
// final round optimised for digest size
|
|
||||||
keccak_f1600_round((uint2*)a, r++, out_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define copy(dst, src, count) for (uint i = 0; i != count; ++i) { (dst)[i] = (src)[i]; }
|
|
||||||
|
|
||||||
#define countof(x) (sizeof(x) / sizeof(x[0]))
|
|
||||||
|
|
||||||
uint fnv(uint x, uint y)
|
|
||||||
{
|
|
||||||
return x * FNV_PRIME ^ y;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint4 fnv4(uint4 x, uint4 y)
|
|
||||||
{
|
|
||||||
return x * FNV_PRIME ^ y;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint fnv_reduce(uint4 v)
|
|
||||||
{
|
|
||||||
return fnv(fnv(fnv(v.x, v.y), v.z), v.w);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef union
|
|
||||||
{
|
|
||||||
ulong ulongs[32 / sizeof(ulong)];
|
|
||||||
uint uints[32 / sizeof(uint)];
|
|
||||||
} hash32_t;
|
|
||||||
|
|
||||||
typedef union
|
|
||||||
{
|
|
||||||
ulong ulongs[64 / sizeof(ulong)];
|
|
||||||
uint4 uint4s[64 / sizeof(uint4)];
|
|
||||||
} hash64_t;
|
|
||||||
|
|
||||||
typedef union
|
|
||||||
{
|
|
||||||
uint uints[128 / sizeof(uint)];
|
|
||||||
uint4 uint4s[128 / sizeof(uint4)];
|
|
||||||
} hash128_t;
|
|
||||||
|
|
||||||
hash64_t init_hash(__constant hash32_t const* header, ulong nonce, uint isolate)
|
|
||||||
{
|
|
||||||
hash64_t init;
|
|
||||||
uint const init_size = countof(init.ulongs);
|
|
||||||
uint const hash_size = countof(header->ulongs);
|
|
||||||
|
|
||||||
// sha3_512(header .. nonce)
|
|
||||||
ulong state[25];
|
|
||||||
copy(state, header->ulongs, hash_size);
|
|
||||||
state[hash_size] = nonce;
|
|
||||||
keccak_f1600_no_absorb(state, hash_size + 1, init_size, isolate);
|
|
||||||
|
|
||||||
copy(init.ulongs, state, init_size);
|
|
||||||
return init;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint inner_loop_chunks(uint4 init, uint thread_id, __local uint* share, __global hash128_t const* g_dag, __global hash128_t const* g_dag1, __global hash128_t const* g_dag2, __global hash128_t const* g_dag3, uint isolate)
|
|
||||||
{
|
|
||||||
uint4 mix = init;
|
|
||||||
|
|
||||||
// share init0
|
|
||||||
if (thread_id == 0)
|
|
||||||
*share = mix.x;
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
uint init0 = *share;
|
|
||||||
|
|
||||||
uint a = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
bool update_share = thread_id == (a/4) % THREADS_PER_HASH;
|
|
||||||
|
|
||||||
#pragma unroll
|
|
||||||
for (uint i = 0; i != 4; ++i)
|
|
||||||
{
|
|
||||||
if (update_share)
|
|
||||||
{
|
|
||||||
uint m[4] = { mix.x, mix.y, mix.z, mix.w };
|
|
||||||
*share = fnv(init0 ^ (a+i), m[i]) % DAG_SIZE;
|
|
||||||
}
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
|
|
||||||
mix = fnv4(mix, *share>=3 * DAG_SIZE / 4 ? g_dag3[*share - 3 * DAG_SIZE / 4].uint4s[thread_id] : *share>=DAG_SIZE / 2 ? g_dag2[*share - DAG_SIZE / 2].uint4s[thread_id] : *share>=DAG_SIZE / 4 ? g_dag1[*share - DAG_SIZE / 4].uint4s[thread_id]:g_dag[*share].uint4s[thread_id]);
|
|
||||||
}
|
|
||||||
} while ((a += 4) != (ACCESSES & isolate));
|
|
||||||
|
|
||||||
return fnv_reduce(mix);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint inner_loop(uint4 init, uint thread_id, __local uint* share, __global hash128_t const* g_dag, uint isolate)
|
|
||||||
{
|
|
||||||
uint4 mix = init;
|
|
||||||
|
|
||||||
// share init0
|
|
||||||
if (thread_id == 0)
|
|
||||||
*share = mix.x;
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
uint init0 = *share;
|
|
||||||
|
|
||||||
uint a = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
bool update_share = thread_id == (a/4) % THREADS_PER_HASH;
|
|
||||||
|
|
||||||
#pragma unroll
|
|
||||||
for (uint i = 0; i != 4; ++i)
|
|
||||||
{
|
|
||||||
if (update_share)
|
|
||||||
{
|
|
||||||
uint m[4] = { mix.x, mix.y, mix.z, mix.w };
|
|
||||||
*share = fnv(init0 ^ (a+i), m[i]) % DAG_SIZE;
|
|
||||||
}
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
|
|
||||||
mix = fnv4(mix, g_dag[*share].uint4s[thread_id]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while ((a += 4) != (ACCESSES & isolate));
|
|
||||||
|
|
||||||
return fnv_reduce(mix);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
hash32_t final_hash(hash64_t const* init, hash32_t const* mix, uint isolate)
|
|
||||||
{
|
|
||||||
ulong state[25];
|
|
||||||
|
|
||||||
hash32_t hash;
|
|
||||||
uint const hash_size = countof(hash.ulongs);
|
|
||||||
uint const init_size = countof(init->ulongs);
|
|
||||||
uint const mix_size = countof(mix->ulongs);
|
|
||||||
|
|
||||||
// keccak_256(keccak_512(header..nonce) .. mix);
|
|
||||||
copy(state, init->ulongs, init_size);
|
|
||||||
copy(state + init_size, mix->ulongs, mix_size);
|
|
||||||
keccak_f1600_no_absorb(state, init_size+mix_size, hash_size, isolate);
|
|
||||||
|
|
||||||
// copy out
|
|
||||||
copy(hash.ulongs, state, hash_size);
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
hash32_t compute_hash_simple(
|
|
||||||
__constant hash32_t const* g_header,
|
|
||||||
__global hash128_t const* g_dag,
|
|
||||||
ulong nonce,
|
|
||||||
uint isolate
|
|
||||||
)
|
|
||||||
{
|
|
||||||
hash64_t init = init_hash(g_header, nonce, isolate);
|
|
||||||
|
|
||||||
hash128_t mix;
|
|
||||||
for (uint i = 0; i != countof(mix.uint4s); ++i)
|
|
||||||
{
|
|
||||||
mix.uint4s[i] = init.uint4s[i % countof(init.uint4s)];
|
|
||||||
}
|
|
||||||
|
|
||||||
uint mix_val = mix.uints[0];
|
|
||||||
uint init0 = mix.uints[0];
|
|
||||||
uint a = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
uint pi = fnv(init0 ^ a, mix_val) % DAG_SIZE;
|
|
||||||
uint n = (a+1) % countof(mix.uints);
|
|
||||||
|
|
||||||
#pragma unroll
|
|
||||||
for (uint i = 0; i != countof(mix.uints); ++i)
|
|
||||||
{
|
|
||||||
mix.uints[i] = fnv(mix.uints[i], g_dag[pi].uints[i]);
|
|
||||||
mix_val = i == n ? mix.uints[i] : mix_val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (++a != (ACCESSES & isolate));
|
|
||||||
|
|
||||||
// reduce to output
|
|
||||||
hash32_t fnv_mix;
|
|
||||||
for (uint i = 0; i != countof(fnv_mix.uints); ++i)
|
|
||||||
{
|
|
||||||
fnv_mix.uints[i] = fnv_reduce(mix.uint4s[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return final_hash(&init, &fnv_mix, isolate);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
hash64_t init;
|
|
||||||
uint pad; // avoid lds bank conflicts
|
|
||||||
};
|
|
||||||
hash32_t mix;
|
|
||||||
} compute_hash_share;
|
|
||||||
|
|
||||||
|
|
||||||
hash32_t compute_hash(
|
|
||||||
__local compute_hash_share* share,
|
|
||||||
__constant hash32_t const* g_header,
|
|
||||||
__global hash128_t const* g_dag,
|
|
||||||
ulong nonce,
|
|
||||||
uint isolate
|
|
||||||
)
|
|
||||||
{
|
|
||||||
uint const gid = get_global_id(0);
|
|
||||||
|
|
||||||
// Compute one init hash per work item.
|
|
||||||
hash64_t init = init_hash(g_header, nonce, isolate);
|
|
||||||
|
|
||||||
// Threads work together in this phase in groups of 8.
|
|
||||||
uint const thread_id = gid % THREADS_PER_HASH;
|
|
||||||
uint const hash_id = (gid % GROUP_SIZE) / THREADS_PER_HASH;
|
|
||||||
|
|
||||||
hash32_t mix;
|
|
||||||
uint i = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// share init with other threads
|
|
||||||
if (i == thread_id)
|
|
||||||
share[hash_id].init = init;
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
|
|
||||||
uint4 thread_init = share[hash_id].init.uint4s[thread_id % (64 / sizeof(uint4))];
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
|
|
||||||
uint thread_mix = inner_loop(thread_init, thread_id, share[hash_id].mix.uints, g_dag, isolate);
|
|
||||||
|
|
||||||
share[hash_id].mix.uints[thread_id] = thread_mix;
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
|
|
||||||
if (i == thread_id)
|
|
||||||
mix = share[hash_id].mix;
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
}
|
|
||||||
while (++i != (THREADS_PER_HASH & isolate));
|
|
||||||
|
|
||||||
return final_hash(&init, &mix, isolate);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
hash32_t compute_hash_chunks(
|
|
||||||
__local compute_hash_share* share,
|
|
||||||
__constant hash32_t const* g_header,
|
|
||||||
__global hash128_t const* g_dag,
|
|
||||||
__global hash128_t const* g_dag1,
|
|
||||||
__global hash128_t const* g_dag2,
|
|
||||||
__global hash128_t const* g_dag3,
|
|
||||||
ulong nonce,
|
|
||||||
uint isolate
|
|
||||||
)
|
|
||||||
{
|
|
||||||
uint const gid = get_global_id(0);
|
|
||||||
|
|
||||||
// Compute one init hash per work item.
|
|
||||||
hash64_t init = init_hash(g_header, nonce, isolate);
|
|
||||||
|
|
||||||
// Threads work together in this phase in groups of 8.
|
|
||||||
uint const thread_id = gid % THREADS_PER_HASH;
|
|
||||||
uint const hash_id = (gid % GROUP_SIZE) / THREADS_PER_HASH;
|
|
||||||
|
|
||||||
hash32_t mix;
|
|
||||||
uint i = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// share init with other threads
|
|
||||||
if (i == thread_id)
|
|
||||||
share[hash_id].init = init;
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
|
|
||||||
uint4 thread_init = share[hash_id].init.uint4s[thread_id % (64 / sizeof(uint4))];
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
|
|
||||||
uint thread_mix = inner_loop_chunks(thread_init, thread_id, share[hash_id].mix.uints, g_dag, g_dag1, g_dag2, g_dag3, isolate);
|
|
||||||
|
|
||||||
share[hash_id].mix.uints[thread_id] = thread_mix;
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
|
|
||||||
if (i == thread_id)
|
|
||||||
mix = share[hash_id].mix;
|
|
||||||
barrier(CLK_LOCAL_MEM_FENCE);
|
|
||||||
}
|
|
||||||
while (++i != (THREADS_PER_HASH & isolate));
|
|
||||||
|
|
||||||
return final_hash(&init, &mix, isolate);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((reqd_work_group_size(GROUP_SIZE, 1, 1)))
|
|
||||||
__kernel void ethash_hash_simple(
|
|
||||||
__global hash32_t* g_hashes,
|
|
||||||
__constant hash32_t const* g_header,
|
|
||||||
__global hash128_t const* g_dag,
|
|
||||||
ulong start_nonce,
|
|
||||||
uint isolate
|
|
||||||
)
|
|
||||||
{
|
|
||||||
uint const gid = get_global_id(0);
|
|
||||||
g_hashes[gid] = compute_hash_simple(g_header, g_dag, start_nonce + gid, isolate);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((reqd_work_group_size(GROUP_SIZE, 1, 1)))
|
|
||||||
__kernel void ethash_search_simple(
|
|
||||||
__global volatile uint* restrict g_output,
|
|
||||||
__constant hash32_t const* g_header,
|
|
||||||
__global hash128_t const* g_dag,
|
|
||||||
ulong start_nonce,
|
|
||||||
ulong target,
|
|
||||||
uint isolate
|
|
||||||
)
|
|
||||||
{
|
|
||||||
uint const gid = get_global_id(0);
|
|
||||||
hash32_t hash = compute_hash_simple(g_header, g_dag, start_nonce + gid, isolate);
|
|
||||||
|
|
||||||
if (hash.ulongs[countof(hash.ulongs)-1] < target)
|
|
||||||
{
|
|
||||||
uint slot = min(convert_uint(MAX_OUTPUTS), convert_uint(atomic_inc(&g_output[0]) + 1));
|
|
||||||
g_output[slot] = gid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
__attribute__((reqd_work_group_size(GROUP_SIZE, 1, 1)))
|
|
||||||
__kernel void ethash_hash(
|
|
||||||
__global hash32_t* g_hashes,
|
|
||||||
__constant hash32_t const* g_header,
|
|
||||||
__global hash128_t const* g_dag,
|
|
||||||
ulong start_nonce,
|
|
||||||
uint isolate
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__local compute_hash_share share[HASHES_PER_LOOP];
|
|
||||||
|
|
||||||
uint const gid = get_global_id(0);
|
|
||||||
g_hashes[gid] = compute_hash(share, g_header, g_dag, start_nonce + gid, isolate);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((reqd_work_group_size(GROUP_SIZE, 1, 1)))
|
|
||||||
__kernel void ethash_search(
|
|
||||||
__global volatile uint* restrict g_output,
|
|
||||||
__constant hash32_t const* g_header,
|
|
||||||
__global hash128_t const* g_dag,
|
|
||||||
ulong start_nonce,
|
|
||||||
ulong target,
|
|
||||||
uint isolate
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__local compute_hash_share share[HASHES_PER_LOOP];
|
|
||||||
|
|
||||||
uint const gid = get_global_id(0);
|
|
||||||
hash32_t hash = compute_hash(share, g_header, g_dag, start_nonce + gid, isolate);
|
|
||||||
|
|
||||||
if (as_ulong(as_uchar8(hash.ulongs[0]).s76543210) < target)
|
|
||||||
{
|
|
||||||
uint slot = min((uint)MAX_OUTPUTS, atomic_inc(&g_output[0]) + 1);
|
|
||||||
g_output[slot] = gid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((reqd_work_group_size(GROUP_SIZE, 1, 1)))
|
|
||||||
__kernel void ethash_hash_chunks(
|
|
||||||
__global hash32_t* g_hashes,
|
|
||||||
__constant hash32_t const* g_header,
|
|
||||||
__global hash128_t const* g_dag,
|
|
||||||
__global hash128_t const* g_dag1,
|
|
||||||
__global hash128_t const* g_dag2,
|
|
||||||
__global hash128_t const* g_dag3,
|
|
||||||
ulong start_nonce,
|
|
||||||
uint isolate
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__local compute_hash_share share[HASHES_PER_LOOP];
|
|
||||||
|
|
||||||
uint const gid = get_global_id(0);
|
|
||||||
g_hashes[gid] = compute_hash_chunks(share, g_header, g_dag, g_dag1, g_dag2, g_dag3,start_nonce + gid, isolate);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((reqd_work_group_size(GROUP_SIZE, 1, 1)))
|
|
||||||
__kernel void ethash_search_chunks(
|
|
||||||
__global volatile uint* restrict g_output,
|
|
||||||
__constant hash32_t const* g_header,
|
|
||||||
__global hash128_t const* g_dag,
|
|
||||||
__global hash128_t const* g_dag1,
|
|
||||||
__global hash128_t const* g_dag2,
|
|
||||||
__global hash128_t const* g_dag3,
|
|
||||||
ulong start_nonce,
|
|
||||||
ulong target,
|
|
||||||
uint isolate
|
|
||||||
)
|
|
||||||
{
|
|
||||||
__local compute_hash_share share[HASHES_PER_LOOP];
|
|
||||||
|
|
||||||
uint const gid = get_global_id(0);
|
|
||||||
hash32_t hash = compute_hash_chunks(share, g_header, g_dag, g_dag1, g_dag2, g_dag3, start_nonce + gid, isolate);
|
|
||||||
|
|
||||||
if (as_ulong(as_uchar8(hash.ulongs[0]).s76543210) < target)
|
|
||||||
{
|
|
||||||
uint slot = min(convert_uint(MAX_OUTPUTS), convert_uint(atomic_inc(&g_output[0]) + 1));
|
|
||||||
g_output[slot] = gid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
51
Godeps/_workspace/src/github.com/ethereum/ethash/ethashc.go
generated
vendored
51
Godeps/_workspace/src/github.com/ethereum/ethash/ethashc.go
generated
vendored
@@ -1,51 +0,0 @@
|
|||||||
// Copyright 2015 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package ethash
|
|
||||||
|
|
||||||
/*
|
|
||||||
-mno-stack-arg-probe disables stack probing which avoids the function
|
|
||||||
__chkstk_ms being linked. this avoids a clash of this symbol as we also
|
|
||||||
separately link the secp256k1 lib which ends up defining this symbol
|
|
||||||
|
|
||||||
1. https://gcc.gnu.org/onlinedocs/gccint/Stack-Checking.html
|
|
||||||
2. https://groups.google.com/forum/#!msg/golang-dev/v1bziURSQ4k/88fXuJ24e-gJ
|
|
||||||
3. https://groups.google.com/forum/#!topic/golang-nuts/VNP6Mwz_B6o
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
#cgo CFLAGS: -std=gnu99 -Wall
|
|
||||||
#cgo windows CFLAGS: -mno-stack-arg-probe
|
|
||||||
#cgo LDFLAGS: -lm
|
|
||||||
|
|
||||||
#include "src/libethash/internal.c"
|
|
||||||
#include "src/libethash/sha3.c"
|
|
||||||
#include "src/libethash/io.c"
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
# include "src/libethash/io_win32.c"
|
|
||||||
# include "src/libethash/mmap_win32.c"
|
|
||||||
#else
|
|
||||||
# include "src/libethash/io_posix.c"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 'gateway function' for calling back into go.
|
|
||||||
extern int ethashGoCallback(unsigned);
|
|
||||||
int ethashGoCallback_cgo(unsigned percent) { return ethashGoCallback(percent); }
|
|
||||||
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
47
Godeps/_workspace/src/github.com/ethereum/ethash/setup.py
generated
vendored
47
Godeps/_workspace/src/github.com/ethereum/ethash/setup.py
generated
vendored
@@ -1,47 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
import os
|
|
||||||
from distutils.core import setup, Extension
|
|
||||||
sources = [
|
|
||||||
'src/python/core.c',
|
|
||||||
'src/libethash/io.c',
|
|
||||||
'src/libethash/internal.c',
|
|
||||||
'src/libethash/sha3.c']
|
|
||||||
if os.name == 'nt':
|
|
||||||
sources += [
|
|
||||||
'src/libethash/util_win32.c',
|
|
||||||
'src/libethash/io_win32.c',
|
|
||||||
'src/libethash/mmap_win32.c',
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
sources += [
|
|
||||||
'src/libethash/io_posix.c'
|
|
||||||
]
|
|
||||||
depends = [
|
|
||||||
'src/libethash/ethash.h',
|
|
||||||
'src/libethash/compiler.h',
|
|
||||||
'src/libethash/data_sizes.h',
|
|
||||||
'src/libethash/endian.h',
|
|
||||||
'src/libethash/ethash.h',
|
|
||||||
'src/libethash/io.h',
|
|
||||||
'src/libethash/fnv.h',
|
|
||||||
'src/libethash/internal.h',
|
|
||||||
'src/libethash/sha3.h',
|
|
||||||
'src/libethash/util.h',
|
|
||||||
]
|
|
||||||
pyethash = Extension('pyethash',
|
|
||||||
sources=sources,
|
|
||||||
depends=depends,
|
|
||||||
extra_compile_args=["-Isrc/", "-std=gnu99", "-Wall"])
|
|
||||||
|
|
||||||
setup(
|
|
||||||
name='pyethash',
|
|
||||||
author="Matthew Wampler-Doty",
|
|
||||||
author_email="matthew.wampler.doty@gmail.com",
|
|
||||||
license='GPL',
|
|
||||||
version='0.1.23',
|
|
||||||
url='https://github.com/ethereum/ethash',
|
|
||||||
download_url='https://github.com/ethereum/ethash/tarball/v23',
|
|
||||||
description=('Python wrappers for ethash, the ethereum proof of work'
|
|
||||||
'hashing function'),
|
|
||||||
ext_modules=[pyethash],
|
|
||||||
)
|
|
||||||
3
Godeps/_workspace/src/github.com/fatih/color/.travis.yml
generated
vendored
3
Godeps/_workspace/src/github.com/fatih/color/.travis.yml
generated
vendored
@@ -1,3 +0,0 @@
|
|||||||
language: go
|
|
||||||
go: 1.3
|
|
||||||
|
|
||||||
25
Godeps/_workspace/src/github.com/gizak/termui/.gitignore
generated
vendored
25
Godeps/_workspace/src/github.com/gizak/termui/.gitignore
generated
vendored
@@ -1,25 +0,0 @@
|
|||||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
|
||||||
*.o
|
|
||||||
*.a
|
|
||||||
*.so
|
|
||||||
|
|
||||||
# Folders
|
|
||||||
_obj
|
|
||||||
_test
|
|
||||||
|
|
||||||
# Architecture specific extensions/prefixes
|
|
||||||
*.[568vq]
|
|
||||||
[568vq].out
|
|
||||||
|
|
||||||
*.cgo1.go
|
|
||||||
*.cgo2.c
|
|
||||||
_cgo_defun.c
|
|
||||||
_cgo_gotypes.go
|
|
||||||
_cgo_export.*
|
|
||||||
|
|
||||||
_testmain.go
|
|
||||||
|
|
||||||
*.exe
|
|
||||||
*.test
|
|
||||||
*.prof
|
|
||||||
.DS_Store
|
|
||||||
6
Godeps/_workspace/src/github.com/gizak/termui/.travis.yml
generated
vendored
6
Godeps/_workspace/src/github.com/gizak/termui/.travis.yml
generated
vendored
@@ -1,6 +0,0 @@
|
|||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- tip
|
|
||||||
|
|
||||||
script: go test -v ./
|
|
||||||
26
Godeps/_workspace/src/github.com/gizak/termui/config
generated
vendored
26
Godeps/_workspace/src/github.com/gizak/termui/config
generated
vendored
@@ -1,26 +0,0 @@
|
|||||||
#!/usr/bin/env perl6
|
|
||||||
|
|
||||||
use v6;
|
|
||||||
|
|
||||||
my $copyright = '// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
';
|
|
||||||
|
|
||||||
sub MAIN('update-docstr', Str $srcp) {
|
|
||||||
if $srcp.IO.f {
|
|
||||||
$_ = $srcp.IO.slurp;
|
|
||||||
if m/^ \/\/\s Copyright .+? \n\n/ {
|
|
||||||
unless ~$/ eq $copyright {
|
|
||||||
s/^ \/\/\s Copyright .+? \n\n /$copyright/;
|
|
||||||
spurt $srcp, $_;
|
|
||||||
say "[updated] doc string for:"~$srcp;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
say "[added] doc string for "~$srcp~" (no match found)";
|
|
||||||
$_ = $copyright ~ $_;
|
|
||||||
spurt $srcp, $_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
117
Godeps/_workspace/src/github.com/gizak/termui/debug/debuger.go
generated
vendored
117
Godeps/_workspace/src/github.com/gizak/termui/debug/debuger.go
generated
vendored
@@ -1,117 +0,0 @@
|
|||||||
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
package debug
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"golang.org/x/net/websocket"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Server struct {
|
|
||||||
Port string
|
|
||||||
Addr string
|
|
||||||
Path string
|
|
||||||
Msg chan string
|
|
||||||
chs []chan string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Client struct {
|
|
||||||
Port string
|
|
||||||
Addr string
|
|
||||||
Path string
|
|
||||||
ws *websocket.Conn
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultPort = ":8080"
|
|
||||||
|
|
||||||
func NewServer() *Server {
|
|
||||||
return &Server{
|
|
||||||
Port: defaultPort,
|
|
||||||
Addr: "localhost",
|
|
||||||
Path: "/echo",
|
|
||||||
Msg: make(chan string),
|
|
||||||
chs: make([]chan string, 0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewClient() Client {
|
|
||||||
return Client{
|
|
||||||
Port: defaultPort,
|
|
||||||
Addr: "localhost",
|
|
||||||
Path: "/echo",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c Client) ConnectAndListen() error {
|
|
||||||
ws, err := websocket.Dial("ws://"+c.Addr+c.Port+c.Path, "", "http://"+c.Addr)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer ws.Close()
|
|
||||||
|
|
||||||
var m string
|
|
||||||
for {
|
|
||||||
err := websocket.Message.Receive(ws, &m)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Print(err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Print(m)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) ListenAndServe() error {
|
|
||||||
http.Handle(s.Path, websocket.Handler(func(ws *websocket.Conn) {
|
|
||||||
defer ws.Close()
|
|
||||||
|
|
||||||
mc := make(chan string)
|
|
||||||
s.chs = append(s.chs, mc)
|
|
||||||
|
|
||||||
for m := range mc {
|
|
||||||
websocket.Message.Send(ws, m)
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
for msg := range s.Msg {
|
|
||||||
for _, c := range s.chs {
|
|
||||||
go func(a chan string) {
|
|
||||||
a <- msg
|
|
||||||
}(c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return http.ListenAndServe(s.Port, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) Log(msg string) {
|
|
||||||
go func() { s.Msg <- msg }()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) Logf(format string, a ...interface{}) {
|
|
||||||
s.Log(fmt.Sprintf(format, a...))
|
|
||||||
}
|
|
||||||
|
|
||||||
var DefaultServer = NewServer()
|
|
||||||
var DefaultClient = NewClient()
|
|
||||||
|
|
||||||
func ListenAndServe() error {
|
|
||||||
return DefaultServer.ListenAndServe()
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConnectAndListen() error {
|
|
||||||
return DefaultClient.ConnectAndListen()
|
|
||||||
}
|
|
||||||
|
|
||||||
func Log(msg string) {
|
|
||||||
DefaultServer.Log(msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Logf(format string, a ...interface{}) {
|
|
||||||
DefaultServer.Logf(format, a...)
|
|
||||||
}
|
|
||||||
66
Godeps/_workspace/src/github.com/gizak/termui/test/runtest.go
generated
vendored
66
Godeps/_workspace/src/github.com/gizak/termui/test/runtest.go
generated
vendored
@@ -1,66 +0,0 @@
|
|||||||
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/gizak/termui"
|
|
||||||
"github.com/gizak/termui/debug"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// run as client
|
|
||||||
if len(os.Args) > 1 {
|
|
||||||
fmt.Print(debug.ConnectAndListen())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// run as server
|
|
||||||
go func() { panic(debug.ListenAndServe()) }()
|
|
||||||
|
|
||||||
if err := termui.Init(); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer termui.Close()
|
|
||||||
|
|
||||||
//termui.UseTheme("helloworld")
|
|
||||||
b := termui.NewBlock()
|
|
||||||
b.Width = 20
|
|
||||||
b.Height = 20
|
|
||||||
b.Float = termui.AlignCenter
|
|
||||||
b.BorderLabel = "[HELLO](fg-red,bg-white) [WORLD](fg-blue,bg-green)"
|
|
||||||
|
|
||||||
termui.Render(b)
|
|
||||||
|
|
||||||
termui.Handle("/sys", func(e termui.Event) {
|
|
||||||
k, ok := e.Data.(termui.EvtKbd)
|
|
||||||
debug.Logf("->%v\n", e)
|
|
||||||
if ok && k.KeyStr == "q" {
|
|
||||||
termui.StopLoop()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
termui.Handle(("/usr"), func(e termui.Event) {
|
|
||||||
debug.Logf("->%v\n", e)
|
|
||||||
})
|
|
||||||
|
|
||||||
termui.Handle("/timer/1s", func(e termui.Event) {
|
|
||||||
t := e.Data.(termui.EvtTimer)
|
|
||||||
termui.SendCustomEvt("/usr/t", t.Count)
|
|
||||||
|
|
||||||
if t.Count%2 == 0 {
|
|
||||||
b.BorderLabel = "[HELLO](fg-red,bg-green) [WORLD](fg-blue,bg-white)"
|
|
||||||
} else {
|
|
||||||
b.BorderLabel = "[HELLO](fg-blue,bg-white) [WORLD](fg-red,bg-green)"
|
|
||||||
}
|
|
||||||
|
|
||||||
termui.Render(b)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
termui.Loop()
|
|
||||||
}
|
|
||||||
7
Godeps/_workspace/src/github.com/golang/snappy/README
generated
vendored
7
Godeps/_workspace/src/github.com/golang/snappy/README
generated
vendored
@@ -1,7 +0,0 @@
|
|||||||
The Snappy compression format in the Go programming language.
|
|
||||||
|
|
||||||
To download and install from source:
|
|
||||||
$ go get github.com/golang/snappy
|
|
||||||
|
|
||||||
Unless otherwise noted, the Snappy-Go source files are distributed
|
|
||||||
under the BSD-style license found in the LICENSE file.
|
|
||||||
1
Godeps/_workspace/src/github.com/huin/goupnp/.gitignore
generated
vendored
1
Godeps/_workspace/src/github.com/huin/goupnp/.gitignore
generated
vendored
@@ -1 +0,0 @@
|
|||||||
/gotasks/specs
|
|
||||||
44
Godeps/_workspace/src/github.com/huin/goupnp/README.md
generated
vendored
44
Godeps/_workspace/src/github.com/huin/goupnp/README.md
generated
vendored
@@ -1,44 +0,0 @@
|
|||||||
goupnp is a UPnP client library for Go
|
|
||||||
|
|
||||||
Installation
|
|
||||||
------------
|
|
||||||
|
|
||||||
Run `go get -u github.com/huin/goupnp`.
|
|
||||||
|
|
||||||
Documentation
|
|
||||||
-------------
|
|
||||||
|
|
||||||
All doc links below are for .
|
|
||||||
|
|
||||||
Supported DCPs (you probably want to start with one of these):
|
|
||||||
* [av1](https://godoc.org/github.com/huin/goupnp/dcps/av1) - Client for UPnP Device Control Protocol MediaServer v1 and MediaRenderer v1.
|
|
||||||
* [internetgateway1](https://godoc.org/github.com/huin/goupnp/dcps/internetgateway1) - Client for UPnP Device Control Protocol Internet Gateway Device v1.
|
|
||||||
* [internetgateway2](https://godoc.org/github.com/huin/goupnp/dcps/internetgateway2) - Client for UPnP Device Control Protocol Internet Gateway Device v2.
|
|
||||||
|
|
||||||
Core components:
|
|
||||||
* [(goupnp)](https://godoc.org/github.com/huin/goupnp) core library - contains datastructures and utilities typically used by the implemented DCPs.
|
|
||||||
* [httpu](https://godoc.org/github.com/huin/goupnp/httpu) HTTPU implementation, underlies SSDP.
|
|
||||||
* [ssdp](https://godoc.org/github.com/huin/goupnp/ssdp) SSDP client implementation (simple service discovery protocol) - used to discover UPnP services on a network.
|
|
||||||
* [soap](https://godoc.org/github.com/huin/goupnp/soap) SOAP client implementation (simple object access protocol) - used to communicate with discovered services.
|
|
||||||
|
|
||||||
|
|
||||||
Regenerating dcps generated source code:
|
|
||||||
----------------------------------------
|
|
||||||
|
|
||||||
1. Install gotasks: `go get -u github.com/jingweno/gotask`
|
|
||||||
2. Change to the gotasks directory: `cd gotasks`
|
|
||||||
3. Run specgen task: `gotask specgen`
|
|
||||||
|
|
||||||
Supporting additional UPnP devices and services:
|
|
||||||
------------------------------------------------
|
|
||||||
|
|
||||||
Supporting additional services is, in the trivial case, simply a matter of
|
|
||||||
adding the service to the `dcpMetadata` whitelist in `gotasks/specgen_task.go`,
|
|
||||||
regenerating the source code (see above), and committing that source code.
|
|
||||||
|
|
||||||
However, it would be helpful if anyone needing such a service could test the
|
|
||||||
service against the service they have, and then reporting any trouble
|
|
||||||
encountered as an [issue on this
|
|
||||||
project](https://github.com/huin/goupnp/issues/new). If it just works, then
|
|
||||||
please report at least minimal working functionality as an issue, and
|
|
||||||
optionally contribute the metadata upstream.
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/huin/goupnp/httpu"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
srv := httpu.Server{
|
|
||||||
Addr: "239.255.255.250:1900",
|
|
||||||
Multicast: true,
|
|
||||||
Handler: httpu.HandlerFunc(func(r *http.Request) {
|
|
||||||
log.Printf("Got %s %s message from %v: %v", r.Method, r.URL.Path, r.RemoteAddr, r.Header)
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
err := srv.ListenAndServe()
|
|
||||||
log.Printf("Serving failed with error: %v", err)
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/huin/goupnp/dcps/internetgateway1"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
clients, errors, err := internetgateway1.NewWANPPPConnection1Clients()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Got %d errors finding servers and %d successfully discovered.\n",
|
|
||||||
len(errors), len(clients))
|
|
||||||
for i, e := range errors {
|
|
||||||
fmt.Printf("Error finding server #%d: %v\n", i+1, e)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, c := range clients {
|
|
||||||
dev := &c.ServiceClient.RootDevice.Device
|
|
||||||
srv := c.ServiceClient.Service
|
|
||||||
fmt.Println(dev.FriendlyName, " :: ", srv.String())
|
|
||||||
scpd, err := srv.RequestSCDP()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf(" Error requesting service SCPD: %v\n", err)
|
|
||||||
} else {
|
|
||||||
fmt.Println(" Available actions:")
|
|
||||||
for _, action := range scpd.Actions {
|
|
||||||
fmt.Printf(" * %s\n", action.Name)
|
|
||||||
for _, arg := range action.Arguments {
|
|
||||||
var varDesc string
|
|
||||||
if stateVar := scpd.GetStateVariable(arg.RelatedStateVariable); stateVar != nil {
|
|
||||||
varDesc = fmt.Sprintf(" (%s)", stateVar.DataType.Name)
|
|
||||||
}
|
|
||||||
fmt.Printf(" * [%s] %s%s\n", arg.Direction, arg.Name, varDesc)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if scpd == nil || scpd.GetAction("GetExternalIPAddress") != nil {
|
|
||||||
ip, err := c.GetExternalIPAddress()
|
|
||||||
fmt.Println("GetExternalIPAddress: ", ip, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if scpd == nil || scpd.GetAction("GetStatusInfo") != nil {
|
|
||||||
status, lastErr, uptime, err := c.GetStatusInfo()
|
|
||||||
fmt.Println("GetStatusInfo: ", status, lastErr, uptime, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if scpd == nil || scpd.GetAction("GetIdleDisconnectTime") != nil {
|
|
||||||
idleTime, err := c.GetIdleDisconnectTime()
|
|
||||||
fmt.Println("GetIdleDisconnectTime: ", idleTime, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if scpd == nil || scpd.GetAction("AddPortMapping") != nil {
|
|
||||||
err := c.AddPortMapping("", 5000, "TCP", 5001, "192.168.1.2", true, "Test port mapping", 0)
|
|
||||||
fmt.Println("AddPortMapping: ", err)
|
|
||||||
}
|
|
||||||
if scpd == nil || scpd.GetAction("DeletePortMapping") != nil {
|
|
||||||
err := c.DeletePortMapping("", 5000, "TCP")
|
|
||||||
fmt.Println("DeletePortMapping: ", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/huin/goupnp/ssdp"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
c := make(chan ssdp.Update)
|
|
||||||
srv, reg := ssdp.NewServerAndRegistry()
|
|
||||||
reg.AddListener(c)
|
|
||||||
go listener(c)
|
|
||||||
if err := srv.ListenAndServe(); err != nil {
|
|
||||||
log.Print("ListenAndServe failed: ", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func listener(c <-chan ssdp.Update) {
|
|
||||||
for u := range c {
|
|
||||||
if u.Entry != nil {
|
|
||||||
log.Printf("Event: %v USN: %s Entry: %#v", u.EventType, u.USN, *u.Entry)
|
|
||||||
} else {
|
|
||||||
log.Printf("Event: %v USN: %s Entry: <nil>", u.EventType, u.USN)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
8452
Godeps/_workspace/src/github.com/huin/goupnp/dcps/av1/av1.go
generated
vendored
8452
Godeps/_workspace/src/github.com/huin/goupnp/dcps/av1/av1.go
generated
vendored
File diff suppressed because it is too large
Load Diff
6
Godeps/_workspace/src/github.com/huin/goupnp/example/example.go
generated
vendored
6
Godeps/_workspace/src/github.com/huin/goupnp/example/example.go
generated
vendored
@@ -1,6 +0,0 @@
|
|||||||
// Serves as examples of using the goupnp library.
|
|
||||||
//
|
|
||||||
// To run examples and see the output for your local network, run the following
|
|
||||||
// command (specifically including the -v flag):
|
|
||||||
// go test -v github.com/huin/goupnp/example
|
|
||||||
package example
|
|
||||||
603
Godeps/_workspace/src/github.com/huin/goupnp/gotasks/specgen_task.go
generated
vendored
603
Godeps/_workspace/src/github.com/huin/goupnp/gotasks/specgen_task.go
generated
vendored
@@ -1,603 +0,0 @@
|
|||||||
// +build gotask
|
|
||||||
|
|
||||||
package gotasks
|
|
||||||
|
|
||||||
import (
|
|
||||||
"archive/zip"
|
|
||||||
"encoding/xml"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
"text/template"
|
|
||||||
|
|
||||||
"github.com/huin/goupnp"
|
|
||||||
"github.com/huin/goupnp/scpd"
|
|
||||||
"github.com/huin/goutil/codegen"
|
|
||||||
"github.com/jingweno/gotask/tasking"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
deviceURNPrefix = "urn:schemas-upnp-org:device:"
|
|
||||||
serviceURNPrefix = "urn:schemas-upnp-org:service:"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DCP contains extra metadata to use when generating DCP source files.
|
|
||||||
type DCPMetadata struct {
|
|
||||||
Name string // What to name the Go DCP package.
|
|
||||||
OfficialName string // Official name for the DCP.
|
|
||||||
DocURL string // Optional - URL for futher documentation about the DCP.
|
|
||||||
XMLSpecURL string // Where to download the XML spec from.
|
|
||||||
// Any special-case functions to run against the DCP before writing it out.
|
|
||||||
Hacks []DCPHackFn
|
|
||||||
}
|
|
||||||
|
|
||||||
var dcpMetadata = []DCPMetadata{
|
|
||||||
{
|
|
||||||
Name: "internetgateway1",
|
|
||||||
OfficialName: "Internet Gateway Device v1",
|
|
||||||
DocURL: "http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf",
|
|
||||||
XMLSpecURL: "http://upnp.org/specs/gw/UPnP-gw-IGD-TestFiles-20010921.zip",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "internetgateway2",
|
|
||||||
OfficialName: "Internet Gateway Device v2",
|
|
||||||
DocURL: "http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v2-Device.pdf",
|
|
||||||
XMLSpecURL: "http://upnp.org/specs/gw/UPnP-gw-IGD-Testfiles-20110224.zip",
|
|
||||||
Hacks: []DCPHackFn{
|
|
||||||
func(dcp *DCP) error {
|
|
||||||
missingURN := "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1"
|
|
||||||
if _, ok := dcp.ServiceTypes[missingURN]; ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
urnParts, err := extractURNParts(missingURN, serviceURNPrefix)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dcp.ServiceTypes[missingURN] = urnParts
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "av1",
|
|
||||||
OfficialName: "MediaServer v1 and MediaRenderer v1",
|
|
||||||
DocURL: "http://upnp.org/specs/av/av1/",
|
|
||||||
XMLSpecURL: "http://upnp.org/specs/av/UPnP-av-TestFiles-20070927.zip",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
type DCPHackFn func(*DCP) error
|
|
||||||
|
|
||||||
// NAME
|
|
||||||
// specgen - generates Go code from the UPnP specification files.
|
|
||||||
//
|
|
||||||
// DESCRIPTION
|
|
||||||
// The specification is available for download from:
|
|
||||||
//
|
|
||||||
// OPTIONS
|
|
||||||
// -s, --specs_dir=<spec directory>
|
|
||||||
// Path to the specification storage directory. This is used to find (and download if not present) the specification ZIP files. Defaults to 'specs'
|
|
||||||
// -o, --out_dir=<output directory>
|
|
||||||
// Path to the output directory. This is is where the DCP source files will be placed. Should normally correspond to the directory for github.com/huin/goupnp/dcps. Defaults to '../dcps'
|
|
||||||
// --nogofmt
|
|
||||||
// Disable passing the output through gofmt. Do this if debugging code output problems and needing to see the generated code prior to being passed through gofmt.
|
|
||||||
func TaskSpecgen(t *tasking.T) {
|
|
||||||
specsDir := fallbackStrValue("specs", t.Flags.String("specs_dir"), t.Flags.String("s"))
|
|
||||||
if err := os.MkdirAll(specsDir, os.ModePerm); err != nil {
|
|
||||||
t.Fatalf("Could not create specs-dir %q: %v\n", specsDir, err)
|
|
||||||
}
|
|
||||||
outDir := fallbackStrValue("../dcps", t.Flags.String("out_dir"), t.Flags.String("o"))
|
|
||||||
useGofmt := !t.Flags.Bool("nogofmt")
|
|
||||||
|
|
||||||
NEXT_DCP:
|
|
||||||
for _, d := range dcpMetadata {
|
|
||||||
specFilename := filepath.Join(specsDir, d.Name+".zip")
|
|
||||||
err := acquireFile(specFilename, d.XMLSpecURL)
|
|
||||||
if err != nil {
|
|
||||||
t.Logf("Could not acquire spec for %s, skipping: %v\n", d.Name, err)
|
|
||||||
continue NEXT_DCP
|
|
||||||
}
|
|
||||||
dcp := newDCP(d)
|
|
||||||
if err := dcp.processZipFile(specFilename); err != nil {
|
|
||||||
log.Printf("Error processing spec for %s in file %q: %v", d.Name, specFilename, err)
|
|
||||||
continue NEXT_DCP
|
|
||||||
}
|
|
||||||
for i, hack := range d.Hacks {
|
|
||||||
if err := hack(dcp); err != nil {
|
|
||||||
log.Printf("Error with Hack[%d] for %s: %v", i, d.Name, err)
|
|
||||||
continue NEXT_DCP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dcp.writePackage(outDir, useGofmt)
|
|
||||||
if err := dcp.writePackage(outDir, useGofmt); err != nil {
|
|
||||||
log.Printf("Error writing package %q: %v", dcp.Metadata.Name, err)
|
|
||||||
continue NEXT_DCP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func fallbackStrValue(defaultValue string, values ...string) string {
|
|
||||||
for _, v := range values {
|
|
||||||
if v != "" {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
|
|
||||||
func acquireFile(specFilename string, xmlSpecURL string) error {
|
|
||||||
if f, err := os.Open(specFilename); err != nil {
|
|
||||||
if !os.IsNotExist(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
f.Close()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := http.Get(xmlSpecURL)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return fmt.Errorf("could not download spec %q from %q: ",
|
|
||||||
specFilename, xmlSpecURL, resp.Status)
|
|
||||||
}
|
|
||||||
|
|
||||||
tmpFilename := specFilename + ".download"
|
|
||||||
w, err := os.Create(tmpFilename)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer w.Close()
|
|
||||||
|
|
||||||
_, err = io.Copy(w, resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return os.Rename(tmpFilename, specFilename)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DCP collects together information about a UPnP Device Control Protocol.
|
|
||||||
type DCP struct {
|
|
||||||
Metadata DCPMetadata
|
|
||||||
DeviceTypes map[string]*URNParts
|
|
||||||
ServiceTypes map[string]*URNParts
|
|
||||||
Services []SCPDWithURN
|
|
||||||
}
|
|
||||||
|
|
||||||
func newDCP(metadata DCPMetadata) *DCP {
|
|
||||||
return &DCP{
|
|
||||||
Metadata: metadata,
|
|
||||||
DeviceTypes: make(map[string]*URNParts),
|
|
||||||
ServiceTypes: make(map[string]*URNParts),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dcp *DCP) processZipFile(filename string) error {
|
|
||||||
archive, err := zip.OpenReader(filename)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error reading zip file %q: %v", filename, err)
|
|
||||||
}
|
|
||||||
defer archive.Close()
|
|
||||||
for _, deviceFile := range globFiles("*/device/*.xml", archive) {
|
|
||||||
if err := dcp.processDeviceFile(deviceFile); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, scpdFile := range globFiles("*/service/*.xml", archive) {
|
|
||||||
if err := dcp.processSCPDFile(scpdFile); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dcp *DCP) processDeviceFile(file *zip.File) error {
|
|
||||||
var device goupnp.Device
|
|
||||||
if err := unmarshalXmlFile(file, &device); err != nil {
|
|
||||||
return fmt.Errorf("error decoding device XML from file %q: %v", file.Name, err)
|
|
||||||
}
|
|
||||||
var mainErr error
|
|
||||||
device.VisitDevices(func(d *goupnp.Device) {
|
|
||||||
t := strings.TrimSpace(d.DeviceType)
|
|
||||||
if t != "" {
|
|
||||||
u, err := extractURNParts(t, deviceURNPrefix)
|
|
||||||
if err != nil {
|
|
||||||
mainErr = err
|
|
||||||
}
|
|
||||||
dcp.DeviceTypes[t] = u
|
|
||||||
}
|
|
||||||
})
|
|
||||||
device.VisitServices(func(s *goupnp.Service) {
|
|
||||||
u, err := extractURNParts(s.ServiceType, serviceURNPrefix)
|
|
||||||
if err != nil {
|
|
||||||
mainErr = err
|
|
||||||
}
|
|
||||||
dcp.ServiceTypes[s.ServiceType] = u
|
|
||||||
})
|
|
||||||
return mainErr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dcp *DCP) writePackage(outDir string, useGofmt bool) error {
|
|
||||||
packageDirname := filepath.Join(outDir, dcp.Metadata.Name)
|
|
||||||
err := os.MkdirAll(packageDirname, os.ModePerm)
|
|
||||||
if err != nil && !os.IsExist(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
packageFilename := filepath.Join(packageDirname, dcp.Metadata.Name+".go")
|
|
||||||
packageFile, err := os.Create(packageFilename)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var output io.WriteCloser = packageFile
|
|
||||||
if useGofmt {
|
|
||||||
if output, err = codegen.NewGofmtWriteCloser(output); err != nil {
|
|
||||||
packageFile.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err = packageTmpl.Execute(output, dcp); err != nil {
|
|
||||||
output.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return output.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dcp *DCP) processSCPDFile(file *zip.File) error {
|
|
||||||
scpd := new(scpd.SCPD)
|
|
||||||
if err := unmarshalXmlFile(file, scpd); err != nil {
|
|
||||||
return fmt.Errorf("error decoding SCPD XML from file %q: %v", file.Name, err)
|
|
||||||
}
|
|
||||||
scpd.Clean()
|
|
||||||
urnParts, err := urnPartsFromSCPDFilename(file.Name)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not recognize SCPD filename %q: %v", file.Name, err)
|
|
||||||
}
|
|
||||||
dcp.Services = append(dcp.Services, SCPDWithURN{
|
|
||||||
URNParts: urnParts,
|
|
||||||
SCPD: scpd,
|
|
||||||
})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type SCPDWithURN struct {
|
|
||||||
*URNParts
|
|
||||||
SCPD *scpd.SCPD
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SCPDWithURN) WrapArguments(args []*scpd.Argument) (argumentWrapperList, error) {
|
|
||||||
wrappedArgs := make(argumentWrapperList, len(args))
|
|
||||||
for i, arg := range args {
|
|
||||||
wa, err := s.wrapArgument(arg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
wrappedArgs[i] = wa
|
|
||||||
}
|
|
||||||
return wrappedArgs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SCPDWithURN) wrapArgument(arg *scpd.Argument) (*argumentWrapper, error) {
|
|
||||||
relVar := s.SCPD.GetStateVariable(arg.RelatedStateVariable)
|
|
||||||
if relVar == nil {
|
|
||||||
return nil, fmt.Errorf("no such state variable: %q, for argument %q", arg.RelatedStateVariable, arg.Name)
|
|
||||||
}
|
|
||||||
cnv, ok := typeConvs[relVar.DataType.Name]
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("unknown data type: %q, for state variable %q, for argument %q", relVar.DataType.Type, arg.RelatedStateVariable, arg.Name)
|
|
||||||
}
|
|
||||||
return &argumentWrapper{
|
|
||||||
Argument: *arg,
|
|
||||||
relVar: relVar,
|
|
||||||
conv: cnv,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type argumentWrapper struct {
|
|
||||||
scpd.Argument
|
|
||||||
relVar *scpd.StateVariable
|
|
||||||
conv conv
|
|
||||||
}
|
|
||||||
|
|
||||||
func (arg *argumentWrapper) AsParameter() string {
|
|
||||||
return fmt.Sprintf("%s %s", arg.Name, arg.conv.ExtType)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (arg *argumentWrapper) HasDoc() bool {
|
|
||||||
rng := arg.relVar.AllowedValueRange
|
|
||||||
return ((rng != nil && (rng.Minimum != "" || rng.Maximum != "" || rng.Step != "")) ||
|
|
||||||
len(arg.relVar.AllowedValues) > 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (arg *argumentWrapper) Document() string {
|
|
||||||
relVar := arg.relVar
|
|
||||||
if rng := relVar.AllowedValueRange; rng != nil {
|
|
||||||
var parts []string
|
|
||||||
if rng.Minimum != "" {
|
|
||||||
parts = append(parts, fmt.Sprintf("minimum=%s", rng.Minimum))
|
|
||||||
}
|
|
||||||
if rng.Maximum != "" {
|
|
||||||
parts = append(parts, fmt.Sprintf("maximum=%s", rng.Maximum))
|
|
||||||
}
|
|
||||||
if rng.Step != "" {
|
|
||||||
parts = append(parts, fmt.Sprintf("step=%s", rng.Step))
|
|
||||||
}
|
|
||||||
return "allowed value range: " + strings.Join(parts, ", ")
|
|
||||||
}
|
|
||||||
if len(relVar.AllowedValues) != 0 {
|
|
||||||
return "allowed values: " + strings.Join(relVar.AllowedValues, ", ")
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (arg *argumentWrapper) Marshal() string {
|
|
||||||
return fmt.Sprintf("soap.Marshal%s(%s)", arg.conv.FuncSuffix, arg.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (arg *argumentWrapper) Unmarshal(objVar string) string {
|
|
||||||
return fmt.Sprintf("soap.Unmarshal%s(%s.%s)", arg.conv.FuncSuffix, objVar, arg.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
type argumentWrapperList []*argumentWrapper
|
|
||||||
|
|
||||||
func (args argumentWrapperList) HasDoc() bool {
|
|
||||||
for _, arg := range args {
|
|
||||||
if arg.HasDoc() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
type conv struct {
|
|
||||||
FuncSuffix string
|
|
||||||
ExtType string
|
|
||||||
}
|
|
||||||
|
|
||||||
// typeConvs maps from a SOAP type (e.g "fixed.14.4") to the function name
|
|
||||||
// suffix inside the soap module (e.g "Fixed14_4") and the Go type.
|
|
||||||
var typeConvs = map[string]conv{
|
|
||||||
"ui1": conv{"Ui1", "uint8"},
|
|
||||||
"ui2": conv{"Ui2", "uint16"},
|
|
||||||
"ui4": conv{"Ui4", "uint32"},
|
|
||||||
"i1": conv{"I1", "int8"},
|
|
||||||
"i2": conv{"I2", "int16"},
|
|
||||||
"i4": conv{"I4", "int32"},
|
|
||||||
"int": conv{"Int", "int64"},
|
|
||||||
"r4": conv{"R4", "float32"},
|
|
||||||
"r8": conv{"R8", "float64"},
|
|
||||||
"number": conv{"R8", "float64"}, // Alias for r8.
|
|
||||||
"fixed.14.4": conv{"Fixed14_4", "float64"},
|
|
||||||
"float": conv{"R8", "float64"},
|
|
||||||
"char": conv{"Char", "rune"},
|
|
||||||
"string": conv{"String", "string"},
|
|
||||||
"date": conv{"Date", "time.Time"},
|
|
||||||
"dateTime": conv{"DateTime", "time.Time"},
|
|
||||||
"dateTime.tz": conv{"DateTimeTz", "time.Time"},
|
|
||||||
"time": conv{"TimeOfDay", "soap.TimeOfDay"},
|
|
||||||
"time.tz": conv{"TimeOfDayTz", "soap.TimeOfDay"},
|
|
||||||
"boolean": conv{"Boolean", "bool"},
|
|
||||||
"bin.base64": conv{"BinBase64", "[]byte"},
|
|
||||||
"bin.hex": conv{"BinHex", "[]byte"},
|
|
||||||
"uri": conv{"URI", "*url.URL"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func globFiles(pattern string, archive *zip.ReadCloser) []*zip.File {
|
|
||||||
var files []*zip.File
|
|
||||||
for _, f := range archive.File {
|
|
||||||
if matched, err := path.Match(pattern, f.Name); err != nil {
|
|
||||||
// This shouldn't happen - all patterns are hard-coded, errors in them
|
|
||||||
// are a programming error.
|
|
||||||
panic(err)
|
|
||||||
} else if matched {
|
|
||||||
files = append(files, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return files
|
|
||||||
}
|
|
||||||
|
|
||||||
func unmarshalXmlFile(file *zip.File, data interface{}) error {
|
|
||||||
r, err := file.Open()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
decoder := xml.NewDecoder(r)
|
|
||||||
r.Close()
|
|
||||||
return decoder.Decode(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
type URNParts struct {
|
|
||||||
URN string
|
|
||||||
Name string
|
|
||||||
Version string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *URNParts) Const() string {
|
|
||||||
return fmt.Sprintf("URN_%s_%s", u.Name, u.Version)
|
|
||||||
}
|
|
||||||
|
|
||||||
// extractURNParts extracts the name and version from a URN string.
|
|
||||||
func extractURNParts(urn, expectedPrefix string) (*URNParts, error) {
|
|
||||||
if !strings.HasPrefix(urn, expectedPrefix) {
|
|
||||||
return nil, fmt.Errorf("%q does not have expected prefix %q", urn, expectedPrefix)
|
|
||||||
}
|
|
||||||
parts := strings.SplitN(strings.TrimPrefix(urn, expectedPrefix), ":", 2)
|
|
||||||
if len(parts) != 2 {
|
|
||||||
return nil, fmt.Errorf("%q does not have a name and version", urn)
|
|
||||||
}
|
|
||||||
name, version := parts[0], parts[1]
|
|
||||||
return &URNParts{urn, name, version}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var scpdFilenameRe = regexp.MustCompile(
|
|
||||||
`.*/([a-zA-Z0-9]+)([0-9]+)\.xml`)
|
|
||||||
|
|
||||||
func urnPartsFromSCPDFilename(filename string) (*URNParts, error) {
|
|
||||||
parts := scpdFilenameRe.FindStringSubmatch(filename)
|
|
||||||
if len(parts) != 3 {
|
|
||||||
return nil, fmt.Errorf("SCPD filename %q does not have expected number of parts", filename)
|
|
||||||
}
|
|
||||||
name, version := parts[1], parts[2]
|
|
||||||
return &URNParts{
|
|
||||||
URN: serviceURNPrefix + name + ":" + version,
|
|
||||||
Name: name,
|
|
||||||
Version: version,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var packageTmpl = template.Must(template.New("package").Parse(`{{$name := .Metadata.Name}}
|
|
||||||
// Client for UPnP Device Control Protocol {{.Metadata.OfficialName}}.
|
|
||||||
// {{if .Metadata.DocURL}}
|
|
||||||
// This DCP is documented in detail at: {{.Metadata.DocURL}}{{end}}
|
|
||||||
//
|
|
||||||
// Typically, use one of the New* functions to create clients for services.
|
|
||||||
package {{$name}}
|
|
||||||
|
|
||||||
// Generated file - do not edit by hand. See README.md
|
|
||||||
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/url"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/huin/goupnp"
|
|
||||||
"github.com/huin/goupnp/soap"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Hack to avoid Go complaining if time isn't used.
|
|
||||||
var _ time.Time
|
|
||||||
|
|
||||||
// Device URNs:
|
|
||||||
const ({{range .DeviceTypes}}
|
|
||||||
{{.Const}} = "{{.URN}}"{{end}}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Service URNs:
|
|
||||||
const ({{range .ServiceTypes}}
|
|
||||||
{{.Const}} = "{{.URN}}"{{end}}
|
|
||||||
)
|
|
||||||
|
|
||||||
{{range .Services}}
|
|
||||||
{{$srv := .}}
|
|
||||||
{{$srvIdent := printf "%s%s" .Name .Version}}
|
|
||||||
|
|
||||||
// {{$srvIdent}} is a client for UPnP SOAP service with URN "{{.URN}}". See
|
|
||||||
// goupnp.ServiceClient, which contains RootDevice and Service attributes which
|
|
||||||
// are provided for informational value.
|
|
||||||
type {{$srvIdent}} struct {
|
|
||||||
goupnp.ServiceClient
|
|
||||||
}
|
|
||||||
|
|
||||||
// New{{$srvIdent}}Clients discovers instances of the service on the network,
|
|
||||||
// and returns clients to any that are found. errors will contain an error for
|
|
||||||
// any devices that replied but which could not be queried, and err will be set
|
|
||||||
// if the discovery process failed outright.
|
|
||||||
//
|
|
||||||
// This is a typical entry calling point into this package.
|
|
||||||
func New{{$srvIdent}}Clients() (clients []*{{$srvIdent}}, errors []error, err error) {
|
|
||||||
var genericClients []goupnp.ServiceClient
|
|
||||||
if genericClients, errors, err = goupnp.NewServiceClients({{$srv.Const}}); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
clients = new{{$srvIdent}}ClientsFromGenericClients(genericClients)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// New{{$srvIdent}}ClientsByURL discovers instances of the service at the given
|
|
||||||
// URL, and returns clients to any that are found. An error is returned if
|
|
||||||
// there was an error probing the service.
|
|
||||||
//
|
|
||||||
// This is a typical entry calling point into this package when reusing an
|
|
||||||
// previously discovered service URL.
|
|
||||||
func New{{$srvIdent}}ClientsByURL(loc *url.URL) ([]*{{$srvIdent}}, error) {
|
|
||||||
genericClients, err := goupnp.NewServiceClientsByURL(loc, {{$srv.Const}})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return new{{$srvIdent}}ClientsFromGenericClients(genericClients), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// New{{$srvIdent}}ClientsFromRootDevice discovers instances of the service in
|
|
||||||
// a given root device, and returns clients to any that are found. An error is
|
|
||||||
// returned if there was not at least one instance of the service within the
|
|
||||||
// device. The location parameter is simply assigned to the Location attribute
|
|
||||||
// of the wrapped ServiceClient(s).
|
|
||||||
//
|
|
||||||
// This is a typical entry calling point into this package when reusing an
|
|
||||||
// previously discovered root device.
|
|
||||||
func New{{$srvIdent}}ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*{{$srvIdent}}, error) {
|
|
||||||
genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, {{$srv.Const}})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return new{{$srvIdent}}ClientsFromGenericClients(genericClients), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func new{{$srvIdent}}ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*{{$srvIdent}} {
|
|
||||||
clients := make([]*{{$srvIdent}}, len(genericClients))
|
|
||||||
for i := range genericClients {
|
|
||||||
clients[i] = &{{$srvIdent}}{genericClients[i]}
|
|
||||||
}
|
|
||||||
return clients
|
|
||||||
}
|
|
||||||
|
|
||||||
{{range .SCPD.Actions}}{{/* loops over *SCPDWithURN values */}}
|
|
||||||
|
|
||||||
{{$winargs := $srv.WrapArguments .InputArguments}}
|
|
||||||
{{$woutargs := $srv.WrapArguments .OutputArguments}}
|
|
||||||
{{if $winargs.HasDoc}}
|
|
||||||
//
|
|
||||||
// Arguments:{{range $winargs}}{{if .HasDoc}}
|
|
||||||
//
|
|
||||||
// * {{.Name}}: {{.Document}}{{end}}{{end}}{{end}}
|
|
||||||
{{if $woutargs.HasDoc}}
|
|
||||||
//
|
|
||||||
// Return values:{{range $woutargs}}{{if .HasDoc}}
|
|
||||||
//
|
|
||||||
// * {{.Name}}: {{.Document}}{{end}}{{end}}{{end}}
|
|
||||||
func (client *{{$srvIdent}}) {{.Name}}({{range $winargs}}{{/*
|
|
||||||
*/}}{{.AsParameter}}, {{end}}{{/*
|
|
||||||
*/}}) ({{range $woutargs}}{{/*
|
|
||||||
*/}}{{.AsParameter}}, {{end}} err error) {
|
|
||||||
// Request structure.
|
|
||||||
request := {{if $winargs}}&{{template "argstruct" $winargs}}{{"{}"}}{{else}}{{"interface{}(nil)"}}{{end}}
|
|
||||||
// BEGIN Marshal arguments into request.
|
|
||||||
{{range $winargs}}
|
|
||||||
if request.{{.Name}}, err = {{.Marshal}}; err != nil {
|
|
||||||
return
|
|
||||||
}{{end}}
|
|
||||||
// END Marshal arguments into request.
|
|
||||||
|
|
||||||
// Response structure.
|
|
||||||
response := {{if $woutargs}}&{{template "argstruct" $woutargs}}{{"{}"}}{{else}}{{"interface{}(nil)"}}{{end}}
|
|
||||||
|
|
||||||
// Perform the SOAP call.
|
|
||||||
if err = client.SOAPClient.PerformAction({{$srv.URNParts.Const}}, "{{.Name}}", request, response); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// BEGIN Unmarshal arguments from response.
|
|
||||||
{{range $woutargs}}
|
|
||||||
if {{.Name}}, err = {{.Unmarshal "response"}}; err != nil {
|
|
||||||
return
|
|
||||||
}{{end}}
|
|
||||||
// END Unmarshal arguments from response.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
{{end}}{{/* range .SCPD.Actions */}}
|
|
||||||
{{end}}{{/* range .Services */}}
|
|
||||||
|
|
||||||
{{define "argstruct"}}struct {{"{"}}{{range .}}
|
|
||||||
{{.Name}} string
|
|
||||||
{{end}}{{"}"}}{{end}}
|
|
||||||
`))
|
|
||||||
27
Godeps/_workspace/src/github.com/jackpal/gateway/LICENSE
generated
vendored
27
Godeps/_workspace/src/github.com/jackpal/gateway/LICENSE
generated
vendored
@@ -1,27 +0,0 @@
|
|||||||
// Copyright (c) 2010 Jack Palevich. All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are
|
|
||||||
// met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following disclaimer
|
|
||||||
// in the documentation and/or other materials provided with the
|
|
||||||
// distribution.
|
|
||||||
// * Neither the name of Google Inc. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived from
|
|
||||||
// this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
7
Godeps/_workspace/src/github.com/jackpal/gateway/README.md
generated
vendored
7
Godeps/_workspace/src/github.com/jackpal/gateway/README.md
generated
vendored
@@ -1,7 +0,0 @@
|
|||||||
# gateway
|
|
||||||
|
|
||||||
A very simple library for discovering the IP address of the local LAN gateway.
|
|
||||||
|
|
||||||
Provides implementations for Linux, OS X (Darwin) and Windows.
|
|
||||||
|
|
||||||
Pull requests for other OSs happily considered!
|
|
||||||
40
Godeps/_workspace/src/github.com/jackpal/gateway/gateway_darwin.go
generated
vendored
40
Godeps/_workspace/src/github.com/jackpal/gateway/gateway_darwin.go
generated
vendored
@@ -1,40 +0,0 @@
|
|||||||
package gateway
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"os/exec"
|
|
||||||
)
|
|
||||||
|
|
||||||
func DiscoverGateway() (ip net.IP, err error) {
|
|
||||||
routeCmd := exec.Command("route", "-n", "get", "0.0.0.0")
|
|
||||||
stdOut, err := routeCmd.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = routeCmd.Start(); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
output, err := ioutil.ReadAll(stdOut)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Darwin route out format is always like this:
|
|
||||||
// route to: default
|
|
||||||
// destination: default
|
|
||||||
// mask: default
|
|
||||||
// gateway: 192.168.1.1
|
|
||||||
outputLines := bytes.Split(output, []byte("\n"))
|
|
||||||
for _, line := range outputLines {
|
|
||||||
if bytes.Contains(line, []byte("gateway:")) {
|
|
||||||
gatewayFields := bytes.Fields(line)
|
|
||||||
ip = net.ParseIP(string(gatewayFields[1]))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = routeCmd.Wait()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
75
Godeps/_workspace/src/github.com/jackpal/gateway/gateway_linux.go
generated
vendored
75
Godeps/_workspace/src/github.com/jackpal/gateway/gateway_linux.go
generated
vendored
@@ -1,75 +0,0 @@
|
|||||||
package gateway
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"os/exec"
|
|
||||||
)
|
|
||||||
|
|
||||||
func discoverGatewayUsingIp() (ip net.IP, err error) {
|
|
||||||
routeCmd := exec.Command("ip", "route", "show")
|
|
||||||
stdOut, err := routeCmd.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = routeCmd.Start(); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
output, err := ioutil.ReadAll(stdOut)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Linux 'ip route show' format looks like this:
|
|
||||||
// default via 192.168.178.1 dev wlp3s0 metric 303
|
|
||||||
// 192.168.178.0/24 dev wlp3s0 proto kernel scope link src 192.168.178.76 metric 303
|
|
||||||
outputLines := bytes.Split(output, []byte("\n"))
|
|
||||||
for _, line := range outputLines {
|
|
||||||
if bytes.Contains(line, []byte("default")) {
|
|
||||||
ipFields := bytes.Fields(line)
|
|
||||||
ip = net.ParseIP(string(ipFields[2]))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = routeCmd.Wait()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func discoverGatewayUsingRoute() (ip net.IP, err error) {
|
|
||||||
routeCmd := exec.Command("route", "-n")
|
|
||||||
stdOut, err := routeCmd.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = routeCmd.Start(); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
output, err := ioutil.ReadAll(stdOut)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Linux route out format is always like this:
|
|
||||||
// Kernel IP routing table
|
|
||||||
// Destination Gateway Genmask Flags Metric Ref Use Iface
|
|
||||||
// 0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
|
|
||||||
outputLines := bytes.Split(output, []byte("\n"))
|
|
||||||
for _, line := range outputLines {
|
|
||||||
if bytes.Contains(line, []byte("0.0.0.0")) {
|
|
||||||
ipFields := bytes.Fields(line)
|
|
||||||
ip = net.ParseIP(string(ipFields[1]))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = routeCmd.Wait()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func DiscoverGateway() (ip net.IP, err error) {
|
|
||||||
ip, err = discoverGatewayUsingRoute()
|
|
||||||
if err != nil {
|
|
||||||
ip, err = discoverGatewayUsingIp()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
14
Godeps/_workspace/src/github.com/jackpal/gateway/gateway_unimplemented.go
generated
vendored
14
Godeps/_workspace/src/github.com/jackpal/gateway/gateway_unimplemented.go
generated
vendored
@@ -1,14 +0,0 @@
|
|||||||
// +build !darwin,!linux,!windows
|
|
||||||
|
|
||||||
package gateway
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
func DiscoverGateway() (ip net.IP, err error) {
|
|
||||||
err = fmt.Errorf("DiscoverGateway not implemented for OS %s", runtime.GOOS)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
43
Godeps/_workspace/src/github.com/jackpal/gateway/gateway_windows.go
generated
vendored
43
Godeps/_workspace/src/github.com/jackpal/gateway/gateway_windows.go
generated
vendored
@@ -1,43 +0,0 @@
|
|||||||
package gateway
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"os/exec"
|
|
||||||
)
|
|
||||||
|
|
||||||
func DiscoverGateway() (ip net.IP, err error) {
|
|
||||||
routeCmd := exec.Command("route", "print", "0.0.0.0")
|
|
||||||
stdOut, err := routeCmd.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = routeCmd.Start(); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
output, err := ioutil.ReadAll(stdOut)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Windows route output format is always like this:
|
|
||||||
// ===========================================================================
|
|
||||||
// Active Routes:
|
|
||||||
// Network Destination Netmask Gateway Interface Metric
|
|
||||||
// 0.0.0.0 0.0.0.0 192.168.1.1 192.168.1.100 20
|
|
||||||
// ===========================================================================
|
|
||||||
// I'm trying to pick the active route,
|
|
||||||
// then jump 2 lines and pick the third IP
|
|
||||||
// Not using regex because output is quite standard from Windows XP to 8 (NEEDS TESTING)
|
|
||||||
outputLines := bytes.Split(output, []byte("\n"))
|
|
||||||
for idx, line := range outputLines {
|
|
||||||
if bytes.Contains(line, []byte("Active Routes:")) {
|
|
||||||
ipFields := bytes.Fields(outputLines[idx+2])
|
|
||||||
ip = net.ParseIP(string(ipFields[2]))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = routeCmd.Wait()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
16
Godeps/_workspace/src/github.com/mattn/go-colorable/colorable_others.go
generated
vendored
16
Godeps/_workspace/src/github.com/mattn/go-colorable/colorable_others.go
generated
vendored
@@ -1,16 +0,0 @@
|
|||||||
// +build !windows
|
|
||||||
|
|
||||||
package colorable
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewColorableStdout() io.Writer {
|
|
||||||
return os.Stdout
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewColorableStderr() io.Writer {
|
|
||||||
return os.Stderr
|
|
||||||
}
|
|
||||||
37
Godeps/_workspace/src/github.com/mattn/go-isatty/README.md
generated
vendored
37
Godeps/_workspace/src/github.com/mattn/go-isatty/README.md
generated
vendored
@@ -1,37 +0,0 @@
|
|||||||
# go-isatty
|
|
||||||
|
|
||||||
isatty for golang
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/mattn/go-isatty"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
if isatty.IsTerminal(os.Stdout.Fd()) {
|
|
||||||
fmt.Println("Is Terminal")
|
|
||||||
} else {
|
|
||||||
fmt.Println("Is Not Terminal")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```
|
|
||||||
$ go get github.com/mattn/go-isatty
|
|
||||||
```
|
|
||||||
|
|
||||||
# License
|
|
||||||
|
|
||||||
MIT
|
|
||||||
|
|
||||||
# Author
|
|
||||||
|
|
||||||
Yasuhiro Matsumoto (a.k.a mattn)
|
|
||||||
19
Godeps/_workspace/src/github.com/mattn/go-isatty/isatty_windows.go
generated
vendored
19
Godeps/_workspace/src/github.com/mattn/go-isatty/isatty_windows.go
generated
vendored
@@ -1,19 +0,0 @@
|
|||||||
// +build windows
|
|
||||||
// +build !appengine
|
|
||||||
|
|
||||||
package isatty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
||||||
var procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
|
|
||||||
|
|
||||||
// IsTerminal return true if the file descriptor is terminal.
|
|
||||||
func IsTerminal(fd uintptr) bool {
|
|
||||||
var st uint32
|
|
||||||
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0)
|
|
||||||
return r != 0 && e == 0
|
|
||||||
}
|
|
||||||
9
Godeps/_workspace/src/github.com/mattn/go-runewidth/.travis.yml
generated
vendored
9
Godeps/_workspace/src/github.com/mattn/go-runewidth/.travis.yml
generated
vendored
@@ -1,9 +0,0 @@
|
|||||||
language: go
|
|
||||||
go:
|
|
||||||
- tip
|
|
||||||
before_install:
|
|
||||||
- go get github.com/axw/gocov/gocov
|
|
||||||
- go get github.com/mattn/goveralls
|
|
||||||
- go get golang.org/x/tools/cmd/cover
|
|
||||||
script:
|
|
||||||
- $HOME/gopath/bin/goveralls -repotoken lAKAWPzcGsD3A8yBX3BGGtRUdJ6CaGERL
|
|
||||||
464
Godeps/_workspace/src/github.com/mattn/go-runewidth/runewidth.go
generated
vendored
464
Godeps/_workspace/src/github.com/mattn/go-runewidth/runewidth.go
generated
vendored
@@ -1,464 +0,0 @@
|
|||||||
package runewidth
|
|
||||||
|
|
||||||
var EastAsianWidth = IsEastAsian()
|
|
||||||
var DefaultCondition = &Condition{EastAsianWidth}
|
|
||||||
|
|
||||||
type interval struct {
|
|
||||||
first rune
|
|
||||||
last rune
|
|
||||||
}
|
|
||||||
|
|
||||||
var combining = []interval{
|
|
||||||
{0x0300, 0x036F}, {0x0483, 0x0486}, {0x0488, 0x0489},
|
|
||||||
{0x0591, 0x05BD}, {0x05BF, 0x05BF}, {0x05C1, 0x05C2},
|
|
||||||
{0x05C4, 0x05C5}, {0x05C7, 0x05C7}, {0x0600, 0x0603},
|
|
||||||
{0x0610, 0x0615}, {0x064B, 0x065E}, {0x0670, 0x0670},
|
|
||||||
{0x06D6, 0x06E4}, {0x06E7, 0x06E8}, {0x06EA, 0x06ED},
|
|
||||||
{0x070F, 0x070F}, {0x0711, 0x0711}, {0x0730, 0x074A},
|
|
||||||
{0x07A6, 0x07B0}, {0x07EB, 0x07F3}, {0x0901, 0x0902},
|
|
||||||
{0x093C, 0x093C}, {0x0941, 0x0948}, {0x094D, 0x094D},
|
|
||||||
{0x0951, 0x0954}, {0x0962, 0x0963}, {0x0981, 0x0981},
|
|
||||||
{0x09BC, 0x09BC}, {0x09C1, 0x09C4}, {0x09CD, 0x09CD},
|
|
||||||
{0x09E2, 0x09E3}, {0x0A01, 0x0A02}, {0x0A3C, 0x0A3C},
|
|
||||||
{0x0A41, 0x0A42}, {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D},
|
|
||||||
{0x0A70, 0x0A71}, {0x0A81, 0x0A82}, {0x0ABC, 0x0ABC},
|
|
||||||
{0x0AC1, 0x0AC5}, {0x0AC7, 0x0AC8}, {0x0ACD, 0x0ACD},
|
|
||||||
{0x0AE2, 0x0AE3}, {0x0B01, 0x0B01}, {0x0B3C, 0x0B3C},
|
|
||||||
{0x0B3F, 0x0B3F}, {0x0B41, 0x0B43}, {0x0B4D, 0x0B4D},
|
|
||||||
{0x0B56, 0x0B56}, {0x0B82, 0x0B82}, {0x0BC0, 0x0BC0},
|
|
||||||
{0x0BCD, 0x0BCD}, {0x0C3E, 0x0C40}, {0x0C46, 0x0C48},
|
|
||||||
{0x0C4A, 0x0C4D}, {0x0C55, 0x0C56}, {0x0CBC, 0x0CBC},
|
|
||||||
{0x0CBF, 0x0CBF}, {0x0CC6, 0x0CC6}, {0x0CCC, 0x0CCD},
|
|
||||||
{0x0CE2, 0x0CE3}, {0x0D41, 0x0D43}, {0x0D4D, 0x0D4D},
|
|
||||||
{0x0DCA, 0x0DCA}, {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6},
|
|
||||||
{0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E},
|
|
||||||
{0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC},
|
|
||||||
{0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35},
|
|
||||||
{0x0F37, 0x0F37}, {0x0F39, 0x0F39}, {0x0F71, 0x0F7E},
|
|
||||||
{0x0F80, 0x0F84}, {0x0F86, 0x0F87}, {0x0F90, 0x0F97},
|
|
||||||
{0x0F99, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102D, 0x1030},
|
|
||||||
{0x1032, 0x1032}, {0x1036, 0x1037}, {0x1039, 0x1039},
|
|
||||||
{0x1058, 0x1059}, {0x1160, 0x11FF}, {0x135F, 0x135F},
|
|
||||||
{0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753},
|
|
||||||
{0x1772, 0x1773}, {0x17B4, 0x17B5}, {0x17B7, 0x17BD},
|
|
||||||
{0x17C6, 0x17C6}, {0x17C9, 0x17D3}, {0x17DD, 0x17DD},
|
|
||||||
{0x180B, 0x180D}, {0x18A9, 0x18A9}, {0x1920, 0x1922},
|
|
||||||
{0x1927, 0x1928}, {0x1932, 0x1932}, {0x1939, 0x193B},
|
|
||||||
{0x1A17, 0x1A18}, {0x1B00, 0x1B03}, {0x1B34, 0x1B34},
|
|
||||||
{0x1B36, 0x1B3A}, {0x1B3C, 0x1B3C}, {0x1B42, 0x1B42},
|
|
||||||
{0x1B6B, 0x1B73}, {0x1DC0, 0x1DCA}, {0x1DFE, 0x1DFF},
|
|
||||||
{0x200B, 0x200F}, {0x202A, 0x202E}, {0x2060, 0x2063},
|
|
||||||
{0x206A, 0x206F}, {0x20D0, 0x20EF}, {0x302A, 0x302F},
|
|
||||||
{0x3099, 0x309A}, {0xA806, 0xA806}, {0xA80B, 0xA80B},
|
|
||||||
{0xA825, 0xA826}, {0xFB1E, 0xFB1E}, {0xFE00, 0xFE0F},
|
|
||||||
{0xFE20, 0xFE23}, {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB},
|
|
||||||
{0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F},
|
|
||||||
{0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x1D167, 0x1D169},
|
|
||||||
{0x1D173, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD},
|
|
||||||
{0x1D242, 0x1D244}, {0xE0001, 0xE0001}, {0xE0020, 0xE007F},
|
|
||||||
{0xE0100, 0xE01EF},
|
|
||||||
}
|
|
||||||
|
|
||||||
type ctype int
|
|
||||||
|
|
||||||
const (
|
|
||||||
narrow ctype = iota
|
|
||||||
ambiguous
|
|
||||||
wide
|
|
||||||
halfwidth
|
|
||||||
fullwidth
|
|
||||||
neutral
|
|
||||||
)
|
|
||||||
|
|
||||||
type intervalType struct {
|
|
||||||
first rune
|
|
||||||
last rune
|
|
||||||
ctype ctype
|
|
||||||
}
|
|
||||||
|
|
||||||
var ctypes = []intervalType{
|
|
||||||
{0x0020, 0x007E, narrow},
|
|
||||||
{0x00A1, 0x00A1, ambiguous},
|
|
||||||
{0x00A2, 0x00A3, narrow},
|
|
||||||
{0x00A4, 0x00A4, ambiguous},
|
|
||||||
{0x00A5, 0x00A6, narrow},
|
|
||||||
{0x00A7, 0x00A8, ambiguous},
|
|
||||||
{0x00AA, 0x00AA, ambiguous},
|
|
||||||
{0x00AC, 0x00AC, narrow},
|
|
||||||
{0x00AD, 0x00AE, ambiguous},
|
|
||||||
{0x00AF, 0x00AF, narrow},
|
|
||||||
{0x00B0, 0x00B4, ambiguous},
|
|
||||||
{0x00B6, 0x00BA, ambiguous},
|
|
||||||
{0x00BC, 0x00BF, ambiguous},
|
|
||||||
{0x00C6, 0x00C6, ambiguous},
|
|
||||||
{0x00D0, 0x00D0, ambiguous},
|
|
||||||
{0x00D7, 0x00D8, ambiguous},
|
|
||||||
{0x00DE, 0x00E1, ambiguous},
|
|
||||||
{0x00E6, 0x00E6, ambiguous},
|
|
||||||
{0x00E8, 0x00EA, ambiguous},
|
|
||||||
{0x00EC, 0x00ED, ambiguous},
|
|
||||||
{0x00F0, 0x00F0, ambiguous},
|
|
||||||
{0x00F2, 0x00F3, ambiguous},
|
|
||||||
{0x00F7, 0x00FA, ambiguous},
|
|
||||||
{0x00FC, 0x00FC, ambiguous},
|
|
||||||
{0x00FE, 0x00FE, ambiguous},
|
|
||||||
{0x0101, 0x0101, ambiguous},
|
|
||||||
{0x0111, 0x0111, ambiguous},
|
|
||||||
{0x0113, 0x0113, ambiguous},
|
|
||||||
{0x011B, 0x011B, ambiguous},
|
|
||||||
{0x0126, 0x0127, ambiguous},
|
|
||||||
{0x012B, 0x012B, ambiguous},
|
|
||||||
{0x0131, 0x0133, ambiguous},
|
|
||||||
{0x0138, 0x0138, ambiguous},
|
|
||||||
{0x013F, 0x0142, ambiguous},
|
|
||||||
{0x0144, 0x0144, ambiguous},
|
|
||||||
{0x0148, 0x014B, ambiguous},
|
|
||||||
{0x014D, 0x014D, ambiguous},
|
|
||||||
{0x0152, 0x0153, ambiguous},
|
|
||||||
{0x0166, 0x0167, ambiguous},
|
|
||||||
{0x016B, 0x016B, ambiguous},
|
|
||||||
{0x01CE, 0x01CE, ambiguous},
|
|
||||||
{0x01D0, 0x01D0, ambiguous},
|
|
||||||
{0x01D2, 0x01D2, ambiguous},
|
|
||||||
{0x01D4, 0x01D4, ambiguous},
|
|
||||||
{0x01D6, 0x01D6, ambiguous},
|
|
||||||
{0x01D8, 0x01D8, ambiguous},
|
|
||||||
{0x01DA, 0x01DA, ambiguous},
|
|
||||||
{0x01DC, 0x01DC, ambiguous},
|
|
||||||
{0x0251, 0x0251, ambiguous},
|
|
||||||
{0x0261, 0x0261, ambiguous},
|
|
||||||
{0x02C4, 0x02C4, ambiguous},
|
|
||||||
{0x02C7, 0x02C7, ambiguous},
|
|
||||||
{0x02C9, 0x02CB, ambiguous},
|
|
||||||
{0x02CD, 0x02CD, ambiguous},
|
|
||||||
{0x02D0, 0x02D0, ambiguous},
|
|
||||||
{0x02D8, 0x02DB, ambiguous},
|
|
||||||
{0x02DD, 0x02DD, ambiguous},
|
|
||||||
{0x02DF, 0x02DF, ambiguous},
|
|
||||||
{0x0300, 0x036F, ambiguous},
|
|
||||||
{0x0391, 0x03A2, ambiguous},
|
|
||||||
{0x03A3, 0x03A9, ambiguous},
|
|
||||||
{0x03B1, 0x03C1, ambiguous},
|
|
||||||
{0x03C3, 0x03C9, ambiguous},
|
|
||||||
{0x0401, 0x0401, ambiguous},
|
|
||||||
{0x0410, 0x044F, ambiguous},
|
|
||||||
{0x0451, 0x0451, ambiguous},
|
|
||||||
{0x1100, 0x115F, wide},
|
|
||||||
{0x2010, 0x2010, ambiguous},
|
|
||||||
{0x2013, 0x2016, ambiguous},
|
|
||||||
{0x2018, 0x2019, ambiguous},
|
|
||||||
{0x201C, 0x201D, ambiguous},
|
|
||||||
{0x2020, 0x2022, ambiguous},
|
|
||||||
{0x2024, 0x2027, ambiguous},
|
|
||||||
{0x2030, 0x2030, ambiguous},
|
|
||||||
{0x2032, 0x2033, ambiguous},
|
|
||||||
{0x2035, 0x2035, ambiguous},
|
|
||||||
{0x203B, 0x203B, ambiguous},
|
|
||||||
{0x203E, 0x203E, ambiguous},
|
|
||||||
{0x2074, 0x2074, ambiguous},
|
|
||||||
{0x207F, 0x207F, ambiguous},
|
|
||||||
{0x2081, 0x2084, ambiguous},
|
|
||||||
{0x20A9, 0x20A9, halfwidth},
|
|
||||||
{0x20AC, 0x20AC, ambiguous},
|
|
||||||
{0x2103, 0x2103, ambiguous},
|
|
||||||
{0x2105, 0x2105, ambiguous},
|
|
||||||
{0x2109, 0x2109, ambiguous},
|
|
||||||
{0x2113, 0x2113, ambiguous},
|
|
||||||
{0x2116, 0x2116, ambiguous},
|
|
||||||
{0x2121, 0x2122, ambiguous},
|
|
||||||
{0x2126, 0x2126, ambiguous},
|
|
||||||
{0x212B, 0x212B, ambiguous},
|
|
||||||
{0x2153, 0x2154, ambiguous},
|
|
||||||
{0x215B, 0x215E, ambiguous},
|
|
||||||
{0x2160, 0x216B, ambiguous},
|
|
||||||
{0x2170, 0x2179, ambiguous},
|
|
||||||
{0x2189, 0x218A, ambiguous},
|
|
||||||
{0x2190, 0x2199, ambiguous},
|
|
||||||
{0x21B8, 0x21B9, ambiguous},
|
|
||||||
{0x21D2, 0x21D2, ambiguous},
|
|
||||||
{0x21D4, 0x21D4, ambiguous},
|
|
||||||
{0x21E7, 0x21E7, ambiguous},
|
|
||||||
{0x2200, 0x2200, ambiguous},
|
|
||||||
{0x2202, 0x2203, ambiguous},
|
|
||||||
{0x2207, 0x2208, ambiguous},
|
|
||||||
{0x220B, 0x220B, ambiguous},
|
|
||||||
{0x220F, 0x220F, ambiguous},
|
|
||||||
{0x2211, 0x2211, ambiguous},
|
|
||||||
{0x2215, 0x2215, ambiguous},
|
|
||||||
{0x221A, 0x221A, ambiguous},
|
|
||||||
{0x221D, 0x2220, ambiguous},
|
|
||||||
{0x2223, 0x2223, ambiguous},
|
|
||||||
{0x2225, 0x2225, ambiguous},
|
|
||||||
{0x2227, 0x222C, ambiguous},
|
|
||||||
{0x222E, 0x222E, ambiguous},
|
|
||||||
{0x2234, 0x2237, ambiguous},
|
|
||||||
{0x223C, 0x223D, ambiguous},
|
|
||||||
{0x2248, 0x2248, ambiguous},
|
|
||||||
{0x224C, 0x224C, ambiguous},
|
|
||||||
{0x2252, 0x2252, ambiguous},
|
|
||||||
{0x2260, 0x2261, ambiguous},
|
|
||||||
{0x2264, 0x2267, ambiguous},
|
|
||||||
{0x226A, 0x226B, ambiguous},
|
|
||||||
{0x226E, 0x226F, ambiguous},
|
|
||||||
{0x2282, 0x2283, ambiguous},
|
|
||||||
{0x2286, 0x2287, ambiguous},
|
|
||||||
{0x2295, 0x2295, ambiguous},
|
|
||||||
{0x2299, 0x2299, ambiguous},
|
|
||||||
{0x22A5, 0x22A5, ambiguous},
|
|
||||||
{0x22BF, 0x22BF, ambiguous},
|
|
||||||
{0x2312, 0x2312, ambiguous},
|
|
||||||
{0x2329, 0x232A, wide},
|
|
||||||
{0x2460, 0x24E9, ambiguous},
|
|
||||||
{0x24EB, 0x254B, ambiguous},
|
|
||||||
{0x2550, 0x2573, ambiguous},
|
|
||||||
{0x2580, 0x258F, ambiguous},
|
|
||||||
{0x2592, 0x2595, ambiguous},
|
|
||||||
{0x25A0, 0x25A1, ambiguous},
|
|
||||||
{0x25A3, 0x25A9, ambiguous},
|
|
||||||
{0x25B2, 0x25B3, ambiguous},
|
|
||||||
{0x25B6, 0x25B7, ambiguous},
|
|
||||||
{0x25BC, 0x25BD, ambiguous},
|
|
||||||
{0x25C0, 0x25C1, ambiguous},
|
|
||||||
{0x25C6, 0x25C8, ambiguous},
|
|
||||||
{0x25CB, 0x25CB, ambiguous},
|
|
||||||
{0x25CE, 0x25D1, ambiguous},
|
|
||||||
{0x25E2, 0x25E5, ambiguous},
|
|
||||||
{0x25EF, 0x25EF, ambiguous},
|
|
||||||
{0x2605, 0x2606, ambiguous},
|
|
||||||
{0x2609, 0x2609, ambiguous},
|
|
||||||
{0x260E, 0x260F, ambiguous},
|
|
||||||
{0x2614, 0x2615, ambiguous},
|
|
||||||
{0x261C, 0x261C, ambiguous},
|
|
||||||
{0x261E, 0x261E, ambiguous},
|
|
||||||
{0x2640, 0x2640, ambiguous},
|
|
||||||
{0x2642, 0x2642, ambiguous},
|
|
||||||
{0x2660, 0x2661, ambiguous},
|
|
||||||
{0x2663, 0x2665, ambiguous},
|
|
||||||
{0x2667, 0x266A, ambiguous},
|
|
||||||
{0x266C, 0x266D, ambiguous},
|
|
||||||
{0x266F, 0x266F, ambiguous},
|
|
||||||
{0x269E, 0x269F, ambiguous},
|
|
||||||
{0x26BE, 0x26BF, ambiguous},
|
|
||||||
{0x26C4, 0x26CD, ambiguous},
|
|
||||||
{0x26CF, 0x26E1, ambiguous},
|
|
||||||
{0x26E3, 0x26E3, ambiguous},
|
|
||||||
{0x26E8, 0x26FF, ambiguous},
|
|
||||||
{0x273D, 0x273D, ambiguous},
|
|
||||||
{0x2757, 0x2757, ambiguous},
|
|
||||||
{0x2776, 0x277F, ambiguous},
|
|
||||||
{0x27E6, 0x27ED, narrow},
|
|
||||||
{0x2985, 0x2986, narrow},
|
|
||||||
{0x2B55, 0x2B59, ambiguous},
|
|
||||||
{0x2E80, 0x2E9A, wide},
|
|
||||||
{0x2E9B, 0x2EF4, wide},
|
|
||||||
{0x2F00, 0x2FD6, wide},
|
|
||||||
{0x2FF0, 0x2FFC, wide},
|
|
||||||
{0x3000, 0x3000, fullwidth},
|
|
||||||
{0x3001, 0x303E, wide},
|
|
||||||
{0x3041, 0x3097, wide},
|
|
||||||
{0x3099, 0x3100, wide},
|
|
||||||
{0x3105, 0x312E, wide},
|
|
||||||
{0x3131, 0x318F, wide},
|
|
||||||
{0x3190, 0x31BB, wide},
|
|
||||||
{0x31C0, 0x31E4, wide},
|
|
||||||
{0x31F0, 0x321F, wide},
|
|
||||||
{0x3220, 0x3247, wide},
|
|
||||||
{0x3248, 0x324F, ambiguous},
|
|
||||||
{0x3250, 0x32FF, wide},
|
|
||||||
{0x3300, 0x4DBF, wide},
|
|
||||||
{0x4E00, 0xA48D, wide},
|
|
||||||
{0xA490, 0xA4C7, wide},
|
|
||||||
{0xA960, 0xA97D, wide},
|
|
||||||
{0xAC00, 0xD7A4, wide},
|
|
||||||
{0xE000, 0xF8FF, ambiguous},
|
|
||||||
{0xF900, 0xFAFF, wide},
|
|
||||||
{0xFE00, 0xFE0F, ambiguous},
|
|
||||||
{0xFE10, 0xFE1A, wide},
|
|
||||||
{0xFE30, 0xFE53, wide},
|
|
||||||
{0xFE54, 0xFE67, wide},
|
|
||||||
{0xFE68, 0xFE6C, wide},
|
|
||||||
{0xFF01, 0xFF60, fullwidth},
|
|
||||||
{0xFF61, 0xFFBF, halfwidth},
|
|
||||||
{0xFFC2, 0xFFC8, halfwidth},
|
|
||||||
{0xFFCA, 0xFFD0, halfwidth},
|
|
||||||
{0xFFD2, 0xFFD8, halfwidth},
|
|
||||||
{0xFFDA, 0xFFDD, halfwidth},
|
|
||||||
{0xFFE0, 0xFFE7, fullwidth},
|
|
||||||
{0xFFE8, 0xFFEF, halfwidth},
|
|
||||||
{0xFFFD, 0xFFFE, ambiguous},
|
|
||||||
{0x1B000, 0x1B002, wide},
|
|
||||||
{0x1F100, 0x1F10A, ambiguous},
|
|
||||||
{0x1F110, 0x1F12D, ambiguous},
|
|
||||||
{0x1F130, 0x1F169, ambiguous},
|
|
||||||
{0x1F170, 0x1F19B, ambiguous},
|
|
||||||
{0x1F200, 0x1F203, wide},
|
|
||||||
{0x1F210, 0x1F23B, wide},
|
|
||||||
{0x1F240, 0x1F249, wide},
|
|
||||||
{0x1F250, 0x1F252, wide},
|
|
||||||
{0x20000, 0x2FFFE, wide},
|
|
||||||
{0x30000, 0x3FFFE, wide},
|
|
||||||
{0xE0100, 0xE01F0, ambiguous},
|
|
||||||
{0xF0000, 0xFFFFD, ambiguous},
|
|
||||||
{0x100000, 0x10FFFE, ambiguous},
|
|
||||||
}
|
|
||||||
|
|
||||||
type Condition struct {
|
|
||||||
EastAsianWidth bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCondition() *Condition {
|
|
||||||
return &Condition{EastAsianWidth}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RuneWidth returns the number of cells in r.
|
|
||||||
// See http://www.unicode.org/reports/tr11/
|
|
||||||
func (c *Condition) RuneWidth(r rune) int {
|
|
||||||
if r == 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if r < 32 || (r >= 0x7f && r < 0xa0) {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
for _, iv := range combining {
|
|
||||||
if iv.first <= r && r <= iv.last {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.EastAsianWidth && IsAmbiguousWidth(r) {
|
|
||||||
return 2
|
|
||||||
}
|
|
||||||
|
|
||||||
if r >= 0x1100 &&
|
|
||||||
(r <= 0x115f || r == 0x2329 || r == 0x232a ||
|
|
||||||
(r >= 0x2e80 && r <= 0xa4cf && r != 0x303f) ||
|
|
||||||
(r >= 0xac00 && r <= 0xd7a3) ||
|
|
||||||
(r >= 0xf900 && r <= 0xfaff) ||
|
|
||||||
(r >= 0xfe30 && r <= 0xfe6f) ||
|
|
||||||
(r >= 0xff00 && r <= 0xff60) ||
|
|
||||||
(r >= 0xffe0 && r <= 0xffe6) ||
|
|
||||||
(r >= 0x20000 && r <= 0x2fffd) ||
|
|
||||||
(r >= 0x30000 && r <= 0x3fffd)) {
|
|
||||||
return 2
|
|
||||||
}
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Condition) StringWidth(s string) (width int) {
|
|
||||||
for _, r := range []rune(s) {
|
|
||||||
width += c.RuneWidth(r)
|
|
||||||
}
|
|
||||||
return width
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Condition) Truncate(s string, w int, tail string) string {
|
|
||||||
if c.StringWidth(s) <= w {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
r := []rune(s)
|
|
||||||
tw := c.StringWidth(tail)
|
|
||||||
w -= tw
|
|
||||||
width := 0
|
|
||||||
i := 0
|
|
||||||
for ; i < len(r); i++ {
|
|
||||||
cw := c.RuneWidth(r[i])
|
|
||||||
if width+cw > w {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
width += cw
|
|
||||||
}
|
|
||||||
return string(r[0:i]) + tail
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Condition) Wrap(s string, w int) string {
|
|
||||||
width := 0
|
|
||||||
out := ""
|
|
||||||
for _, r := range []rune(s) {
|
|
||||||
cw := RuneWidth(r)
|
|
||||||
if r == '\n' {
|
|
||||||
out += string(r)
|
|
||||||
width = 0
|
|
||||||
continue
|
|
||||||
} else if width+cw > w {
|
|
||||||
out += "\n"
|
|
||||||
width = 0
|
|
||||||
out += string(r)
|
|
||||||
width += cw
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
out += string(r)
|
|
||||||
width += cw
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Condition) FillLeft(s string, w int) string {
|
|
||||||
width := c.StringWidth(s)
|
|
||||||
count := w - width
|
|
||||||
if count > 0 {
|
|
||||||
b := make([]byte, count)
|
|
||||||
for i := range b {
|
|
||||||
b[i] = ' '
|
|
||||||
}
|
|
||||||
return string(b) + s
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Condition) FillRight(s string, w int) string {
|
|
||||||
width := c.StringWidth(s)
|
|
||||||
count := w - width
|
|
||||||
if count > 0 {
|
|
||||||
b := make([]byte, count)
|
|
||||||
for i := range b {
|
|
||||||
b[i] = ' '
|
|
||||||
}
|
|
||||||
return s + string(b)
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// RuneWidth returns the number of cells in r.
|
|
||||||
// See http://www.unicode.org/reports/tr11/
|
|
||||||
func RuneWidth(r rune) int {
|
|
||||||
return DefaultCondition.RuneWidth(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ct(r rune) ctype {
|
|
||||||
for _, iv := range ctypes {
|
|
||||||
if iv.first <= r && r <= iv.last {
|
|
||||||
return iv.ctype
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return neutral
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsAmbiguousWidth returns whether is ambiguous width or not.
|
|
||||||
func IsAmbiguousWidth(r rune) bool {
|
|
||||||
return ct(r) == ambiguous
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsAmbiguousWidth returns whether is ambiguous width or not.
|
|
||||||
func IsNeutralWidth(r rune) bool {
|
|
||||||
return ct(r) == neutral
|
|
||||||
}
|
|
||||||
|
|
||||||
func StringWidth(s string) (width int) {
|
|
||||||
return DefaultCondition.StringWidth(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Truncate(s string, w int, tail string) string {
|
|
||||||
return DefaultCondition.Truncate(s, w, tail)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Wrap(s string, w int) string {
|
|
||||||
return DefaultCondition.Wrap(s, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func FillLeft(s string, w int) string {
|
|
||||||
return DefaultCondition.FillLeft(s, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func FillRight(s string, w int) string {
|
|
||||||
return DefaultCondition.FillRight(s, w)
|
|
||||||
}
|
|
||||||
15
Godeps/_workspace/src/github.com/microsoft/go-winio/README.md
generated
vendored
15
Godeps/_workspace/src/github.com/microsoft/go-winio/README.md
generated
vendored
@@ -1,15 +0,0 @@
|
|||||||
# go-winio
|
|
||||||
|
|
||||||
This repository contains utilities for efficiently performing Win32 IO operations in
|
|
||||||
Go. Currently, this is focused on accessing named pipes and other file handles, and
|
|
||||||
for using named pipes as a net transport.
|
|
||||||
|
|
||||||
This code relies on IO completion ports to avoid blocking IO on system threads, allowing Go
|
|
||||||
to reuse the thread to schedule another goroutine. This limits support to Windows Vista and
|
|
||||||
newer operating systems. This is similar to the implementation of network sockets in Go's net
|
|
||||||
package.
|
|
||||||
|
|
||||||
Please see the LICENSE file for licensing information.
|
|
||||||
|
|
||||||
Thanks to natefinch for the inspiration for this library. See https://github.com/natefinch/npipe
|
|
||||||
for another named pipe implementation.
|
|
||||||
266
Godeps/_workspace/src/github.com/microsoft/go-winio/backup.go
generated
vendored
266
Godeps/_workspace/src/github.com/microsoft/go-winio/backup.go
generated
vendored
@@ -1,266 +0,0 @@
|
|||||||
package winio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"syscall"
|
|
||||||
"unicode/utf16"
|
|
||||||
)
|
|
||||||
|
|
||||||
//sys backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupRead
|
|
||||||
//sys backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupWrite
|
|
||||||
|
|
||||||
const (
|
|
||||||
BackupData = uint32(iota + 1)
|
|
||||||
BackupEaData
|
|
||||||
BackupSecurity
|
|
||||||
BackupAlternateData
|
|
||||||
BackupLink
|
|
||||||
BackupPropertyData
|
|
||||||
BackupObjectId
|
|
||||||
BackupReparseData
|
|
||||||
BackupSparseBlock
|
|
||||||
BackupTxfsData
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
StreamSparseAttributes = uint32(8)
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
WRITE_DAC = 0x40000
|
|
||||||
WRITE_OWNER = 0x80000
|
|
||||||
ACCESS_SYSTEM_SECURITY = 0x1000000
|
|
||||||
)
|
|
||||||
|
|
||||||
// BackupHeader represents a backup stream of a file.
|
|
||||||
type BackupHeader struct {
|
|
||||||
Id uint32 // The backup stream ID
|
|
||||||
Attributes uint32 // Stream attributes
|
|
||||||
Size int64 // The size of the stream in bytes
|
|
||||||
Name string // The name of the stream (for BackupAlternateData only).
|
|
||||||
Offset int64 // The offset of the stream in the file (for BackupSparseBlock only).
|
|
||||||
}
|
|
||||||
|
|
||||||
type win32StreamId struct {
|
|
||||||
StreamId uint32
|
|
||||||
Attributes uint32
|
|
||||||
Size uint64
|
|
||||||
NameSize uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
// BackupStreamReader reads from a stream produced by the BackupRead Win32 API and produces a series
|
|
||||||
// of BackupHeader values.
|
|
||||||
type BackupStreamReader struct {
|
|
||||||
r io.Reader
|
|
||||||
bytesLeft int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBackupStreamReader produces a BackupStreamReader from any io.Reader.
|
|
||||||
func NewBackupStreamReader(r io.Reader) *BackupStreamReader {
|
|
||||||
return &BackupStreamReader{r, 0}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next returns the next backup stream and prepares for calls to Write(). It skips the remainder of the current stream if
|
|
||||||
// it was not completely read.
|
|
||||||
func (r *BackupStreamReader) Next() (*BackupHeader, error) {
|
|
||||||
if r.bytesLeft > 0 {
|
|
||||||
if _, err := io.Copy(ioutil.Discard, r); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var wsi win32StreamId
|
|
||||||
if err := binary.Read(r.r, binary.LittleEndian, &wsi); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
hdr := &BackupHeader{
|
|
||||||
Id: wsi.StreamId,
|
|
||||||
Attributes: wsi.Attributes,
|
|
||||||
Size: int64(wsi.Size),
|
|
||||||
}
|
|
||||||
if wsi.NameSize != 0 {
|
|
||||||
name := make([]uint16, int(wsi.NameSize/2))
|
|
||||||
if err := binary.Read(r.r, binary.LittleEndian, name); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
hdr.Name = syscall.UTF16ToString(name)
|
|
||||||
}
|
|
||||||
if wsi.StreamId == BackupSparseBlock {
|
|
||||||
if err := binary.Read(r.r, binary.LittleEndian, &hdr.Offset); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
hdr.Size -= 8
|
|
||||||
}
|
|
||||||
r.bytesLeft = hdr.Size
|
|
||||||
return hdr, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads from the current backup stream.
|
|
||||||
func (r *BackupStreamReader) Read(b []byte) (int, error) {
|
|
||||||
if r.bytesLeft == 0 {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
if int64(len(b)) > r.bytesLeft {
|
|
||||||
b = b[:r.bytesLeft]
|
|
||||||
}
|
|
||||||
n, err := r.r.Read(b)
|
|
||||||
r.bytesLeft -= int64(n)
|
|
||||||
if err == io.EOF {
|
|
||||||
err = io.ErrUnexpectedEOF
|
|
||||||
} else if r.bytesLeft == 0 && err == nil {
|
|
||||||
err = io.EOF
|
|
||||||
}
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// BackupStreamWriter writes a stream compatible with the BackupWrite Win32 API.
|
|
||||||
type BackupStreamWriter struct {
|
|
||||||
w io.Writer
|
|
||||||
bytesLeft int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBackupStreamWriter produces a BackupStreamWriter on top of an io.Writer.
|
|
||||||
func NewBackupStreamWriter(w io.Writer) *BackupStreamWriter {
|
|
||||||
return &BackupStreamWriter{w, 0}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteHeader writes the next backup stream header and prepares for calls to Write().
|
|
||||||
func (w *BackupStreamWriter) WriteHeader(hdr *BackupHeader) error {
|
|
||||||
if w.bytesLeft != 0 {
|
|
||||||
return fmt.Errorf("missing %d bytes", w.bytesLeft)
|
|
||||||
}
|
|
||||||
name := utf16.Encode([]rune(hdr.Name))
|
|
||||||
wsi := win32StreamId{
|
|
||||||
StreamId: hdr.Id,
|
|
||||||
Attributes: hdr.Attributes,
|
|
||||||
Size: uint64(hdr.Size),
|
|
||||||
NameSize: uint32(len(name) * 2),
|
|
||||||
}
|
|
||||||
if hdr.Id == BackupSparseBlock {
|
|
||||||
// Include space for the int64 block offset
|
|
||||||
wsi.Size += 8
|
|
||||||
}
|
|
||||||
if err := binary.Write(w.w, binary.LittleEndian, &wsi); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(name) != 0 {
|
|
||||||
if err := binary.Write(w.w, binary.LittleEndian, name); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if hdr.Id == BackupSparseBlock {
|
|
||||||
if err := binary.Write(w.w, binary.LittleEndian, hdr.Offset); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.bytesLeft = hdr.Size
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write writes to the current backup stream.
|
|
||||||
func (w *BackupStreamWriter) Write(b []byte) (int, error) {
|
|
||||||
if w.bytesLeft < int64(len(b)) {
|
|
||||||
return 0, fmt.Errorf("too many bytes by %d", int64(len(b))-w.bytesLeft)
|
|
||||||
}
|
|
||||||
n, err := w.w.Write(b)
|
|
||||||
w.bytesLeft -= int64(n)
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// BackupFileReader provides an io.ReadCloser interface on top of the BackupRead Win32 API.
|
|
||||||
type BackupFileReader struct {
|
|
||||||
f *os.File
|
|
||||||
includeSecurity bool
|
|
||||||
ctx uintptr
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBackupFileReader returns a new BackupFileReader from a file handle. If includeSecurity is true,
|
|
||||||
// Read will attempt to read the security descriptor of the file.
|
|
||||||
func NewBackupFileReader(f *os.File, includeSecurity bool) *BackupFileReader {
|
|
||||||
r := &BackupFileReader{f, includeSecurity, 0}
|
|
||||||
runtime.SetFinalizer(r, func(r *BackupFileReader) { r.Close() })
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads a backup stream from the file by calling the Win32 API BackupRead().
|
|
||||||
func (r *BackupFileReader) Read(b []byte) (int, error) {
|
|
||||||
var bytesRead uint32
|
|
||||||
err := backupRead(syscall.Handle(r.f.Fd()), b, &bytesRead, false, r.includeSecurity, &r.ctx)
|
|
||||||
if err != nil {
|
|
||||||
return 0, &os.PathError{"BackupRead", r.f.Name(), err}
|
|
||||||
}
|
|
||||||
if bytesRead == 0 {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
return int(bytesRead), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close frees Win32 resources associated with the BackupFileReader. It does not close
|
|
||||||
// the underlying file.
|
|
||||||
func (r *BackupFileReader) Close() error {
|
|
||||||
if r.ctx != 0 {
|
|
||||||
backupRead(syscall.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx)
|
|
||||||
r.ctx = 0
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// BackupFileWriter provides an io.WriteCloser interface on top of the BackupWrite Win32 API.
|
|
||||||
type BackupFileWriter struct {
|
|
||||||
f *os.File
|
|
||||||
includeSecurity bool
|
|
||||||
ctx uintptr
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBackupFileWrtier returns a new BackupFileWriter from a file handle. If includeSecurity is true,
|
|
||||||
// Write() will attempt to restore the security descriptor from the stream.
|
|
||||||
func NewBackupFileWriter(f *os.File, includeSecurity bool) *BackupFileWriter {
|
|
||||||
w := &BackupFileWriter{f, includeSecurity, 0}
|
|
||||||
runtime.SetFinalizer(w, func(w *BackupFileWriter) { w.Close() })
|
|
||||||
return w
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write restores a portion of the file using the provided backup stream.
|
|
||||||
func (w *BackupFileWriter) Write(b []byte) (int, error) {
|
|
||||||
var bytesWritten uint32
|
|
||||||
err := backupWrite(syscall.Handle(w.f.Fd()), b, &bytesWritten, false, w.includeSecurity, &w.ctx)
|
|
||||||
if err != nil {
|
|
||||||
return 0, &os.PathError{"BackupWrite", w.f.Name(), err}
|
|
||||||
}
|
|
||||||
if int(bytesWritten) != len(b) {
|
|
||||||
return int(bytesWritten), errors.New("not all bytes could be written")
|
|
||||||
}
|
|
||||||
return len(b), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close frees Win32 resources associated with the BackupFileWriter. It does not
|
|
||||||
// close the underlying file.
|
|
||||||
func (w *BackupFileWriter) Close() error {
|
|
||||||
if w.ctx != 0 {
|
|
||||||
backupWrite(syscall.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx)
|
|
||||||
w.ctx = 0
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenForBackup opens a file or directory, potentially skipping access checks if the backup
|
|
||||||
// or restore privileges have been acquired.
|
|
||||||
//
|
|
||||||
// If the file opened was a directory, it cannot be used with Readdir().
|
|
||||||
func OpenForBackup(path string, access uint32, share uint32, createmode uint32) (*os.File, error) {
|
|
||||||
winPath, err := syscall.UTF16FromString(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
h, err := syscall.CreateFile(&winPath[0], access, share, nil, createmode, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
|
|
||||||
if err != nil {
|
|
||||||
err = &os.PathError{Op: "open", Path: path, Err: err}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return os.NewFile(uintptr(h), path), nil
|
|
||||||
}
|
|
||||||
219
Godeps/_workspace/src/github.com/microsoft/go-winio/file.go
generated
vendored
219
Godeps/_workspace/src/github.com/microsoft/go-winio/file.go
generated
vendored
@@ -1,219 +0,0 @@
|
|||||||
package winio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"runtime"
|
|
||||||
"sync"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
//sys cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) = CancelIoEx
|
|
||||||
//sys createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) = CreateIoCompletionPort
|
|
||||||
//sys getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus
|
|
||||||
//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
|
|
||||||
//sys timeBeginPeriod(period uint32) (n int32) = winmm.timeBeginPeriod
|
|
||||||
|
|
||||||
const (
|
|
||||||
cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
|
|
||||||
cFILE_SKIP_SET_EVENT_ON_HANDLE = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrFileClosed = errors.New("file has already been closed")
|
|
||||||
ErrTimeout = &timeoutError{}
|
|
||||||
)
|
|
||||||
|
|
||||||
type timeoutError struct{}
|
|
||||||
|
|
||||||
func (e *timeoutError) Error() string { return "i/o timeout" }
|
|
||||||
func (e *timeoutError) Timeout() bool { return true }
|
|
||||||
func (e *timeoutError) Temporary() bool { return true }
|
|
||||||
|
|
||||||
var ioInitOnce sync.Once
|
|
||||||
var ioCompletionPort syscall.Handle
|
|
||||||
|
|
||||||
// ioResult contains the result of an asynchronous IO operation
|
|
||||||
type ioResult struct {
|
|
||||||
bytes uint32
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
// ioOperation represents an outstanding asynchronous Win32 IO
|
|
||||||
type ioOperation struct {
|
|
||||||
o syscall.Overlapped
|
|
||||||
ch chan ioResult
|
|
||||||
}
|
|
||||||
|
|
||||||
func initIo() {
|
|
||||||
h, err := createIoCompletionPort(syscall.InvalidHandle, 0, 0, 0xffffffff)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
ioCompletionPort = h
|
|
||||||
go ioCompletionProcessor(h)
|
|
||||||
}
|
|
||||||
|
|
||||||
// win32File implements Reader, Writer, and Closer on a Win32 handle without blocking in a syscall.
|
|
||||||
// It takes ownership of this handle and will close it if it is garbage collected.
|
|
||||||
type win32File struct {
|
|
||||||
handle syscall.Handle
|
|
||||||
wg sync.WaitGroup
|
|
||||||
closing bool
|
|
||||||
readDeadline time.Time
|
|
||||||
writeDeadline time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// makeWin32File makes a new win32File from an existing file handle
|
|
||||||
func makeWin32File(h syscall.Handle) (*win32File, error) {
|
|
||||||
f := &win32File{handle: h}
|
|
||||||
ioInitOnce.Do(initIo)
|
|
||||||
_, err := createIoCompletionPort(h, ioCompletionPort, 0, 0xffffffff)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = setFileCompletionNotificationModes(h, cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS|cFILE_SKIP_SET_EVENT_ON_HANDLE)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
runtime.SetFinalizer(f, (*win32File).closeHandle)
|
|
||||||
return f, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) {
|
|
||||||
return makeWin32File(h)
|
|
||||||
}
|
|
||||||
|
|
||||||
// closeHandle closes the resources associated with a Win32 handle
|
|
||||||
func (f *win32File) closeHandle() {
|
|
||||||
if !f.closing {
|
|
||||||
// cancel all IO and wait for it to complete
|
|
||||||
f.closing = true
|
|
||||||
cancelIoEx(f.handle, nil)
|
|
||||||
f.wg.Wait()
|
|
||||||
// at this point, no new IO can start
|
|
||||||
syscall.Close(f.handle)
|
|
||||||
f.handle = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close closes a win32File.
|
|
||||||
func (f *win32File) Close() error {
|
|
||||||
f.closeHandle()
|
|
||||||
runtime.SetFinalizer(f, nil)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepareIo prepares for a new IO operation
|
|
||||||
func (f *win32File) prepareIo() (*ioOperation, error) {
|
|
||||||
f.wg.Add(1)
|
|
||||||
if f.closing {
|
|
||||||
return nil, ErrFileClosed
|
|
||||||
}
|
|
||||||
c := &ioOperation{}
|
|
||||||
c.ch = make(chan ioResult)
|
|
||||||
return c, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ioCompletionProcessor processes completed async IOs forever
|
|
||||||
func ioCompletionProcessor(h syscall.Handle) {
|
|
||||||
// Set the timer resolution to 1. This fixes a performance regression in golang 1.6.
|
|
||||||
timeBeginPeriod(1)
|
|
||||||
for {
|
|
||||||
var bytes uint32
|
|
||||||
var key uintptr
|
|
||||||
var op *ioOperation
|
|
||||||
err := getQueuedCompletionStatus(h, &bytes, &key, &op, syscall.INFINITE)
|
|
||||||
if op == nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
op.ch <- ioResult{bytes, err}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// asyncIo processes the return value from ReadFile or WriteFile, blocking until
|
|
||||||
// the operation has actually completed.
|
|
||||||
func (f *win32File) asyncIo(c *ioOperation, deadline time.Time, bytes uint32, err error) (int, error) {
|
|
||||||
if err != syscall.ERROR_IO_PENDING {
|
|
||||||
f.wg.Done()
|
|
||||||
return int(bytes), err
|
|
||||||
} else {
|
|
||||||
var r ioResult
|
|
||||||
wait := true
|
|
||||||
timedout := false
|
|
||||||
if f.closing {
|
|
||||||
cancelIoEx(f.handle, &c.o)
|
|
||||||
} else if !deadline.IsZero() {
|
|
||||||
now := time.Now()
|
|
||||||
if !deadline.After(now) {
|
|
||||||
timedout = true
|
|
||||||
} else {
|
|
||||||
timeout := time.After(deadline.Sub(now))
|
|
||||||
select {
|
|
||||||
case r = <-c.ch:
|
|
||||||
wait = false
|
|
||||||
case <-timeout:
|
|
||||||
timedout = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if timedout {
|
|
||||||
cancelIoEx(f.handle, &c.o)
|
|
||||||
}
|
|
||||||
if wait {
|
|
||||||
r = <-c.ch
|
|
||||||
}
|
|
||||||
err = r.err
|
|
||||||
if err == syscall.ERROR_OPERATION_ABORTED {
|
|
||||||
if f.closing {
|
|
||||||
err = ErrFileClosed
|
|
||||||
} else if timedout {
|
|
||||||
err = ErrTimeout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f.wg.Done()
|
|
||||||
return int(r.bytes), err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads from a file handle.
|
|
||||||
func (f *win32File) Read(b []byte) (int, error) {
|
|
||||||
c, err := f.prepareIo()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
var bytes uint32
|
|
||||||
err = syscall.ReadFile(f.handle, b, &bytes, &c.o)
|
|
||||||
n, err := f.asyncIo(c, f.readDeadline, bytes, err)
|
|
||||||
|
|
||||||
// Handle EOF conditions.
|
|
||||||
if err == nil && n == 0 && len(b) != 0 {
|
|
||||||
return 0, io.EOF
|
|
||||||
} else if err == syscall.ERROR_BROKEN_PIPE {
|
|
||||||
return 0, io.EOF
|
|
||||||
} else {
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write writes to a file handle.
|
|
||||||
func (f *win32File) Write(b []byte) (int, error) {
|
|
||||||
c, err := f.prepareIo()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
var bytes uint32
|
|
||||||
err = syscall.WriteFile(f.handle, b, &bytes, &c.o)
|
|
||||||
return f.asyncIo(c, f.writeDeadline, bytes, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *win32File) SetReadDeadline(t time.Time) error {
|
|
||||||
f.readDeadline = t
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *win32File) SetWriteDeadline(t time.Time) error {
|
|
||||||
f.writeDeadline = t
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
54
Godeps/_workspace/src/github.com/microsoft/go-winio/fileinfo.go
generated
vendored
54
Godeps/_workspace/src/github.com/microsoft/go-winio/fileinfo.go
generated
vendored
@@ -1,54 +0,0 @@
|
|||||||
package winio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
//sys getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = GetFileInformationByHandleEx
|
|
||||||
//sys setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = SetFileInformationByHandle
|
|
||||||
|
|
||||||
const (
|
|
||||||
fileBasicInfo = 0
|
|
||||||
fileIDInfo = 0x12
|
|
||||||
)
|
|
||||||
|
|
||||||
// FileBasicInfo contains file access time and file attributes information.
|
|
||||||
type FileBasicInfo struct {
|
|
||||||
CreationTime, LastAccessTime, LastWriteTime, ChangeTime syscall.Filetime
|
|
||||||
FileAttributes uintptr // includes padding
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetFileBasicInfo retrieves times and attributes for a file.
|
|
||||||
func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
|
|
||||||
bi := &FileBasicInfo{}
|
|
||||||
if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
|
|
||||||
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
|
|
||||||
}
|
|
||||||
return bi, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetFileBasicInfo sets times and attributes for a file.
|
|
||||||
func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error {
|
|
||||||
if err := setFileInformationByHandle(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
|
|
||||||
return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileIDInfo contains the volume serial number and file ID for a file. This pair should be
|
|
||||||
// unique on a system.
|
|
||||||
type FileIDInfo struct {
|
|
||||||
VolumeSerialNumber uint64
|
|
||||||
FileID [16]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetFileID retrieves the unique (volume, file ID) pair for a file.
|
|
||||||
func GetFileID(f *os.File) (*FileIDInfo, error) {
|
|
||||||
fileID := &FileIDInfo{}
|
|
||||||
if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileIDInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil {
|
|
||||||
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
|
|
||||||
}
|
|
||||||
return fileID, nil
|
|
||||||
}
|
|
||||||
398
Godeps/_workspace/src/github.com/microsoft/go-winio/pipe.go
generated
vendored
398
Godeps/_workspace/src/github.com/microsoft/go-winio/pipe.go
generated
vendored
@@ -1,398 +0,0 @@
|
|||||||
package winio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
//sys connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) = ConnectNamedPipe
|
|
||||||
//sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateNamedPipeW
|
|
||||||
//sys createFile(name string, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateFileW
|
|
||||||
//sys waitNamedPipe(name string, timeout uint32) (err error) = WaitNamedPipeW
|
|
||||||
//sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo
|
|
||||||
//sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
|
|
||||||
|
|
||||||
type securityAttributes struct {
|
|
||||||
Length uint32
|
|
||||||
SecurityDescriptor *byte
|
|
||||||
InheritHandle uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
cERROR_PIPE_BUSY = syscall.Errno(231)
|
|
||||||
cERROR_PIPE_CONNECTED = syscall.Errno(535)
|
|
||||||
cERROR_SEM_TIMEOUT = syscall.Errno(121)
|
|
||||||
|
|
||||||
cPIPE_ACCESS_DUPLEX = 0x3
|
|
||||||
cFILE_FLAG_FIRST_PIPE_INSTANCE = 0x80000
|
|
||||||
cSECURITY_SQOS_PRESENT = 0x100000
|
|
||||||
cSECURITY_ANONYMOUS = 0
|
|
||||||
|
|
||||||
cPIPE_REJECT_REMOTE_CLIENTS = 0x8
|
|
||||||
|
|
||||||
cPIPE_UNLIMITED_INSTANCES = 255
|
|
||||||
|
|
||||||
cNMPWAIT_USE_DEFAULT_WAIT = 0
|
|
||||||
cNMPWAIT_NOWAIT = 1
|
|
||||||
|
|
||||||
cPIPE_TYPE_MESSAGE = 4
|
|
||||||
|
|
||||||
cPIPE_READMODE_MESSAGE = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrPipeListenerClosed is returned for pipe operations on listeners that have been closed.
|
|
||||||
// This error should match net.errClosing since docker takes a dependency on its text.
|
|
||||||
ErrPipeListenerClosed = errors.New("use of closed network connection")
|
|
||||||
|
|
||||||
errPipeWriteClosed = errors.New("pipe has been closed for write")
|
|
||||||
)
|
|
||||||
|
|
||||||
type win32Pipe struct {
|
|
||||||
*win32File
|
|
||||||
path string
|
|
||||||
}
|
|
||||||
|
|
||||||
type win32MessageBytePipe struct {
|
|
||||||
win32Pipe
|
|
||||||
writeClosed bool
|
|
||||||
readEOF bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type pipeAddress string
|
|
||||||
|
|
||||||
func (f *win32Pipe) LocalAddr() net.Addr {
|
|
||||||
return pipeAddress(f.path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *win32Pipe) RemoteAddr() net.Addr {
|
|
||||||
return pipeAddress(f.path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *win32Pipe) SetDeadline(t time.Time) error {
|
|
||||||
f.SetReadDeadline(t)
|
|
||||||
f.SetWriteDeadline(t)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CloseWrite closes the write side of a message pipe in byte mode.
|
|
||||||
func (f *win32MessageBytePipe) CloseWrite() error {
|
|
||||||
if f.writeClosed {
|
|
||||||
return errPipeWriteClosed
|
|
||||||
}
|
|
||||||
_, err := f.win32File.Write(nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
f.writeClosed = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write writes bytes to a message pipe in byte mode. Zero-byte writes are ignored, since
|
|
||||||
// they are used to implement CloseWrite().
|
|
||||||
func (f *win32MessageBytePipe) Write(b []byte) (int, error) {
|
|
||||||
if f.writeClosed {
|
|
||||||
return 0, errPipeWriteClosed
|
|
||||||
}
|
|
||||||
if len(b) == 0 {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return f.win32File.Write(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads bytes from a message pipe in byte mode. A read of a zero-byte message on a message
|
|
||||||
// mode pipe will return io.EOF, as will all subsequent reads.
|
|
||||||
func (f *win32MessageBytePipe) Read(b []byte) (int, error) {
|
|
||||||
if f.readEOF {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
n, err := f.win32File.Read(b)
|
|
||||||
if err == io.EOF {
|
|
||||||
// If this was the result of a zero-byte read, then
|
|
||||||
// it is possible that the read was due to a zero-size
|
|
||||||
// message. Since we are simulating CloseWrite with a
|
|
||||||
// zero-byte message, ensure that all future Read() calls
|
|
||||||
// also return EOF.
|
|
||||||
f.readEOF = true
|
|
||||||
}
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s pipeAddress) Network() string {
|
|
||||||
return "pipe"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s pipeAddress) String() string {
|
|
||||||
return string(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DialPipe connects to a named pipe by path, timing out if the connection
|
|
||||||
// takes longer than the specified duration. If timeout is nil, then the timeout
|
|
||||||
// is the default timeout established by the pipe server.
|
|
||||||
func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
|
|
||||||
var absTimeout time.Time
|
|
||||||
if timeout != nil {
|
|
||||||
absTimeout = time.Now().Add(*timeout)
|
|
||||||
}
|
|
||||||
var err error
|
|
||||||
var h syscall.Handle
|
|
||||||
for {
|
|
||||||
h, err = createFile(path, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_OVERLAPPED|cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0)
|
|
||||||
if err != cERROR_PIPE_BUSY {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
now := time.Now()
|
|
||||||
var ms uint32
|
|
||||||
if absTimeout.IsZero() {
|
|
||||||
ms = cNMPWAIT_USE_DEFAULT_WAIT
|
|
||||||
} else if now.After(absTimeout) {
|
|
||||||
ms = cNMPWAIT_NOWAIT
|
|
||||||
} else {
|
|
||||||
ms = uint32(absTimeout.Sub(now).Nanoseconds() / 1000 / 1000)
|
|
||||||
}
|
|
||||||
err = waitNamedPipe(path, ms)
|
|
||||||
if err != nil {
|
|
||||||
if err == cERROR_SEM_TIMEOUT {
|
|
||||||
return nil, ErrTimeout
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, &os.PathError{Op: "open", Path: path, Err: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
var flags uint32
|
|
||||||
err = getNamedPipeInfo(h, &flags, nil, nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var state uint32
|
|
||||||
err = getNamedPipeHandleState(h, &state, nil, nil, nil, nil, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if state&cPIPE_READMODE_MESSAGE != 0 {
|
|
||||||
return nil, &os.PathError{Op: "open", Path: path, Err: errors.New("message readmode pipes not supported")}
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err := makeWin32File(h)
|
|
||||||
if err != nil {
|
|
||||||
syscall.Close(h)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the pipe is in message mode, return a message byte pipe, which
|
|
||||||
// supports CloseWrite().
|
|
||||||
if flags&cPIPE_TYPE_MESSAGE != 0 {
|
|
||||||
return &win32MessageBytePipe{
|
|
||||||
win32Pipe: win32Pipe{win32File: f, path: path},
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
return &win32Pipe{win32File: f, path: path}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type acceptResponse struct {
|
|
||||||
f *win32File
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
type win32PipeListener struct {
|
|
||||||
firstHandle syscall.Handle
|
|
||||||
path string
|
|
||||||
securityDescriptor []byte
|
|
||||||
config PipeConfig
|
|
||||||
acceptCh chan (chan acceptResponse)
|
|
||||||
closeCh chan int
|
|
||||||
doneCh chan int
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeServerPipeHandle(path string, securityDescriptor []byte, c *PipeConfig, first bool) (syscall.Handle, error) {
|
|
||||||
var flags uint32 = cPIPE_ACCESS_DUPLEX | syscall.FILE_FLAG_OVERLAPPED
|
|
||||||
if first {
|
|
||||||
flags |= cFILE_FLAG_FIRST_PIPE_INSTANCE
|
|
||||||
}
|
|
||||||
|
|
||||||
var mode uint32 = cPIPE_REJECT_REMOTE_CLIENTS
|
|
||||||
if c.MessageMode {
|
|
||||||
mode |= cPIPE_TYPE_MESSAGE
|
|
||||||
}
|
|
||||||
|
|
||||||
var sa securityAttributes
|
|
||||||
sa.Length = uint32(unsafe.Sizeof(sa))
|
|
||||||
if securityDescriptor != nil {
|
|
||||||
sa.SecurityDescriptor = &securityDescriptor[0]
|
|
||||||
}
|
|
||||||
h, err := createNamedPipe(path, flags, mode, cPIPE_UNLIMITED_INSTANCES, uint32(c.OutputBufferSize), uint32(c.InputBufferSize), 0, &sa)
|
|
||||||
if err != nil {
|
|
||||||
return 0, &os.PathError{Op: "open", Path: path, Err: err}
|
|
||||||
}
|
|
||||||
return h, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *win32PipeListener) makeServerPipe() (*win32File, error) {
|
|
||||||
h, err := makeServerPipeHandle(l.path, l.securityDescriptor, &l.config, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
f, err := makeWin32File(h)
|
|
||||||
if err != nil {
|
|
||||||
syscall.Close(h)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return f, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *win32PipeListener) listenerRoutine() {
|
|
||||||
closed := false
|
|
||||||
for !closed {
|
|
||||||
select {
|
|
||||||
case <-l.closeCh:
|
|
||||||
closed = true
|
|
||||||
case responseCh := <-l.acceptCh:
|
|
||||||
p, err := l.makeServerPipe()
|
|
||||||
if err == nil {
|
|
||||||
// Wait for the client to connect.
|
|
||||||
ch := make(chan error)
|
|
||||||
go func() {
|
|
||||||
ch <- connectPipe(p)
|
|
||||||
}()
|
|
||||||
select {
|
|
||||||
case err = <-ch:
|
|
||||||
if err != nil {
|
|
||||||
p.Close()
|
|
||||||
p = nil
|
|
||||||
}
|
|
||||||
case <-l.closeCh:
|
|
||||||
// Abort the connect request by closing the handle.
|
|
||||||
p.Close()
|
|
||||||
p = nil
|
|
||||||
err = <-ch
|
|
||||||
if err == nil || err == ErrFileClosed {
|
|
||||||
err = ErrPipeListenerClosed
|
|
||||||
}
|
|
||||||
closed = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
responseCh <- acceptResponse{p, err}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
syscall.Close(l.firstHandle)
|
|
||||||
l.firstHandle = 0
|
|
||||||
// Notify Close() and Accept() callers that the handle has been closed.
|
|
||||||
close(l.doneCh)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PipeConfig contain configuration for the pipe listener.
|
|
||||||
type PipeConfig struct {
|
|
||||||
// SecurityDescriptor contains a Windows security descriptor in SDDL format.
|
|
||||||
SecurityDescriptor string
|
|
||||||
|
|
||||||
// MessageMode determines whether the pipe is in byte or message mode. In either
|
|
||||||
// case the pipe is read in byte mode by default. The only practical difference in
|
|
||||||
// this implementation is that CloseWrite() is only supported for message mode pipes;
|
|
||||||
// CloseWrite() is implemented as a zero-byte write, but zero-byte writes are only
|
|
||||||
// transferred to the reader (and returned as io.EOF in this implementation)
|
|
||||||
// when the pipe is in message mode.
|
|
||||||
MessageMode bool
|
|
||||||
|
|
||||||
// InputBufferSize specifies the size the input buffer, in bytes.
|
|
||||||
InputBufferSize int32
|
|
||||||
|
|
||||||
// OutputBufferSize specifies the size the input buffer, in bytes.
|
|
||||||
OutputBufferSize int32
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListenPipe creates a listener on a Windows named pipe path, e.g. \\.\pipe\mypipe.
|
|
||||||
// The pipe must not already exist.
|
|
||||||
func ListenPipe(path string, c *PipeConfig) (net.Listener, error) {
|
|
||||||
var (
|
|
||||||
sd []byte
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
if c == nil {
|
|
||||||
c = &PipeConfig{}
|
|
||||||
}
|
|
||||||
if c.SecurityDescriptor != "" {
|
|
||||||
sd, err = SddlToSecurityDescriptor(c.SecurityDescriptor)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
h, err := makeServerPipeHandle(path, sd, c, true)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// Immediately open and then close a client handle so that the named pipe is
|
|
||||||
// created but not currently accepting connections.
|
|
||||||
h2, err := createFile(path, 0, 0, nil, syscall.OPEN_EXISTING, cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0)
|
|
||||||
if err != nil {
|
|
||||||
syscall.Close(h)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
syscall.Close(h2)
|
|
||||||
l := &win32PipeListener{
|
|
||||||
firstHandle: h,
|
|
||||||
path: path,
|
|
||||||
securityDescriptor: sd,
|
|
||||||
config: *c,
|
|
||||||
acceptCh: make(chan (chan acceptResponse)),
|
|
||||||
closeCh: make(chan int),
|
|
||||||
doneCh: make(chan int),
|
|
||||||
}
|
|
||||||
go l.listenerRoutine()
|
|
||||||
return l, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func connectPipe(p *win32File) error {
|
|
||||||
c, err := p.prepareIo()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = connectNamedPipe(p.handle, &c.o)
|
|
||||||
_, err = p.asyncIo(c, time.Time{}, 0, err)
|
|
||||||
if err != nil && err != cERROR_PIPE_CONNECTED {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *win32PipeListener) Accept() (net.Conn, error) {
|
|
||||||
ch := make(chan acceptResponse)
|
|
||||||
select {
|
|
||||||
case l.acceptCh <- ch:
|
|
||||||
response := <-ch
|
|
||||||
err := response.err
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if l.config.MessageMode {
|
|
||||||
return &win32MessageBytePipe{
|
|
||||||
win32Pipe: win32Pipe{win32File: response.f, path: l.path},
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
return &win32Pipe{win32File: response.f, path: l.path}, nil
|
|
||||||
case <-l.doneCh:
|
|
||||||
return nil, ErrPipeListenerClosed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *win32PipeListener) Close() error {
|
|
||||||
select {
|
|
||||||
case l.closeCh <- 1:
|
|
||||||
<-l.doneCh
|
|
||||||
case <-l.doneCh:
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *win32PipeListener) Addr() net.Addr {
|
|
||||||
return pipeAddress(l.path)
|
|
||||||
}
|
|
||||||
150
Godeps/_workspace/src/github.com/microsoft/go-winio/privilege.go
generated
vendored
150
Godeps/_workspace/src/github.com/microsoft/go-winio/privilege.go
generated
vendored
@@ -1,150 +0,0 @@
|
|||||||
package winio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
|
||||||
"runtime"
|
|
||||||
"syscall"
|
|
||||||
"unicode/utf16"
|
|
||||||
)
|
|
||||||
|
|
||||||
//sys adjustTokenPrivileges(token syscall.Handle, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges
|
|
||||||
//sys impersonateSelf(level uint32) (err error) = advapi32.ImpersonateSelf
|
|
||||||
//sys revertToSelf() (err error) = advapi32.RevertToSelf
|
|
||||||
//sys openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *syscall.Handle) (err error) = advapi32.OpenThreadToken
|
|
||||||
//sys getCurrentThread() (h syscall.Handle) = GetCurrentThread
|
|
||||||
//sys lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) = advapi32.LookupPrivilegeValueW
|
|
||||||
//sys lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) = advapi32.LookupPrivilegeNameW
|
|
||||||
//sys lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) = advapi32.LookupPrivilegeDisplayNameW
|
|
||||||
|
|
||||||
const (
|
|
||||||
SE_PRIVILEGE_ENABLED = 2
|
|
||||||
|
|
||||||
ERROR_NOT_ALL_ASSIGNED syscall.Errno = 1300
|
|
||||||
|
|
||||||
SeBackupPrivilege = "SeBackupPrivilege"
|
|
||||||
SeRestorePrivilege = "SeRestorePrivilege"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
securityAnonymous = iota
|
|
||||||
securityIdentification
|
|
||||||
securityImpersonation
|
|
||||||
securityDelegation
|
|
||||||
)
|
|
||||||
|
|
||||||
type PrivilegeError struct {
|
|
||||||
privileges []uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *PrivilegeError) Error() string {
|
|
||||||
s := ""
|
|
||||||
if len(e.privileges) > 1 {
|
|
||||||
s = "Could not enable privileges "
|
|
||||||
} else {
|
|
||||||
s = "Could not enable privilege "
|
|
||||||
}
|
|
||||||
for i, p := range e.privileges {
|
|
||||||
if i != 0 {
|
|
||||||
s += ", "
|
|
||||||
}
|
|
||||||
s += `"`
|
|
||||||
s += getPrivilegeName(p)
|
|
||||||
s += `"`
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func RunWithPrivilege(name string, fn func() error) error {
|
|
||||||
return RunWithPrivileges([]string{name}, fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func RunWithPrivileges(names []string, fn func() error) error {
|
|
||||||
var privileges []uint64
|
|
||||||
for _, name := range names {
|
|
||||||
p := uint64(0)
|
|
||||||
err := lookupPrivilegeValue("", name, &p)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
privileges = append(privileges, p)
|
|
||||||
}
|
|
||||||
runtime.LockOSThread()
|
|
||||||
defer runtime.UnlockOSThread()
|
|
||||||
token, err := newThreadToken()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer releaseThreadToken(token)
|
|
||||||
err = adjustPrivileges(token, privileges)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return fn()
|
|
||||||
}
|
|
||||||
|
|
||||||
func adjustPrivileges(token syscall.Handle, privileges []uint64) error {
|
|
||||||
var b bytes.Buffer
|
|
||||||
binary.Write(&b, binary.LittleEndian, uint32(len(privileges)))
|
|
||||||
for _, p := range privileges {
|
|
||||||
binary.Write(&b, binary.LittleEndian, p)
|
|
||||||
binary.Write(&b, binary.LittleEndian, uint32(SE_PRIVILEGE_ENABLED))
|
|
||||||
}
|
|
||||||
prevState := make([]byte, b.Len())
|
|
||||||
reqSize := uint32(0)
|
|
||||||
success, err := adjustTokenPrivileges(token, false, &b.Bytes()[0], uint32(len(prevState)), &prevState[0], &reqSize)
|
|
||||||
if !success {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err == ERROR_NOT_ALL_ASSIGNED {
|
|
||||||
return &PrivilegeError{privileges}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getPrivilegeName(luid uint64) string {
|
|
||||||
var nameBuffer [256]uint16
|
|
||||||
bufSize := uint32(len(nameBuffer))
|
|
||||||
err := lookupPrivilegeName("", &luid, &nameBuffer[0], &bufSize)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("<unknown privilege %d>", luid)
|
|
||||||
}
|
|
||||||
|
|
||||||
var displayNameBuffer [256]uint16
|
|
||||||
displayBufSize := uint32(len(displayNameBuffer))
|
|
||||||
var langId uint32
|
|
||||||
err = lookupPrivilegeDisplayName("", &nameBuffer[0], &displayNameBuffer[0], &displayBufSize, &langId)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Sprintf("<unknown privilege %s>", utf16.Decode(nameBuffer[:bufSize]))
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(utf16.Decode(displayNameBuffer[:displayBufSize]))
|
|
||||||
}
|
|
||||||
|
|
||||||
func newThreadToken() (syscall.Handle, error) {
|
|
||||||
err := impersonateSelf(securityImpersonation)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var token syscall.Handle
|
|
||||||
err = openThreadToken(getCurrentThread(), syscall.TOKEN_ADJUST_PRIVILEGES|syscall.TOKEN_QUERY, false, &token)
|
|
||||||
if err != nil {
|
|
||||||
rerr := revertToSelf()
|
|
||||||
if rerr != nil {
|
|
||||||
panic(rerr)
|
|
||||||
}
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return token, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func releaseThreadToken(h syscall.Handle) {
|
|
||||||
err := revertToSelf()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
syscall.Close(h)
|
|
||||||
}
|
|
||||||
124
Godeps/_workspace/src/github.com/microsoft/go-winio/reparse.go
generated
vendored
124
Godeps/_workspace/src/github.com/microsoft/go-winio/reparse.go
generated
vendored
@@ -1,124 +0,0 @@
|
|||||||
package winio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"unicode/utf16"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
reparseTagMountPoint = 0xA0000003
|
|
||||||
reparseTagSymlink = 0xA000000C
|
|
||||||
)
|
|
||||||
|
|
||||||
type reparseDataBuffer struct {
|
|
||||||
ReparseTag uint32
|
|
||||||
ReparseDataLength uint16
|
|
||||||
Reserved uint16
|
|
||||||
SubstituteNameOffset uint16
|
|
||||||
SubstituteNameLength uint16
|
|
||||||
PrintNameOffset uint16
|
|
||||||
PrintNameLength uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReparsePoint describes a Win32 symlink or mount point.
|
|
||||||
type ReparsePoint struct {
|
|
||||||
Target string
|
|
||||||
IsMountPoint bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnsupportedReparsePointError is returned when trying to decode a non-symlink or
|
|
||||||
// mount point reparse point.
|
|
||||||
type UnsupportedReparsePointError struct {
|
|
||||||
Tag uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *UnsupportedReparsePointError) Error() string {
|
|
||||||
return fmt.Sprintf("unsupported reparse point %x", e.Tag)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeReparsePoint decodes a Win32 REPARSE_DATA_BUFFER structure containing either a symlink
|
|
||||||
// or a mount point.
|
|
||||||
func DecodeReparsePoint(b []byte) (*ReparsePoint, error) {
|
|
||||||
isMountPoint := false
|
|
||||||
tag := binary.LittleEndian.Uint32(b[0:4])
|
|
||||||
switch tag {
|
|
||||||
case reparseTagMountPoint:
|
|
||||||
isMountPoint = true
|
|
||||||
case reparseTagSymlink:
|
|
||||||
default:
|
|
||||||
return nil, &UnsupportedReparsePointError{tag}
|
|
||||||
}
|
|
||||||
nameOffset := 16 + binary.LittleEndian.Uint16(b[12:14])
|
|
||||||
if !isMountPoint {
|
|
||||||
nameOffset += 4
|
|
||||||
}
|
|
||||||
nameLength := binary.LittleEndian.Uint16(b[14:16])
|
|
||||||
name := make([]uint16, nameLength/2)
|
|
||||||
err := binary.Read(bytes.NewReader(b[nameOffset:nameOffset+nameLength]), binary.LittleEndian, &name)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &ReparsePoint{string(utf16.Decode(name)), isMountPoint}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func isDriveLetter(c byte) bool {
|
|
||||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeReparsePoint encodes a Win32 REPARSE_DATA_BUFFER structure describing a symlink or
|
|
||||||
// mount point.
|
|
||||||
func EncodeReparsePoint(rp *ReparsePoint) []byte {
|
|
||||||
// Generate an NT path and determine if this is a relative path.
|
|
||||||
var ntTarget string
|
|
||||||
relative := false
|
|
||||||
if strings.HasPrefix(rp.Target, `\\?\`) {
|
|
||||||
ntTarget = rp.Target
|
|
||||||
} else if strings.HasPrefix(rp.Target, `\\`) {
|
|
||||||
ntTarget = `\??\UNC\` + rp.Target[2:]
|
|
||||||
} else if len(rp.Target) >= 2 && isDriveLetter(rp.Target[0]) && rp.Target[1] == ':' {
|
|
||||||
ntTarget = `\??\` + rp.Target
|
|
||||||
} else {
|
|
||||||
ntTarget = rp.Target
|
|
||||||
relative = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// The paths must be NUL-terminated even though they are counted strings.
|
|
||||||
target16 := utf16.Encode([]rune(rp.Target + "\x00"))
|
|
||||||
ntTarget16 := utf16.Encode([]rune(ntTarget + "\x00"))
|
|
||||||
|
|
||||||
size := int(unsafe.Sizeof(reparseDataBuffer{})) - 8
|
|
||||||
size += len(ntTarget16)*2 + len(target16)*2
|
|
||||||
|
|
||||||
tag := uint32(reparseTagMountPoint)
|
|
||||||
if !rp.IsMountPoint {
|
|
||||||
tag = reparseTagSymlink
|
|
||||||
size += 4 // Add room for symlink flags
|
|
||||||
}
|
|
||||||
|
|
||||||
data := reparseDataBuffer{
|
|
||||||
ReparseTag: tag,
|
|
||||||
ReparseDataLength: uint16(size),
|
|
||||||
SubstituteNameOffset: 0,
|
|
||||||
SubstituteNameLength: uint16((len(ntTarget16) - 1) * 2),
|
|
||||||
PrintNameOffset: uint16(len(ntTarget16) * 2),
|
|
||||||
PrintNameLength: uint16((len(target16) - 1) * 2),
|
|
||||||
}
|
|
||||||
|
|
||||||
var b bytes.Buffer
|
|
||||||
binary.Write(&b, binary.LittleEndian, &data)
|
|
||||||
if !rp.IsMountPoint {
|
|
||||||
flags := uint32(0)
|
|
||||||
if relative {
|
|
||||||
flags |= 1
|
|
||||||
}
|
|
||||||
binary.Write(&b, binary.LittleEndian, flags)
|
|
||||||
}
|
|
||||||
|
|
||||||
binary.Write(&b, binary.LittleEndian, ntTarget16)
|
|
||||||
binary.Write(&b, binary.LittleEndian, target16)
|
|
||||||
return b.Bytes()
|
|
||||||
}
|
|
||||||
96
Godeps/_workspace/src/github.com/microsoft/go-winio/sd.go
generated
vendored
96
Godeps/_workspace/src/github.com/microsoft/go-winio/sd.go
generated
vendored
@@ -1,96 +0,0 @@
|
|||||||
package winio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
//sys lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) = advapi32.LookupAccountNameW
|
|
||||||
//sys convertSidToStringSid(sid *byte, str **uint16) (err error) = advapi32.ConvertSidToStringSidW
|
|
||||||
//sys convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW
|
|
||||||
//sys convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) = advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorW
|
|
||||||
//sys localFree(mem uintptr) = LocalFree
|
|
||||||
//sys getSecurityDescriptorLength(sd uintptr) (len uint32) = advapi32.GetSecurityDescriptorLength
|
|
||||||
|
|
||||||
const (
|
|
||||||
cERROR_NONE_MAPPED = syscall.Errno(1332)
|
|
||||||
)
|
|
||||||
|
|
||||||
type AccountLookupError struct {
|
|
||||||
Name string
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *AccountLookupError) Error() string {
|
|
||||||
if e.Name == "" {
|
|
||||||
return "lookup account: empty account name specified"
|
|
||||||
}
|
|
||||||
var s string
|
|
||||||
switch e.Err {
|
|
||||||
case cERROR_NONE_MAPPED:
|
|
||||||
s = "not found"
|
|
||||||
default:
|
|
||||||
s = e.Err.Error()
|
|
||||||
}
|
|
||||||
return "lookup account " + e.Name + ": " + s
|
|
||||||
}
|
|
||||||
|
|
||||||
type SddlConversionError struct {
|
|
||||||
Sddl string
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *SddlConversionError) Error() string {
|
|
||||||
return "convert " + e.Sddl + ": " + e.Err.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// LookupSidByName looks up the SID of an account by name
|
|
||||||
func LookupSidByName(name string) (sid string, err error) {
|
|
||||||
if name == "" {
|
|
||||||
return "", &AccountLookupError{name, cERROR_NONE_MAPPED}
|
|
||||||
}
|
|
||||||
|
|
||||||
var sidSize, sidNameUse, refDomainSize uint32
|
|
||||||
err = lookupAccountName(nil, name, nil, &sidSize, nil, &refDomainSize, &sidNameUse)
|
|
||||||
if err != nil && err != syscall.ERROR_INSUFFICIENT_BUFFER {
|
|
||||||
return "", &AccountLookupError{name, err}
|
|
||||||
}
|
|
||||||
sidBuffer := make([]byte, sidSize)
|
|
||||||
refDomainBuffer := make([]uint16, refDomainSize)
|
|
||||||
err = lookupAccountName(nil, name, &sidBuffer[0], &sidSize, &refDomainBuffer[0], &refDomainSize, &sidNameUse)
|
|
||||||
if err != nil {
|
|
||||||
return "", &AccountLookupError{name, err}
|
|
||||||
}
|
|
||||||
var strBuffer *uint16
|
|
||||||
err = convertSidToStringSid(&sidBuffer[0], &strBuffer)
|
|
||||||
if err != nil {
|
|
||||||
return "", &AccountLookupError{name, err}
|
|
||||||
}
|
|
||||||
sid = syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(strBuffer))[:])
|
|
||||||
localFree(uintptr(unsafe.Pointer(strBuffer)))
|
|
||||||
return sid, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func SddlToSecurityDescriptor(sddl string) ([]byte, error) {
|
|
||||||
var sdBuffer uintptr
|
|
||||||
err := convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &sdBuffer, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, &SddlConversionError{sddl, err}
|
|
||||||
}
|
|
||||||
defer localFree(sdBuffer)
|
|
||||||
sd := make([]byte, getSecurityDescriptorLength(sdBuffer))
|
|
||||||
copy(sd, (*[0xffff]byte)(unsafe.Pointer(sdBuffer))[:len(sd)])
|
|
||||||
return sd, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func SecurityDescriptorToSddl(sd []byte) (string, error) {
|
|
||||||
var sddl *uint16
|
|
||||||
// The returned string length seems to including an aribtrary number of terminating NULs.
|
|
||||||
// Don't use it.
|
|
||||||
err := convertSecurityDescriptorToStringSecurityDescriptor(&sd[0], 1, 0xff, &sddl, nil)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
defer localFree(uintptr(unsafe.Pointer(sddl)))
|
|
||||||
return syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(sddl))[:]), nil
|
|
||||||
}
|
|
||||||
3
Godeps/_workspace/src/github.com/microsoft/go-winio/syscall.go
generated
vendored
3
Godeps/_workspace/src/github.com/microsoft/go-winio/syscall.go
generated
vendored
@@ -1,3 +0,0 @@
|
|||||||
package winio
|
|
||||||
|
|
||||||
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go
|
|
||||||
492
Godeps/_workspace/src/github.com/microsoft/go-winio/zsyscall.go
generated
vendored
492
Godeps/_workspace/src/github.com/microsoft/go-winio/zsyscall.go
generated
vendored
@@ -1,492 +0,0 @@
|
|||||||
// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
|
|
||||||
|
|
||||||
package winio
|
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
var _ unsafe.Pointer
|
|
||||||
|
|
||||||
var (
|
|
||||||
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
||||||
modwinmm = syscall.NewLazyDLL("winmm.dll")
|
|
||||||
modadvapi32 = syscall.NewLazyDLL("advapi32.dll")
|
|
||||||
|
|
||||||
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
|
|
||||||
procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
|
|
||||||
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
|
|
||||||
procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
|
|
||||||
proctimeBeginPeriod = modwinmm.NewProc("timeBeginPeriod")
|
|
||||||
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
|
|
||||||
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
|
|
||||||
procCreateFileW = modkernel32.NewProc("CreateFileW")
|
|
||||||
procWaitNamedPipeW = modkernel32.NewProc("WaitNamedPipeW")
|
|
||||||
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
|
|
||||||
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
|
|
||||||
procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
|
|
||||||
procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
|
|
||||||
procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
|
|
||||||
procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW")
|
|
||||||
procLocalFree = modkernel32.NewProc("LocalFree")
|
|
||||||
procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength")
|
|
||||||
procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx")
|
|
||||||
procSetFileInformationByHandle = modkernel32.NewProc("SetFileInformationByHandle")
|
|
||||||
procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
|
|
||||||
procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf")
|
|
||||||
procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
|
|
||||||
procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
|
|
||||||
procGetCurrentThread = modkernel32.NewProc("GetCurrentThread")
|
|
||||||
procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
|
|
||||||
procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW")
|
|
||||||
procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW")
|
|
||||||
procBackupRead = modkernel32.NewProc("BackupRead")
|
|
||||||
procBackupWrite = modkernel32.NewProc("BackupWrite")
|
|
||||||
)
|
|
||||||
|
|
||||||
func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) {
|
|
||||||
r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0)
|
|
||||||
newport = syscall.Handle(r0)
|
|
||||||
if newport == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func timeBeginPeriod(period uint32) (n int32) {
|
|
||||||
r0, _, _ := syscall.Syscall(proctimeBeginPeriod.Addr(), 1, uintptr(period), 0, 0)
|
|
||||||
n = int32(r0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(name)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) {
|
|
||||||
r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0)
|
|
||||||
handle = syscall.Handle(r0)
|
|
||||||
if handle == syscall.InvalidHandle {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func createFile(name string, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(name)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _createFile(_p0, access, mode, sa, createmode, attrs, templatefile)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _createFile(name *uint16, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
|
|
||||||
r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
|
|
||||||
handle = syscall.Handle(r0)
|
|
||||||
if handle == syscall.InvalidHandle {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func waitNamedPipe(name string, timeout uint32) (err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(name)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _waitNamedPipe(_p0, timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _waitNamedPipe(name *uint16, timeout uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procWaitNamedPipeW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(timeout), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(accountName)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertSidToStringSid(sid *byte, str **uint16) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(str)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _convertStringSecurityDescriptorToSecurityDescriptor(_p0, revision, sd, size)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd *uintptr, size *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func localFree(mem uintptr) {
|
|
||||||
syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSecurityDescriptorLength(sd uintptr) (len uint32) {
|
|
||||||
r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(sd), 0, 0)
|
|
||||||
len = uint32(r0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func adjustTokenPrivileges(token syscall.Handle, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {
|
|
||||||
var _p0 uint32
|
|
||||||
if releaseAll {
|
|
||||||
_p0 = 1
|
|
||||||
} else {
|
|
||||||
_p0 = 0
|
|
||||||
}
|
|
||||||
r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize)))
|
|
||||||
success = r0 != 0
|
|
||||||
if true {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func impersonateSelf(level uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func revertToSelf() (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *syscall.Handle) (err error) {
|
|
||||||
var _p0 uint32
|
|
||||||
if openAsSelf {
|
|
||||||
_p0 = 1
|
|
||||||
} else {
|
|
||||||
_p0 = 0
|
|
||||||
}
|
|
||||||
r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCurrentThread() (h syscall.Handle) {
|
|
||||||
r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0)
|
|
||||||
h = syscall.Handle(r0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(systemName)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var _p1 *uint16
|
|
||||||
_p1, err = syscall.UTF16PtrFromString(name)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _lookupPrivilegeValue(_p0, _p1, luid)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(systemName)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _lookupPrivilegeName(_p0, luid, buffer, size)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(systemName)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
|
|
||||||
var _p0 *byte
|
|
||||||
if len(b) > 0 {
|
|
||||||
_p0 = &b[0]
|
|
||||||
}
|
|
||||||
var _p1 uint32
|
|
||||||
if abort {
|
|
||||||
_p1 = 1
|
|
||||||
} else {
|
|
||||||
_p1 = 0
|
|
||||||
}
|
|
||||||
var _p2 uint32
|
|
||||||
if processSecurity {
|
|
||||||
_p2 = 1
|
|
||||||
} else {
|
|
||||||
_p2 = 0
|
|
||||||
}
|
|
||||||
r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
|
|
||||||
var _p0 *byte
|
|
||||||
if len(b) > 0 {
|
|
||||||
_p0 = &b[0]
|
|
||||||
}
|
|
||||||
var _p1 uint32
|
|
||||||
if abort {
|
|
||||||
_p1 = 1
|
|
||||||
} else {
|
|
||||||
_p1 = 0
|
|
||||||
}
|
|
||||||
var _p2 uint32
|
|
||||||
if processSecurity {
|
|
||||||
_p2 = 1
|
|
||||||
} else {
|
|
||||||
_p2 = 0
|
|
||||||
}
|
|
||||||
r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
10
Godeps/_workspace/src/github.com/pborman/uuid/.travis.yml
generated
vendored
10
Godeps/_workspace/src/github.com/pborman/uuid/.travis.yml
generated
vendored
@@ -1,10 +0,0 @@
|
|||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- 1.4.3
|
|
||||||
- 1.5.3
|
|
||||||
- release
|
|
||||||
- tip
|
|
||||||
|
|
||||||
script:
|
|
||||||
- go test -v ./...
|
|
||||||
34
Godeps/_workspace/src/github.com/pborman/uuid/json.go
generated
vendored
34
Godeps/_workspace/src/github.com/pborman/uuid/json.go
generated
vendored
@@ -1,34 +0,0 @@
|
|||||||
// Copyright 2014 Google Inc. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package uuid
|
|
||||||
|
|
||||||
import "errors"
|
|
||||||
|
|
||||||
func (u UUID) MarshalJSON() ([]byte, error) {
|
|
||||||
if len(u) != 16 {
|
|
||||||
return []byte(`""`), nil
|
|
||||||
}
|
|
||||||
var js [38]byte
|
|
||||||
js[0] = '"'
|
|
||||||
encodeHex(js[1:], u)
|
|
||||||
js[37] = '"'
|
|
||||||
return js[:], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *UUID) UnmarshalJSON(data []byte) error {
|
|
||||||
if string(data) == `""` {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if data[0] != '"' {
|
|
||||||
return errors.New("invalid UUID format")
|
|
||||||
}
|
|
||||||
data = data[1 : len(data)-1]
|
|
||||||
uu := Parse(string(data))
|
|
||||||
if uu == nil {
|
|
||||||
return errors.New("invalid UUID format")
|
|
||||||
}
|
|
||||||
*u = uu
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
12
Godeps/_workspace/src/github.com/peterh/liner/signal.go
generated
vendored
12
Godeps/_workspace/src/github.com/peterh/liner/signal.go
generated
vendored
@@ -1,12 +0,0 @@
|
|||||||
// +build go1.1,!windows
|
|
||||||
|
|
||||||
package liner
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
)
|
|
||||||
|
|
||||||
func stopSignal(c chan<- os.Signal) {
|
|
||||||
signal.Stop(c)
|
|
||||||
}
|
|
||||||
11
Godeps/_workspace/src/github.com/peterh/liner/signal_legacy.go
generated
vendored
11
Godeps/_workspace/src/github.com/peterh/liner/signal_legacy.go
generated
vendored
@@ -1,11 +0,0 @@
|
|||||||
// +build !go1.1,!windows
|
|
||||||
|
|
||||||
package liner
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
func stopSignal(c chan<- os.Signal) {
|
|
||||||
// signal.Stop does not exist before Go 1.1
|
|
||||||
}
|
|
||||||
9
Godeps/_workspace/src/github.com/rcrowley/go-metrics/.gitignore
generated
vendored
9
Godeps/_workspace/src/github.com/rcrowley/go-metrics/.gitignore
generated
vendored
@@ -1,9 +0,0 @@
|
|||||||
*.[68]
|
|
||||||
*.a
|
|
||||||
*.out
|
|
||||||
*.swp
|
|
||||||
_obj
|
|
||||||
_testmain.go
|
|
||||||
cmd/metrics-bench/metrics-bench
|
|
||||||
cmd/metrics-example/metrics-example
|
|
||||||
cmd/never-read/never-read
|
|
||||||
14
Godeps/_workspace/src/github.com/rcrowley/go-metrics/.travis.yml
generated
vendored
14
Godeps/_workspace/src/github.com/rcrowley/go-metrics/.travis.yml
generated
vendored
@@ -1,14 +0,0 @@
|
|||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- 1.2
|
|
||||||
- 1.3
|
|
||||||
- 1.4
|
|
||||||
- 1.5
|
|
||||||
|
|
||||||
script:
|
|
||||||
- ./validate.sh
|
|
||||||
|
|
||||||
# this should give us faster builds according to
|
|
||||||
# http://docs.travis-ci.com/user/migrating-from-legacy/
|
|
||||||
sudo: false
|
|
||||||
20
Godeps/_workspace/src/github.com/rcrowley/go-metrics/cmd/metrics-bench/metrics-bench.go
generated
vendored
20
Godeps/_workspace/src/github.com/rcrowley/go-metrics/cmd/metrics-bench/metrics-bench.go
generated
vendored
@@ -1,20 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/rcrowley/go-metrics"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
r := metrics.NewRegistry()
|
|
||||||
for i := 0; i < 10000; i++ {
|
|
||||||
r.Register(fmt.Sprintf("counter-%d", i), metrics.NewCounter())
|
|
||||||
r.Register(fmt.Sprintf("gauge-%d", i), metrics.NewGauge())
|
|
||||||
r.Register(fmt.Sprintf("gaugefloat64-%d", i), metrics.NewGaugeFloat64())
|
|
||||||
r.Register(fmt.Sprintf("histogram-uniform-%d", i), metrics.NewHistogram(metrics.NewUniformSample(1028)))
|
|
||||||
r.Register(fmt.Sprintf("histogram-exp-%d", i), metrics.NewHistogram(metrics.NewExpDecaySample(1028, 0.015)))
|
|
||||||
r.Register(fmt.Sprintf("meter-%d", i), metrics.NewMeter())
|
|
||||||
}
|
|
||||||
time.Sleep(600e9)
|
|
||||||
}
|
|
||||||
154
Godeps/_workspace/src/github.com/rcrowley/go-metrics/cmd/metrics-example/metrics-example.go
generated
vendored
154
Godeps/_workspace/src/github.com/rcrowley/go-metrics/cmd/metrics-example/metrics-example.go
generated
vendored
@@ -1,154 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"github.com/rcrowley/go-metrics"
|
|
||||||
// "github.com/rcrowley/go-metrics/stathat"
|
|
||||||
"log"
|
|
||||||
"math/rand"
|
|
||||||
"os"
|
|
||||||
// "syslog"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const fanout = 10
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
|
|
||||||
r := metrics.NewRegistry()
|
|
||||||
|
|
||||||
c := metrics.NewCounter()
|
|
||||||
r.Register("foo", c)
|
|
||||||
for i := 0; i < fanout; i++ {
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
c.Dec(19)
|
|
||||||
time.Sleep(300e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
c.Inc(47)
|
|
||||||
time.Sleep(400e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
g := metrics.NewGauge()
|
|
||||||
r.Register("bar", g)
|
|
||||||
for i := 0; i < fanout; i++ {
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
g.Update(19)
|
|
||||||
time.Sleep(300e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
g.Update(47)
|
|
||||||
time.Sleep(400e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
gf := metrics.NewGaugeFloat64()
|
|
||||||
r.Register("barfloat64", gf)
|
|
||||||
for i := 0; i < fanout; i++ {
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
g.Update(19.0)
|
|
||||||
time.Sleep(300e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
g.Update(47.0)
|
|
||||||
time.Sleep(400e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
hc := metrics.NewHealthcheck(func(h metrics.Healthcheck) {
|
|
||||||
if 0 < rand.Intn(2) {
|
|
||||||
h.Healthy()
|
|
||||||
} else {
|
|
||||||
h.Unhealthy(errors.New("baz"))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
r.Register("baz", hc)
|
|
||||||
|
|
||||||
s := metrics.NewExpDecaySample(1028, 0.015)
|
|
||||||
//s := metrics.NewUniformSample(1028)
|
|
||||||
h := metrics.NewHistogram(s)
|
|
||||||
r.Register("bang", h)
|
|
||||||
for i := 0; i < fanout; i++ {
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
h.Update(19)
|
|
||||||
time.Sleep(300e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
h.Update(47)
|
|
||||||
time.Sleep(400e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
m := metrics.NewMeter()
|
|
||||||
r.Register("quux", m)
|
|
||||||
for i := 0; i < fanout; i++ {
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
m.Mark(19)
|
|
||||||
time.Sleep(300e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
m.Mark(47)
|
|
||||||
time.Sleep(400e6)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
t := metrics.NewTimer()
|
|
||||||
r.Register("hooah", t)
|
|
||||||
for i := 0; i < fanout; i++ {
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
t.Time(func() { time.Sleep(300e6) })
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
t.Time(func() { time.Sleep(400e6) })
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
metrics.RegisterDebugGCStats(r)
|
|
||||||
go metrics.CaptureDebugGCStats(r, 5e9)
|
|
||||||
|
|
||||||
metrics.RegisterRuntimeMemStats(r)
|
|
||||||
go metrics.CaptureRuntimeMemStats(r, 5e9)
|
|
||||||
|
|
||||||
metrics.Log(r, 60e9, log.New(os.Stderr, "metrics: ", log.Lmicroseconds))
|
|
||||||
|
|
||||||
/*
|
|
||||||
w, err := syslog.Dial("unixgram", "/dev/log", syslog.LOG_INFO, "metrics")
|
|
||||||
if nil != err { log.Fatalln(err) }
|
|
||||||
metrics.Syslog(r, 60e9, w)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
addr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:2003")
|
|
||||||
metrics.Graphite(r, 10e9, "metrics", addr)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
stathat.Stathat(r, 10e9, "example@example.com")
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
||||||
22
Godeps/_workspace/src/github.com/rcrowley/go-metrics/cmd/never-read/never-read.go
generated
vendored
22
Godeps/_workspace/src/github.com/rcrowley/go-metrics/cmd/never-read/never-read.go
generated
vendored
@@ -1,22 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"net"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
addr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:2003")
|
|
||||||
l, err := net.ListenTCP("tcp", addr)
|
|
||||||
if nil != err {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
log.Println("listening", l.Addr())
|
|
||||||
for {
|
|
||||||
c, err := l.AcceptTCP()
|
|
||||||
if nil != err {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
log.Println("accepted", c.RemoteAddr())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
102
Godeps/_workspace/src/github.com/rcrowley/go-metrics/librato/client.go
generated
vendored
102
Godeps/_workspace/src/github.com/rcrowley/go-metrics/librato/client.go
generated
vendored
@@ -1,102 +0,0 @@
|
|||||||
package librato
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
const Operations = "operations"
|
|
||||||
const OperationsShort = "ops"
|
|
||||||
|
|
||||||
type LibratoClient struct {
|
|
||||||
Email, Token string
|
|
||||||
}
|
|
||||||
|
|
||||||
// property strings
|
|
||||||
const (
|
|
||||||
// display attributes
|
|
||||||
Color = "color"
|
|
||||||
DisplayMax = "display_max"
|
|
||||||
DisplayMin = "display_min"
|
|
||||||
DisplayUnitsLong = "display_units_long"
|
|
||||||
DisplayUnitsShort = "display_units_short"
|
|
||||||
DisplayStacked = "display_stacked"
|
|
||||||
DisplayTransform = "display_transform"
|
|
||||||
// special gauge display attributes
|
|
||||||
SummarizeFunction = "summarize_function"
|
|
||||||
Aggregate = "aggregate"
|
|
||||||
|
|
||||||
// metric keys
|
|
||||||
Name = "name"
|
|
||||||
Period = "period"
|
|
||||||
Description = "description"
|
|
||||||
DisplayName = "display_name"
|
|
||||||
Attributes = "attributes"
|
|
||||||
|
|
||||||
// measurement keys
|
|
||||||
MeasureTime = "measure_time"
|
|
||||||
Source = "source"
|
|
||||||
Value = "value"
|
|
||||||
|
|
||||||
// special gauge keys
|
|
||||||
Count = "count"
|
|
||||||
Sum = "sum"
|
|
||||||
Max = "max"
|
|
||||||
Min = "min"
|
|
||||||
SumSquares = "sum_squares"
|
|
||||||
|
|
||||||
// batch keys
|
|
||||||
Counters = "counters"
|
|
||||||
Gauges = "gauges"
|
|
||||||
|
|
||||||
MetricsPostUrl = "https://metrics-api.librato.com/v1/metrics"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Measurement map[string]interface{}
|
|
||||||
type Metric map[string]interface{}
|
|
||||||
|
|
||||||
type Batch struct {
|
|
||||||
Gauges []Measurement `json:"gauges,omitempty"`
|
|
||||||
Counters []Measurement `json:"counters,omitempty"`
|
|
||||||
MeasureTime int64 `json:"measure_time"`
|
|
||||||
Source string `json:"source"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *LibratoClient) PostMetrics(batch Batch) (err error) {
|
|
||||||
var (
|
|
||||||
js []byte
|
|
||||||
req *http.Request
|
|
||||||
resp *http.Response
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(batch.Counters) == 0 && len(batch.Gauges) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if js, err = json.Marshal(batch); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if req, err = http.NewRequest("POST", MetricsPostUrl, bytes.NewBuffer(js)); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
|
||||||
req.SetBasicAuth(self.Email, self.Token)
|
|
||||||
|
|
||||||
if resp, err = http.DefaultClient.Do(req); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
var body []byte
|
|
||||||
if body, err = ioutil.ReadAll(resp.Body); err != nil {
|
|
||||||
body = []byte(fmt.Sprintf("(could not fetch response body for error: %s)", err))
|
|
||||||
}
|
|
||||||
err = fmt.Errorf("Unable to post to Librato: %d %s %s", resp.StatusCode, resp.Status, string(body))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
235
Godeps/_workspace/src/github.com/rcrowley/go-metrics/librato/librato.go
generated
vendored
235
Godeps/_workspace/src/github.com/rcrowley/go-metrics/librato/librato.go
generated
vendored
@@ -1,235 +0,0 @@
|
|||||||
package librato
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"math"
|
|
||||||
"regexp"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/rcrowley/go-metrics"
|
|
||||||
)
|
|
||||||
|
|
||||||
// a regexp for extracting the unit from time.Duration.String
|
|
||||||
var unitRegexp = regexp.MustCompile("[^\\d]+$")
|
|
||||||
|
|
||||||
// a helper that turns a time.Duration into librato display attributes for timer metrics
|
|
||||||
func translateTimerAttributes(d time.Duration) (attrs map[string]interface{}) {
|
|
||||||
attrs = make(map[string]interface{})
|
|
||||||
attrs[DisplayTransform] = fmt.Sprintf("x/%d", int64(d))
|
|
||||||
attrs[DisplayUnitsShort] = string(unitRegexp.Find([]byte(d.String())))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type Reporter struct {
|
|
||||||
Email, Token string
|
|
||||||
Namespace string
|
|
||||||
Source string
|
|
||||||
Interval time.Duration
|
|
||||||
Registry metrics.Registry
|
|
||||||
Percentiles []float64 // percentiles to report on histogram metrics
|
|
||||||
TimerAttributes map[string]interface{} // units in which timers will be displayed
|
|
||||||
intervalSec int64
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewReporter(r metrics.Registry, d time.Duration, e string, t string, s string, p []float64, u time.Duration) *Reporter {
|
|
||||||
return &Reporter{e, t, "", s, d, r, p, translateTimerAttributes(u), int64(d / time.Second)}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Librato(r metrics.Registry, d time.Duration, e string, t string, s string, p []float64, u time.Duration) {
|
|
||||||
NewReporter(r, d, e, t, s, p, u).Run()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Reporter) Run() {
|
|
||||||
log.Printf("WARNING: This client has been DEPRECATED! It has been moved to https://github.com/mihasya/go-metrics-librato and will be removed from rcrowley/go-metrics on August 5th 2015")
|
|
||||||
ticker := time.Tick(self.Interval)
|
|
||||||
metricsApi := &LibratoClient{self.Email, self.Token}
|
|
||||||
for now := range ticker {
|
|
||||||
var metrics Batch
|
|
||||||
var err error
|
|
||||||
if metrics, err = self.BuildRequest(now, self.Registry); err != nil {
|
|
||||||
log.Printf("ERROR constructing librato request body %s", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := metricsApi.PostMetrics(metrics); err != nil {
|
|
||||||
log.Printf("ERROR sending metrics to librato %s", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate sum of squares from data provided by metrics.Histogram
|
|
||||||
// see http://en.wikipedia.org/wiki/Standard_deviation#Rapid_calculation_methods
|
|
||||||
func sumSquares(s metrics.Sample) float64 {
|
|
||||||
count := float64(s.Count())
|
|
||||||
sumSquared := math.Pow(count*s.Mean(), 2)
|
|
||||||
sumSquares := math.Pow(count*s.StdDev(), 2) + sumSquared/count
|
|
||||||
if math.IsNaN(sumSquares) {
|
|
||||||
return 0.0
|
|
||||||
}
|
|
||||||
return sumSquares
|
|
||||||
}
|
|
||||||
func sumSquaresTimer(t metrics.Timer) float64 {
|
|
||||||
count := float64(t.Count())
|
|
||||||
sumSquared := math.Pow(count*t.Mean(), 2)
|
|
||||||
sumSquares := math.Pow(count*t.StdDev(), 2) + sumSquared/count
|
|
||||||
if math.IsNaN(sumSquares) {
|
|
||||||
return 0.0
|
|
||||||
}
|
|
||||||
return sumSquares
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Reporter) BuildRequest(now time.Time, r metrics.Registry) (snapshot Batch, err error) {
|
|
||||||
snapshot = Batch{
|
|
||||||
// coerce timestamps to a stepping fn so that they line up in Librato graphs
|
|
||||||
MeasureTime: (now.Unix() / self.intervalSec) * self.intervalSec,
|
|
||||||
Source: self.Source,
|
|
||||||
}
|
|
||||||
snapshot.Gauges = make([]Measurement, 0)
|
|
||||||
snapshot.Counters = make([]Measurement, 0)
|
|
||||||
histogramGaugeCount := 1 + len(self.Percentiles)
|
|
||||||
r.Each(func(name string, metric interface{}) {
|
|
||||||
if self.Namespace != "" {
|
|
||||||
name = fmt.Sprintf("%s.%s", self.Namespace, name)
|
|
||||||
}
|
|
||||||
measurement := Measurement{}
|
|
||||||
measurement[Period] = self.Interval.Seconds()
|
|
||||||
switch m := metric.(type) {
|
|
||||||
case metrics.Counter:
|
|
||||||
if m.Count() > 0 {
|
|
||||||
measurement[Name] = fmt.Sprintf("%s.%s", name, "count")
|
|
||||||
measurement[Value] = float64(m.Count())
|
|
||||||
measurement[Attributes] = map[string]interface{}{
|
|
||||||
DisplayUnitsLong: Operations,
|
|
||||||
DisplayUnitsShort: OperationsShort,
|
|
||||||
DisplayMin: "0",
|
|
||||||
}
|
|
||||||
snapshot.Counters = append(snapshot.Counters, measurement)
|
|
||||||
}
|
|
||||||
case metrics.Gauge:
|
|
||||||
measurement[Name] = name
|
|
||||||
measurement[Value] = float64(m.Value())
|
|
||||||
snapshot.Gauges = append(snapshot.Gauges, measurement)
|
|
||||||
case metrics.GaugeFloat64:
|
|
||||||
measurement[Name] = name
|
|
||||||
measurement[Value] = float64(m.Value())
|
|
||||||
snapshot.Gauges = append(snapshot.Gauges, measurement)
|
|
||||||
case metrics.Histogram:
|
|
||||||
if m.Count() > 0 {
|
|
||||||
gauges := make([]Measurement, histogramGaugeCount, histogramGaugeCount)
|
|
||||||
s := m.Sample()
|
|
||||||
measurement[Name] = fmt.Sprintf("%s.%s", name, "hist")
|
|
||||||
measurement[Count] = uint64(s.Count())
|
|
||||||
measurement[Max] = float64(s.Max())
|
|
||||||
measurement[Min] = float64(s.Min())
|
|
||||||
measurement[Sum] = float64(s.Sum())
|
|
||||||
measurement[SumSquares] = sumSquares(s)
|
|
||||||
gauges[0] = measurement
|
|
||||||
for i, p := range self.Percentiles {
|
|
||||||
gauges[i+1] = Measurement{
|
|
||||||
Name: fmt.Sprintf("%s.%.2f", measurement[Name], p),
|
|
||||||
Value: s.Percentile(p),
|
|
||||||
Period: measurement[Period],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
snapshot.Gauges = append(snapshot.Gauges, gauges...)
|
|
||||||
}
|
|
||||||
case metrics.Meter:
|
|
||||||
measurement[Name] = name
|
|
||||||
measurement[Value] = float64(m.Count())
|
|
||||||
snapshot.Counters = append(snapshot.Counters, measurement)
|
|
||||||
snapshot.Gauges = append(snapshot.Gauges,
|
|
||||||
Measurement{
|
|
||||||
Name: fmt.Sprintf("%s.%s", name, "1min"),
|
|
||||||
Value: m.Rate1(),
|
|
||||||
Period: int64(self.Interval.Seconds()),
|
|
||||||
Attributes: map[string]interface{}{
|
|
||||||
DisplayUnitsLong: Operations,
|
|
||||||
DisplayUnitsShort: OperationsShort,
|
|
||||||
DisplayMin: "0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Measurement{
|
|
||||||
Name: fmt.Sprintf("%s.%s", name, "5min"),
|
|
||||||
Value: m.Rate5(),
|
|
||||||
Period: int64(self.Interval.Seconds()),
|
|
||||||
Attributes: map[string]interface{}{
|
|
||||||
DisplayUnitsLong: Operations,
|
|
||||||
DisplayUnitsShort: OperationsShort,
|
|
||||||
DisplayMin: "0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Measurement{
|
|
||||||
Name: fmt.Sprintf("%s.%s", name, "15min"),
|
|
||||||
Value: m.Rate15(),
|
|
||||||
Period: int64(self.Interval.Seconds()),
|
|
||||||
Attributes: map[string]interface{}{
|
|
||||||
DisplayUnitsLong: Operations,
|
|
||||||
DisplayUnitsShort: OperationsShort,
|
|
||||||
DisplayMin: "0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
case metrics.Timer:
|
|
||||||
measurement[Name] = name
|
|
||||||
measurement[Value] = float64(m.Count())
|
|
||||||
snapshot.Counters = append(snapshot.Counters, measurement)
|
|
||||||
if m.Count() > 0 {
|
|
||||||
libratoName := fmt.Sprintf("%s.%s", name, "timer.mean")
|
|
||||||
gauges := make([]Measurement, histogramGaugeCount, histogramGaugeCount)
|
|
||||||
gauges[0] = Measurement{
|
|
||||||
Name: libratoName,
|
|
||||||
Count: uint64(m.Count()),
|
|
||||||
Sum: m.Mean() * float64(m.Count()),
|
|
||||||
Max: float64(m.Max()),
|
|
||||||
Min: float64(m.Min()),
|
|
||||||
SumSquares: sumSquaresTimer(m),
|
|
||||||
Period: int64(self.Interval.Seconds()),
|
|
||||||
Attributes: self.TimerAttributes,
|
|
||||||
}
|
|
||||||
for i, p := range self.Percentiles {
|
|
||||||
gauges[i+1] = Measurement{
|
|
||||||
Name: fmt.Sprintf("%s.timer.%2.0f", name, p*100),
|
|
||||||
Value: m.Percentile(p),
|
|
||||||
Period: int64(self.Interval.Seconds()),
|
|
||||||
Attributes: self.TimerAttributes,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
snapshot.Gauges = append(snapshot.Gauges, gauges...)
|
|
||||||
snapshot.Gauges = append(snapshot.Gauges,
|
|
||||||
Measurement{
|
|
||||||
Name: fmt.Sprintf("%s.%s", name, "rate.1min"),
|
|
||||||
Value: m.Rate1(),
|
|
||||||
Period: int64(self.Interval.Seconds()),
|
|
||||||
Attributes: map[string]interface{}{
|
|
||||||
DisplayUnitsLong: Operations,
|
|
||||||
DisplayUnitsShort: OperationsShort,
|
|
||||||
DisplayMin: "0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Measurement{
|
|
||||||
Name: fmt.Sprintf("%s.%s", name, "rate.5min"),
|
|
||||||
Value: m.Rate5(),
|
|
||||||
Period: int64(self.Interval.Seconds()),
|
|
||||||
Attributes: map[string]interface{}{
|
|
||||||
DisplayUnitsLong: Operations,
|
|
||||||
DisplayUnitsShort: OperationsShort,
|
|
||||||
DisplayMin: "0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Measurement{
|
|
||||||
Name: fmt.Sprintf("%s.%s", name, "rate.15min"),
|
|
||||||
Value: m.Rate15(),
|
|
||||||
Period: int64(self.Interval.Seconds()),
|
|
||||||
Attributes: map[string]interface{}{
|
|
||||||
DisplayUnitsLong: Operations,
|
|
||||||
DisplayUnitsShort: OperationsShort,
|
|
||||||
DisplayMin: "0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
69
Godeps/_workspace/src/github.com/rcrowley/go-metrics/stathat/stathat.go
generated
vendored
69
Godeps/_workspace/src/github.com/rcrowley/go-metrics/stathat/stathat.go
generated
vendored
@@ -1,69 +0,0 @@
|
|||||||
// Metrics output to StatHat.
|
|
||||||
package stathat
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/rcrowley/go-metrics"
|
|
||||||
"github.com/stathat/go"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Stathat(r metrics.Registry, d time.Duration, userkey string) {
|
|
||||||
for {
|
|
||||||
if err := sh(r, userkey); nil != err {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
time.Sleep(d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func sh(r metrics.Registry, userkey string) error {
|
|
||||||
r.Each(func(name string, i interface{}) {
|
|
||||||
switch metric := i.(type) {
|
|
||||||
case metrics.Counter:
|
|
||||||
stathat.PostEZCount(name, userkey, int(metric.Count()))
|
|
||||||
case metrics.Gauge:
|
|
||||||
stathat.PostEZValue(name, userkey, float64(metric.Value()))
|
|
||||||
case metrics.GaugeFloat64:
|
|
||||||
stathat.PostEZValue(name, userkey, float64(metric.Value()))
|
|
||||||
case metrics.Histogram:
|
|
||||||
h := metric.Snapshot()
|
|
||||||
ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
|
|
||||||
stathat.PostEZCount(name+".count", userkey, int(h.Count()))
|
|
||||||
stathat.PostEZValue(name+".min", userkey, float64(h.Min()))
|
|
||||||
stathat.PostEZValue(name+".max", userkey, float64(h.Max()))
|
|
||||||
stathat.PostEZValue(name+".mean", userkey, float64(h.Mean()))
|
|
||||||
stathat.PostEZValue(name+".std-dev", userkey, float64(h.StdDev()))
|
|
||||||
stathat.PostEZValue(name+".50-percentile", userkey, float64(ps[0]))
|
|
||||||
stathat.PostEZValue(name+".75-percentile", userkey, float64(ps[1]))
|
|
||||||
stathat.PostEZValue(name+".95-percentile", userkey, float64(ps[2]))
|
|
||||||
stathat.PostEZValue(name+".99-percentile", userkey, float64(ps[3]))
|
|
||||||
stathat.PostEZValue(name+".999-percentile", userkey, float64(ps[4]))
|
|
||||||
case metrics.Meter:
|
|
||||||
m := metric.Snapshot()
|
|
||||||
stathat.PostEZCount(name+".count", userkey, int(m.Count()))
|
|
||||||
stathat.PostEZValue(name+".one-minute", userkey, float64(m.Rate1()))
|
|
||||||
stathat.PostEZValue(name+".five-minute", userkey, float64(m.Rate5()))
|
|
||||||
stathat.PostEZValue(name+".fifteen-minute", userkey, float64(m.Rate15()))
|
|
||||||
stathat.PostEZValue(name+".mean", userkey, float64(m.RateMean()))
|
|
||||||
case metrics.Timer:
|
|
||||||
t := metric.Snapshot()
|
|
||||||
ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
|
|
||||||
stathat.PostEZCount(name+".count", userkey, int(t.Count()))
|
|
||||||
stathat.PostEZValue(name+".min", userkey, float64(t.Min()))
|
|
||||||
stathat.PostEZValue(name+".max", userkey, float64(t.Max()))
|
|
||||||
stathat.PostEZValue(name+".mean", userkey, float64(t.Mean()))
|
|
||||||
stathat.PostEZValue(name+".std-dev", userkey, float64(t.StdDev()))
|
|
||||||
stathat.PostEZValue(name+".50-percentile", userkey, float64(ps[0]))
|
|
||||||
stathat.PostEZValue(name+".75-percentile", userkey, float64(ps[1]))
|
|
||||||
stathat.PostEZValue(name+".95-percentile", userkey, float64(ps[2]))
|
|
||||||
stathat.PostEZValue(name+".99-percentile", userkey, float64(ps[3]))
|
|
||||||
stathat.PostEZValue(name+".999-percentile", userkey, float64(ps[4]))
|
|
||||||
stathat.PostEZValue(name+".one-minute", userkey, float64(t.Rate1()))
|
|
||||||
stathat.PostEZValue(name+".five-minute", userkey, float64(t.Rate5()))
|
|
||||||
stathat.PostEZValue(name+".fifteen-minute", userkey, float64(t.Rate15()))
|
|
||||||
stathat.PostEZValue(name+".mean-rate", userkey, float64(t.RateMean()))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
88
Godeps/_workspace/src/github.com/rjeczalik/notify/.gitignore
generated
vendored
88
Godeps/_workspace/src/github.com/rjeczalik/notify/.gitignore
generated
vendored
@@ -1,88 +0,0 @@
|
|||||||
# Created by https://www.gitignore.io
|
|
||||||
|
|
||||||
### OSX ###
|
|
||||||
.DS_Store
|
|
||||||
.AppleDouble
|
|
||||||
.LSOverride
|
|
||||||
|
|
||||||
# Icon must end with two \r
|
|
||||||
Icon
|
|
||||||
|
|
||||||
|
|
||||||
# Thumbnails
|
|
||||||
._*
|
|
||||||
|
|
||||||
# Files that might appear on external disk
|
|
||||||
.Spotlight-V100
|
|
||||||
.Trashes
|
|
||||||
|
|
||||||
# Directories potentially created on remote AFP share
|
|
||||||
.AppleDB
|
|
||||||
.AppleDesktop
|
|
||||||
Network Trash Folder
|
|
||||||
Temporary Items
|
|
||||||
.apdisk
|
|
||||||
|
|
||||||
|
|
||||||
### Windows ###
|
|
||||||
# Windows image file caches
|
|
||||||
Thumbs.db
|
|
||||||
ehthumbs.db
|
|
||||||
|
|
||||||
# Folder config file
|
|
||||||
Desktop.ini
|
|
||||||
|
|
||||||
# Recycle Bin used on file shares
|
|
||||||
$RECYCLE.BIN/
|
|
||||||
|
|
||||||
# Windows Installer files
|
|
||||||
*.cab
|
|
||||||
*.msi
|
|
||||||
*.msm
|
|
||||||
*.msp
|
|
||||||
|
|
||||||
# Windows shortcuts
|
|
||||||
*.lnk
|
|
||||||
|
|
||||||
|
|
||||||
### Linux ###
|
|
||||||
*~
|
|
||||||
|
|
||||||
# KDE directory preferences
|
|
||||||
.directory
|
|
||||||
|
|
||||||
|
|
||||||
### Go ###
|
|
||||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
|
||||||
*.o
|
|
||||||
*.a
|
|
||||||
*.so
|
|
||||||
|
|
||||||
# Folders
|
|
||||||
_obj
|
|
||||||
_test
|
|
||||||
|
|
||||||
# Architecture specific extensions/prefixes
|
|
||||||
*.[568vq]
|
|
||||||
[568vq].out
|
|
||||||
|
|
||||||
*.cgo1.go
|
|
||||||
*.cgo2.c
|
|
||||||
_cgo_defun.c
|
|
||||||
_cgo_gotypes.go
|
|
||||||
_cgo_export.*
|
|
||||||
|
|
||||||
_testmain.go
|
|
||||||
|
|
||||||
*.exe
|
|
||||||
*.test
|
|
||||||
*.prof
|
|
||||||
|
|
||||||
|
|
||||||
### vim ###
|
|
||||||
[._]*.s[a-w][a-z]
|
|
||||||
[._]s[a-w][a-z]
|
|
||||||
*.un~
|
|
||||||
Session.vim
|
|
||||||
.netrwhist
|
|
||||||
*~
|
|
||||||
29
Godeps/_workspace/src/github.com/rjeczalik/notify/.travis.yml
generated
vendored
29
Godeps/_workspace/src/github.com/rjeczalik/notify/.travis.yml
generated
vendored
@@ -1,29 +0,0 @@
|
|||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- 1.4.3
|
|
||||||
- 1.6
|
|
||||||
|
|
||||||
os:
|
|
||||||
- linux
|
|
||||||
- osx
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- os: osx
|
|
||||||
go: 1.6
|
|
||||||
env:
|
|
||||||
- GOFLAGS="-tags kqueue"
|
|
||||||
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- GOBIN=$HOME/bin
|
|
||||||
- PATH=$HOME/bin:$PATH
|
|
||||||
|
|
||||||
install:
|
|
||||||
- go get -t -v ./...
|
|
||||||
|
|
||||||
script:
|
|
||||||
- "(go version | grep -q 1.4) || go tool vet -all ."
|
|
||||||
- go install $GOFLAGS ./...
|
|
||||||
- go test -v -race $GOFLAGS ./...
|
|
||||||
5
Godeps/_workspace/src/github.com/robertkrimen/otto/.gitignore
generated
vendored
5
Godeps/_workspace/src/github.com/robertkrimen/otto/.gitignore
generated
vendored
@@ -1,5 +0,0 @@
|
|||||||
/.test
|
|
||||||
/otto/otto
|
|
||||||
/otto/otto-*
|
|
||||||
/test/test-*.js
|
|
||||||
/test/tester
|
|
||||||
92
Godeps/_workspace/src/github.com/robertkrimen/otto/ast/comments.go
generated
vendored
92
Godeps/_workspace/src/github.com/robertkrimen/otto/ast/comments.go
generated
vendored
@@ -1,92 +0,0 @@
|
|||||||
package ast
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/robertkrimen/otto/file"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CommentPosition determines where the comment is in a given context
|
|
||||||
type CommentPosition int
|
|
||||||
|
|
||||||
const (
|
|
||||||
_ CommentPosition = iota
|
|
||||||
LEADING // Before the pertinent expression
|
|
||||||
TRAILING // After the pertinent expression
|
|
||||||
KEY // After a key or keyword
|
|
||||||
COLON // After a colon in a field declaration
|
|
||||||
FINAL // Final comments in a block, not belonging to a specific expression or the comment after a trailing , in an array or object literal
|
|
||||||
TBD
|
|
||||||
)
|
|
||||||
|
|
||||||
// Comment contains the data of the comment
|
|
||||||
type Comment struct {
|
|
||||||
Begin file.Idx
|
|
||||||
Text string
|
|
||||||
Position CommentPosition
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a stringified version of the position
|
|
||||||
func (cp CommentPosition) String() string {
|
|
||||||
switch cp {
|
|
||||||
case LEADING:
|
|
||||||
return "Leading"
|
|
||||||
case TRAILING:
|
|
||||||
return "Trailing"
|
|
||||||
case KEY:
|
|
||||||
return "Key"
|
|
||||||
case COLON:
|
|
||||||
return "Colon"
|
|
||||||
case FINAL:
|
|
||||||
return "Final"
|
|
||||||
default:
|
|
||||||
return "???"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a stringified version of the comment
|
|
||||||
func (c Comment) String() string {
|
|
||||||
return fmt.Sprintf("Comment: %v", c.Text)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CommentMap is the data structure where all found comments are stored
|
|
||||||
type CommentMap map[Node][]*Comment
|
|
||||||
|
|
||||||
// AddComment adds a single comment to the map
|
|
||||||
func (cm CommentMap) AddComment(node Node, comment *Comment) {
|
|
||||||
list := cm[node]
|
|
||||||
list = append(list, comment)
|
|
||||||
|
|
||||||
cm[node] = list
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddComments adds a slice of comments, given a node and an updated position
|
|
||||||
func (cm CommentMap) AddComments(node Node, comments []*Comment, position CommentPosition) {
|
|
||||||
for _, comment := range comments {
|
|
||||||
comment.Position = position
|
|
||||||
cm.AddComment(node, comment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Size returns the size of the map
|
|
||||||
func (cm CommentMap) Size() int {
|
|
||||||
size := 0
|
|
||||||
for _, comments := range cm {
|
|
||||||
size += len(comments)
|
|
||||||
}
|
|
||||||
|
|
||||||
return size
|
|
||||||
}
|
|
||||||
|
|
||||||
// MoveComments moves comments with a given position from a node to another
|
|
||||||
func (cm CommentMap) MoveComments(from, to Node, position CommentPosition) {
|
|
||||||
for i, c := range cm[from] {
|
|
||||||
if c.Position == position {
|
|
||||||
cm.AddComment(to, c)
|
|
||||||
|
|
||||||
// Remove the comment from the "from" slice
|
|
||||||
cm[from][i] = cm[from][len(cm[from])-1]
|
|
||||||
cm[from][len(cm[from])-1] = nil
|
|
||||||
cm[from] = cm[from][:len(cm[from])-1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
5
Godeps/_workspace/src/github.com/robertkrimen/otto/otto/Makefile
generated
vendored
5
Godeps/_workspace/src/github.com/robertkrimen/otto/otto/Makefile
generated
vendored
@@ -1,5 +0,0 @@
|
|||||||
.PHONY: build
|
|
||||||
|
|
||||||
build:
|
|
||||||
go build -a
|
|
||||||
-gxc build-darwin-386 -a
|
|
||||||
48
Godeps/_workspace/src/github.com/robertkrimen/otto/otto/main.go
generated
vendored
48
Godeps/_workspace/src/github.com/robertkrimen/otto/otto/main.go
generated
vendored
@@ -1,48 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/robertkrimen/otto"
|
|
||||||
"github.com/robertkrimen/otto/underscore"
|
|
||||||
)
|
|
||||||
|
|
||||||
var flag_underscore *bool = flag.Bool("underscore", true, "Load underscore into the runtime environment")
|
|
||||||
|
|
||||||
func readSource(filename string) ([]byte, error) {
|
|
||||||
if filename == "" || filename == "-" {
|
|
||||||
return ioutil.ReadAll(os.Stdin)
|
|
||||||
}
|
|
||||||
return ioutil.ReadFile(filename)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
if !*flag_underscore {
|
|
||||||
underscore.Disable()
|
|
||||||
}
|
|
||||||
|
|
||||||
err := func() error {
|
|
||||||
src, err := readSource(flag.Arg(0))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
vm := otto.New()
|
|
||||||
_, err = vm.Run(src)
|
|
||||||
return err
|
|
||||||
}()
|
|
||||||
if err != nil {
|
|
||||||
switch err := err.(type) {
|
|
||||||
case *otto.Error:
|
|
||||||
fmt.Print(err.String())
|
|
||||||
default:
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
os.Exit(64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
115
Godeps/_workspace/src/github.com/robertkrimen/otto/repl/repl.go
generated
vendored
115
Godeps/_workspace/src/github.com/robertkrimen/otto/repl/repl.go
generated
vendored
@@ -1,115 +0,0 @@
|
|||||||
// Package repl implements a REPL (read-eval-print loop) for otto.
|
|
||||||
package repl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"strings"
|
|
||||||
"sync/atomic"
|
|
||||||
|
|
||||||
"github.com/robertkrimen/otto"
|
|
||||||
"gopkg.in/readline.v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
var counter uint32
|
|
||||||
|
|
||||||
// DebuggerHandler implements otto's debugger handler signature, providing a
|
|
||||||
// simple drop-in debugger implementation.
|
|
||||||
func DebuggerHandler(vm *otto.Otto) {
|
|
||||||
i := atomic.AddUint32(&counter, 1)
|
|
||||||
|
|
||||||
// purposefully ignoring the error here - we can't do anything useful with
|
|
||||||
// it except panicking, and that'd be pretty rude. it'd be easy enough for a
|
|
||||||
// consumer to define an equivalent function that _does_ panic if desired.
|
|
||||||
_ = RunWithPrompt(vm, fmt.Sprintf("DEBUGGER[%d]>", i))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run creates a REPL with the default prompt and no prelude.
|
|
||||||
func Run(vm *otto.Otto) error {
|
|
||||||
return RunWithPromptAndPrelude(vm, "", "")
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunWithPrompt runs a REPL with the given prompt and no prelude.
|
|
||||||
func RunWithPrompt(vm *otto.Otto, prompt string) error {
|
|
||||||
return RunWithPromptAndPrelude(vm, prompt, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunWithPrelude runs a REPL with the default prompt and the given prelude.
|
|
||||||
func RunWithPrelude(vm *otto.Otto, prelude string) error {
|
|
||||||
return RunWithPromptAndPrelude(vm, "", prelude)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunWithPromptAndPrelude runs a REPL with the given prompt and prelude.
|
|
||||||
func RunWithPromptAndPrelude(vm *otto.Otto, prompt, prelude string) error {
|
|
||||||
if prompt == "" {
|
|
||||||
prompt = ">"
|
|
||||||
}
|
|
||||||
|
|
||||||
prompt = strings.Trim(prompt, " ")
|
|
||||||
prompt += " "
|
|
||||||
|
|
||||||
rl, err := readline.New(prompt)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if prelude != "" {
|
|
||||||
if _, err := io.Copy(rl.Stderr(), strings.NewReader(prelude+"\n")); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
rl.Refresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
var d []string
|
|
||||||
|
|
||||||
for {
|
|
||||||
l, err := rl.Readline()
|
|
||||||
if err != nil {
|
|
||||||
if err == readline.ErrInterrupt {
|
|
||||||
if d != nil {
|
|
||||||
d = nil
|
|
||||||
|
|
||||||
rl.SetPrompt(prompt)
|
|
||||||
rl.Refresh()
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if l == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
d = append(d, l)
|
|
||||||
|
|
||||||
s, err := vm.Compile("repl", strings.Join(d, "\n"))
|
|
||||||
if err != nil {
|
|
||||||
rl.SetPrompt(strings.Repeat(" ", len(prompt)))
|
|
||||||
} else {
|
|
||||||
rl.SetPrompt(prompt)
|
|
||||||
|
|
||||||
d = nil
|
|
||||||
|
|
||||||
v, err := vm.Eval(s)
|
|
||||||
if err != nil {
|
|
||||||
if oerr, ok := err.(*otto.Error); ok {
|
|
||||||
io.Copy(rl.Stdout(), strings.NewReader(oerr.String()))
|
|
||||||
} else {
|
|
||||||
io.Copy(rl.Stdout(), strings.NewReader(err.Error()))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rl.Stdout().Write([]byte(v.String() + "\n"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rl.Refresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
return rl.Close()
|
|
||||||
}
|
|
||||||
669
Godeps/_workspace/src/github.com/robertkrimen/otto/terst/terst.go
generated
vendored
669
Godeps/_workspace/src/github.com/robertkrimen/otto/terst/terst.go
generated
vendored
@@ -1,669 +0,0 @@
|
|||||||
// This file was AUTOMATICALLY GENERATED by terst-import (smuggol) from github.com/robertkrimen/terst
|
|
||||||
|
|
||||||
/*
|
|
||||||
Package terst is a terse (terst = test + terse), easy-to-use testing library for Go.
|
|
||||||
|
|
||||||
terst is compatible with (and works via) the standard testing package: http://golang.org/pkg/testing
|
|
||||||
|
|
||||||
var is = terst.Is
|
|
||||||
|
|
||||||
func Test(t *testing.T) {
|
|
||||||
terst.Terst(t, func() {
|
|
||||||
is("abc", "abc")
|
|
||||||
|
|
||||||
is(1, ">", 0)
|
|
||||||
|
|
||||||
var abc []int
|
|
||||||
is(abc, nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Do not import terst directly, instead use `terst-import` to copy it into your testing environment:
|
|
||||||
|
|
||||||
https://github.com/robertkrimen/terst/tree/master/terst-import
|
|
||||||
|
|
||||||
$ go get github.com/robertkrimen/terst/terst-import
|
|
||||||
|
|
||||||
$ terst-import
|
|
||||||
|
|
||||||
*/
|
|
||||||
package terst
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"math/big"
|
|
||||||
"reflect"
|
|
||||||
"regexp"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Is compares two values (got & expect) and returns true if the comparison is true,
|
|
||||||
// false otherwise. In addition, if the comparison is false, Is will report the error
|
|
||||||
// in a manner similar to testing.T.Error(...). Is also takes an optional argument,
|
|
||||||
// a comparator, that changes how the comparison is made. The following
|
|
||||||
// comparators are available:
|
|
||||||
//
|
|
||||||
// == # got == expect (default)
|
|
||||||
// != # got != expect
|
|
||||||
//
|
|
||||||
// > # got > expect (float32, uint, uint16, int, int64, ...)
|
|
||||||
// >= # got >= expect
|
|
||||||
// < # got < expect
|
|
||||||
// <= # got <= expect
|
|
||||||
//
|
|
||||||
// =~ # regexp.MustCompile(expect).Match{String}(got)
|
|
||||||
// !~ # !regexp.MustCompile(expect).Match{String}(got)
|
|
||||||
//
|
|
||||||
// Basic usage with the default comparator (==):
|
|
||||||
//
|
|
||||||
// Is(<got>, <expect>)
|
|
||||||
//
|
|
||||||
// Specifying a different comparator:
|
|
||||||
//
|
|
||||||
// Is(<got>, <comparator>, <expect>)
|
|
||||||
//
|
|
||||||
// A simple comparison:
|
|
||||||
//
|
|
||||||
// Is(2 + 2, 4)
|
|
||||||
//
|
|
||||||
// A bit trickier:
|
|
||||||
//
|
|
||||||
// Is(1, ">", 0)
|
|
||||||
// Is(2 + 2, "!=", 5)
|
|
||||||
// Is("Nothing happens.", "=~", `ing(\s+)happens\.$`)
|
|
||||||
//
|
|
||||||
// Is should only be called under a Terst(t, ...) call. For a standalone version,
|
|
||||||
// use IsErr. If no scope is found and the comparison is false, then Is will panic the error.
|
|
||||||
//
|
|
||||||
func Is(arguments ...interface{}) bool {
|
|
||||||
err := IsErr(arguments...)
|
|
||||||
if err != nil {
|
|
||||||
call := Caller()
|
|
||||||
if call == nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
call.Error(err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
type (
|
|
||||||
// ErrFail indicates a comparison failure (e.g. 0 > 1).
|
|
||||||
ErrFail error
|
|
||||||
|
|
||||||
// ErrInvalid indicates an invalid comparison (e.g. bool == string).
|
|
||||||
ErrInvalid error
|
|
||||||
)
|
|
||||||
|
|
||||||
var errInvalid = errors.New("invalid")
|
|
||||||
|
|
||||||
var registry = struct {
|
|
||||||
table map[uintptr]*_scope
|
|
||||||
lock sync.RWMutex
|
|
||||||
}{
|
|
||||||
table: map[uintptr]*_scope{},
|
|
||||||
}
|
|
||||||
|
|
||||||
func registerScope(pc uintptr, scope *_scope) {
|
|
||||||
registry.lock.Lock()
|
|
||||||
defer registry.lock.Unlock()
|
|
||||||
registry.table[pc] = scope
|
|
||||||
}
|
|
||||||
|
|
||||||
func scope() *_scope {
|
|
||||||
scope, _ := findScope()
|
|
||||||
return scope
|
|
||||||
}
|
|
||||||
|
|
||||||
func floatCompare(a float64, b float64) int {
|
|
||||||
if a > b {
|
|
||||||
return 1
|
|
||||||
} else if a < b {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
// NaN == NaN
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func bigIntCompare(a *big.Int, b *big.Int) int {
|
|
||||||
return a.Cmp(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func bigInt(value int64) *big.Int {
|
|
||||||
return big.NewInt(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
func bigUint(value uint64) *big.Int {
|
|
||||||
return big.NewInt(0).SetUint64(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
type _toString interface {
|
|
||||||
String() string
|
|
||||||
}
|
|
||||||
|
|
||||||
func toString(value interface{}) (string, error) {
|
|
||||||
switch value := value.(type) {
|
|
||||||
case string:
|
|
||||||
return value, nil
|
|
||||||
case _toString:
|
|
||||||
return value.String(), nil
|
|
||||||
case error:
|
|
||||||
return value.Error(), nil
|
|
||||||
}
|
|
||||||
return "", errInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
func matchString(got string, expect *regexp.Regexp) (int, error) {
|
|
||||||
if expect.MatchString(got) {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return -1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func match(got []byte, expect *regexp.Regexp) (int, error) {
|
|
||||||
if expect.Match(got) {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return -1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func compareMatch(got, expect interface{}) (int, error) {
|
|
||||||
switch got := got.(type) {
|
|
||||||
case []byte:
|
|
||||||
switch expect := expect.(type) {
|
|
||||||
case string:
|
|
||||||
matcher, err := regexp.Compile(expect)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return match(got, matcher)
|
|
||||||
case *regexp.Regexp:
|
|
||||||
return match(got, expect)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if got, err := toString(got); err == nil {
|
|
||||||
switch expect := expect.(type) {
|
|
||||||
case string:
|
|
||||||
matcher, err := regexp.Compile(expect)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return matchString(got, matcher)
|
|
||||||
case *regexp.Regexp:
|
|
||||||
return matchString(got, expect)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0, errInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
func floatPromote(value reflect.Value) (float64, error) {
|
|
||||||
kind := value.Kind()
|
|
||||||
if reflect.Int <= kind && kind <= reflect.Int64 {
|
|
||||||
return float64(value.Int()), nil
|
|
||||||
}
|
|
||||||
if reflect.Uint <= kind && kind <= reflect.Uint64 {
|
|
||||||
return float64(value.Uint()), nil
|
|
||||||
}
|
|
||||||
if reflect.Float32 <= kind && kind <= reflect.Float64 {
|
|
||||||
return value.Float(), nil
|
|
||||||
}
|
|
||||||
return 0, errInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
func bigIntPromote(value reflect.Value) (*big.Int, error) {
|
|
||||||
kind := value.Kind()
|
|
||||||
if reflect.Int <= kind && kind <= reflect.Int64 {
|
|
||||||
return bigInt(value.Int()), nil
|
|
||||||
}
|
|
||||||
if reflect.Uint <= kind && kind <= reflect.Uint64 {
|
|
||||||
return bigUint(value.Uint()), nil
|
|
||||||
}
|
|
||||||
return nil, errInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
func compareOther(got, expect interface{}) (int, error) {
|
|
||||||
{
|
|
||||||
switch expect.(type) {
|
|
||||||
case float32, float64:
|
|
||||||
return compareNumber(got, expect)
|
|
||||||
case uint, uint8, uint16, uint32, uint64:
|
|
||||||
return compareNumber(got, expect)
|
|
||||||
case int, int8, int16, int32, int64:
|
|
||||||
return compareNumber(got, expect)
|
|
||||||
case string:
|
|
||||||
var err error
|
|
||||||
got, err = toString(got)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
case nil:
|
|
||||||
got := reflect.ValueOf(got)
|
|
||||||
switch got.Kind() {
|
|
||||||
case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.Interface:
|
|
||||||
if got.IsNil() {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return -1, nil
|
|
||||||
case reflect.Invalid: // reflect.Invalid: var abc interface{} = nil
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return 0, errInvalid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if reflect.ValueOf(got).Type() != reflect.ValueOf(expect).Type() {
|
|
||||||
return 0, errInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
if reflect.DeepEqual(got, expect) {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return -1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func compareNumber(got, expect interface{}) (int, error) {
|
|
||||||
{
|
|
||||||
got := reflect.ValueOf(got)
|
|
||||||
k0 := got.Kind()
|
|
||||||
expect := reflect.ValueOf(expect)
|
|
||||||
k1 := expect.Kind()
|
|
||||||
if reflect.Float32 <= k0 && k0 <= reflect.Float64 ||
|
|
||||||
reflect.Float32 <= k1 && k1 <= reflect.Float64 {
|
|
||||||
got, err := floatPromote(got)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
expect, err := floatPromote(expect)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return floatCompare(got, expect), nil
|
|
||||||
} else {
|
|
||||||
got, err := bigIntPromote(got)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
expect, err := bigIntPromote(expect)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return got.Cmp(expect), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0, errInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsErr compares two values (got & expect) and returns nil if the comparison is true, an ErrFail if
|
|
||||||
// the comparison is false, or an ErrInvalid if the comparison is invalid. IsErr also
|
|
||||||
// takes an optional argument, a comparator, that changes how the comparison is made.
|
|
||||||
//
|
|
||||||
// Is & IsErr are similar but different:
|
|
||||||
//
|
|
||||||
// Is(...) // Should only be called within a Terst(...) call
|
|
||||||
// IsErr(...) // A standalone comparator, the same as Is, just without the automatic reporting
|
|
||||||
//
|
|
||||||
func IsErr(arguments ...interface{}) error {
|
|
||||||
var got, expect interface{}
|
|
||||||
comparator := "=="
|
|
||||||
switch len(arguments) {
|
|
||||||
case 0, 1:
|
|
||||||
return fmt.Errorf("invalid number of arguments to IsErr: %d", len(arguments))
|
|
||||||
case 2:
|
|
||||||
got, expect = arguments[0], arguments[1]
|
|
||||||
default:
|
|
||||||
if value, ok := arguments[1].(string); ok {
|
|
||||||
comparator = value
|
|
||||||
} else {
|
|
||||||
return fmt.Errorf("invalid comparator: %v", arguments[1])
|
|
||||||
}
|
|
||||||
got, expect = arguments[0], arguments[2]
|
|
||||||
}
|
|
||||||
|
|
||||||
var result int
|
|
||||||
var err error
|
|
||||||
|
|
||||||
switch comparator {
|
|
||||||
case "<", "<=", ">", ">=":
|
|
||||||
result, err = compareNumber(got, expect)
|
|
||||||
case "=~", "!~":
|
|
||||||
result, err = compareMatch(got, expect)
|
|
||||||
case "==", "!=":
|
|
||||||
result, err = compareOther(got, expect)
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("invalid comparator: %s", comparator)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err == errInvalid {
|
|
||||||
return ErrInvalid(fmt.Errorf(
|
|
||||||
"\nINVALID (%s):\n got: %v (%T)\n expected: %v (%T)",
|
|
||||||
comparator,
|
|
||||||
got, got,
|
|
||||||
expect, expect,
|
|
||||||
))
|
|
||||||
} else if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
equality, pass := false, false
|
|
||||||
|
|
||||||
switch comparator {
|
|
||||||
case "==", "=~":
|
|
||||||
equality = true
|
|
||||||
pass = result == 0
|
|
||||||
case "!=", "!~":
|
|
||||||
equality = true
|
|
||||||
pass = result != 0
|
|
||||||
case "<":
|
|
||||||
pass = result < 0
|
|
||||||
case "<=":
|
|
||||||
pass = result <= 0
|
|
||||||
case ">":
|
|
||||||
pass = result > 0
|
|
||||||
case ">=":
|
|
||||||
pass = result >= 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pass {
|
|
||||||
if equality {
|
|
||||||
if comparator[1] == '~' {
|
|
||||||
if value, ok := got.([]byte); ok {
|
|
||||||
return ErrFail(fmt.Errorf(
|
|
||||||
"\nFAIL (%s)\n got: %s %v%s\nexpected: %v%s",
|
|
||||||
comparator,
|
|
||||||
value, got, typeKindString(got),
|
|
||||||
expect, typeKindString(expect),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ErrFail(fmt.Errorf(
|
|
||||||
"\nFAIL (%s)\n got: %v%s\nexpected: %v%s",
|
|
||||||
comparator,
|
|
||||||
got, typeKindString(got),
|
|
||||||
expect, typeKindString(expect),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
return ErrFail(fmt.Errorf(
|
|
||||||
"\nFAIL (%s)\n got: %v%s\nexpected: %s %v%s",
|
|
||||||
comparator,
|
|
||||||
got, typeKindString(got),
|
|
||||||
comparator, expect, typeKindString(expect),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func typeKindString(value interface{}) string {
|
|
||||||
reflectValue := reflect.ValueOf(value)
|
|
||||||
kind := reflectValue.Kind().String()
|
|
||||||
result := fmt.Sprintf("%T", value)
|
|
||||||
if kind == result {
|
|
||||||
if kind == "string" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return fmt.Sprintf(" (%T)", value)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf(" (%T=%s)", value, kind)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (scope *_scope) reset() {
|
|
||||||
scope.name = ""
|
|
||||||
scope.output = scope.output[:]
|
|
||||||
scope.start = time.Time{}
|
|
||||||
scope.duration = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Terst creates a testing scope, where Is can be called and errors will be reported
|
|
||||||
// according to the top-level location of the comparison, and not where the Is call
|
|
||||||
// actually takes place. For example:
|
|
||||||
//
|
|
||||||
// func test(value int) {
|
|
||||||
// Is(value, 5) // <--- This failure is reported below.
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Terst(t, func(){
|
|
||||||
//
|
|
||||||
// Is(2, ">", 3) // <--- An error is reported here.
|
|
||||||
//
|
|
||||||
// test(5) // <--- An error is reported here.
|
|
||||||
//
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
func Terst(t *testing.T, arguments ...func()) {
|
|
||||||
scope := &_scope{
|
|
||||||
t: t,
|
|
||||||
}
|
|
||||||
|
|
||||||
pc, _, _, ok := runtime.Caller(1) // TODO Associate with the Test... func
|
|
||||||
if !ok {
|
|
||||||
panic("Here be dragons.")
|
|
||||||
}
|
|
||||||
|
|
||||||
_, scope.testFunc = findTestFunc()
|
|
||||||
|
|
||||||
registerScope(pc, scope)
|
|
||||||
|
|
||||||
for _, fn := range arguments {
|
|
||||||
func() {
|
|
||||||
scope.reset()
|
|
||||||
name := scope.testFunc.Name()
|
|
||||||
index := strings.LastIndex(scope.testFunc.Name(), ".")
|
|
||||||
if index >= 0 {
|
|
||||||
name = name[index+1:] + "(Terst)"
|
|
||||||
} else {
|
|
||||||
name = "(Terst)"
|
|
||||||
}
|
|
||||||
name = "(Terst)"
|
|
||||||
scope.name = name
|
|
||||||
scope.start = time.Now()
|
|
||||||
defer func() {
|
|
||||||
scope.duration = time.Now().Sub(scope.start)
|
|
||||||
if err := recover(); err != nil {
|
|
||||||
scope.t.Fail()
|
|
||||||
scope.report()
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
scope.report()
|
|
||||||
}()
|
|
||||||
fn()
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// From "testing"
|
|
||||||
func (scope *_scope) report() {
|
|
||||||
format := "~~~ %s: (Terst)\n%s"
|
|
||||||
if scope.t.Failed() {
|
|
||||||
fmt.Printf(format, "FAIL", scope.output)
|
|
||||||
} else if testing.Verbose() && len(scope.output) > 0 {
|
|
||||||
fmt.Printf(format, "PASS", scope.output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (scope *_scope) log(call _entry, str string) {
|
|
||||||
scope.mu.Lock()
|
|
||||||
defer scope.mu.Unlock()
|
|
||||||
scope.output = append(scope.output, decorate(call, str)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// decorate prefixes the string with the file and line of the call site
|
|
||||||
// and inserts the final newline if needed and indentation tabs for formascing.
|
|
||||||
func decorate(call _entry, s string) string {
|
|
||||||
|
|
||||||
file, line := call.File, call.Line
|
|
||||||
if call.PC > 0 {
|
|
||||||
// Truncate file name at last file name separator.
|
|
||||||
if index := strings.LastIndex(file, "/"); index >= 0 {
|
|
||||||
file = file[index+1:]
|
|
||||||
} else if index = strings.LastIndex(file, "\\"); index >= 0 {
|
|
||||||
file = file[index+1:]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
file = "???"
|
|
||||||
line = 1
|
|
||||||
}
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
// Every line is indented at least one tab.
|
|
||||||
buf.WriteByte('\t')
|
|
||||||
fmt.Fprintf(buf, "%s:%d: ", file, line)
|
|
||||||
lines := strings.Split(s, "\n")
|
|
||||||
if l := len(lines); l > 1 && lines[l-1] == "" {
|
|
||||||
lines = lines[:l-1]
|
|
||||||
}
|
|
||||||
for i, line := range lines {
|
|
||||||
if i > 0 {
|
|
||||||
// Second and subsequent lines are indented an extra tab.
|
|
||||||
buf.WriteString("\n\t\t")
|
|
||||||
}
|
|
||||||
buf.WriteString(line)
|
|
||||||
}
|
|
||||||
buf.WriteByte('\n')
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func findScope() (*_scope, _entry) {
|
|
||||||
registry.lock.RLock()
|
|
||||||
defer registry.lock.RUnlock()
|
|
||||||
table := registry.table
|
|
||||||
depth := 2 // Starting depth
|
|
||||||
call := _entry{}
|
|
||||||
for {
|
|
||||||
pc, _, _, ok := runtime.Caller(depth)
|
|
||||||
if !ok {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if scope, exists := table[pc]; exists {
|
|
||||||
pc, file, line, _ := runtime.Caller(depth - 3) // Terst(...) + func(){}() + fn() => ???()
|
|
||||||
call.PC = pc
|
|
||||||
call.File = file
|
|
||||||
call.Line = line
|
|
||||||
return scope, call
|
|
||||||
}
|
|
||||||
depth++
|
|
||||||
}
|
|
||||||
return nil, _entry{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call is a reference to a line immediately under a Terst testing scope.
|
|
||||||
type Call struct {
|
|
||||||
scope *_scope
|
|
||||||
entry _entry
|
|
||||||
}
|
|
||||||
|
|
||||||
// Caller will search the stack, looking for a Terst testing scope. If a scope
|
|
||||||
// is found, then Caller returns a Call for logging errors, accessing testing.T, etc.
|
|
||||||
// If no scope is found, Caller returns nil.
|
|
||||||
func Caller() *Call {
|
|
||||||
scope, entry := findScope()
|
|
||||||
if scope == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &Call{
|
|
||||||
scope: scope,
|
|
||||||
entry: entry,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestFunc returns the *runtime.Func entry for the top-level Test...(t testing.T)
|
|
||||||
// function.
|
|
||||||
func (cl *Call) TestFunc() *runtime.Func {
|
|
||||||
return cl.scope.testFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
// T returns the original testing.T passed to Terst(...)
|
|
||||||
func (cl *Call) T() *testing.T {
|
|
||||||
return cl.scope.t
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log is the terst version of `testing.T.Log`
|
|
||||||
func (cl *Call) Log(arguments ...interface{}) {
|
|
||||||
cl.scope.log(cl.entry, fmt.Sprintln(arguments...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logf is the terst version of `testing.T.Logf`
|
|
||||||
func (cl *Call) Logf(format string, arguments ...interface{}) {
|
|
||||||
cl.scope.log(cl.entry, fmt.Sprintf(format, arguments...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error is the terst version of `testing.T.Error`
|
|
||||||
func (cl *Call) Error(arguments ...interface{}) {
|
|
||||||
cl.scope.log(cl.entry, fmt.Sprintln(arguments...))
|
|
||||||
cl.scope.t.Fail()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Errorf is the terst version of `testing.T.Errorf`
|
|
||||||
func (cl *Call) Errorf(format string, arguments ...interface{}) {
|
|
||||||
cl.scope.log(cl.entry, fmt.Sprintf(format, arguments...))
|
|
||||||
cl.scope.t.Fail()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip is the terst version of `testing.T.Skip`
|
|
||||||
func (cl *Call) Skip(arguments ...interface{}) {
|
|
||||||
cl.scope.log(cl.entry, fmt.Sprintln(arguments...))
|
|
||||||
cl.scope.t.SkipNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skipf is the terst version of `testing.T.Skipf`
|
|
||||||
func (cl *Call) Skipf(format string, arguments ...interface{}) {
|
|
||||||
cl.scope.log(cl.entry, fmt.Sprintf(format, arguments...))
|
|
||||||
cl.scope.t.SkipNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
type _scope struct {
|
|
||||||
t *testing.T
|
|
||||||
testFunc *runtime.Func
|
|
||||||
name string
|
|
||||||
mu sync.RWMutex
|
|
||||||
output []byte
|
|
||||||
start time.Time
|
|
||||||
duration time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
type _entry struct {
|
|
||||||
PC uintptr
|
|
||||||
File string
|
|
||||||
Line int
|
|
||||||
Func *runtime.Func
|
|
||||||
}
|
|
||||||
|
|
||||||
func _findFunc(match string) (_entry, *runtime.Func) {
|
|
||||||
depth := 2 // Starting depth
|
|
||||||
for {
|
|
||||||
pc, file, line, ok := runtime.Caller(depth)
|
|
||||||
if !ok {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
fn := runtime.FuncForPC(pc)
|
|
||||||
name := fn.Name()
|
|
||||||
if index := strings.LastIndex(name, match); index >= 0 {
|
|
||||||
// Assume we have an instance of TestXyzzy in a _test file
|
|
||||||
return _entry{
|
|
||||||
PC: pc,
|
|
||||||
File: file,
|
|
||||||
Line: line,
|
|
||||||
Func: fn,
|
|
||||||
}, fn
|
|
||||||
}
|
|
||||||
depth++
|
|
||||||
}
|
|
||||||
return _entry{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func findTestFunc() (_entry, *runtime.Func) {
|
|
||||||
return _findFunc(".Test")
|
|
||||||
}
|
|
||||||
|
|
||||||
func findTerstFunc() (_entry, *runtime.Func) {
|
|
||||||
return _findFunc(".Terst")
|
|
||||||
}
|
|
||||||
26
Godeps/_workspace/src/github.com/robertkrimen/otto/test/Makefile
generated
vendored
26
Godeps/_workspace/src/github.com/robertkrimen/otto/test/Makefile
generated
vendored
@@ -1,26 +0,0 @@
|
|||||||
.PHONY: test fetch clean build err report
|
|
||||||
|
|
||||||
TESTER := tester
|
|
||||||
|
|
||||||
test: $(TESTER)
|
|
||||||
for test in test-*.js; do ./$^ -test=true $$test 1>/dev/null || exit 1; done
|
|
||||||
@echo PASS
|
|
||||||
|
|
||||||
report: $(TESTER)
|
|
||||||
./$^ -report | grep -v "MT READY"
|
|
||||||
|
|
||||||
fetch: $(TESTER)
|
|
||||||
./$^ fetch
|
|
||||||
|
|
||||||
build:
|
|
||||||
go build -a -o $(TESTER)
|
|
||||||
|
|
||||||
$(TESTER): tester.go
|
|
||||||
$(MAKE) build
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f test-*.js
|
|
||||||
rm -f $(TESTER)
|
|
||||||
|
|
||||||
err: $(TESTER)
|
|
||||||
for test in test-*.js; do ./$^ $$test; done 2>$@
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user