Rev 108 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 108 | Rev 154 | ||
---|---|---|---|
Line 27... | Line 27... | ||
27 | * on a single cache line rather than being split across two, assuming the * |
27 | * on a single cache line rather than being split across two, assuming the * |
28 | * structure is 64 bytes or less of course. * |
28 | * structure is 64 bytes or less of course. * |
29 | * * |
29 | * * |
30 | ******************************************************************************* |
30 | ******************************************************************************* |
31 | */ |
31 | */ |
32 | void AlignedMalloc(void **pointer, |
32 | void AlignedMalloc(void **pointer, uint64_t alignment, size_t size) { |
- | 33 | uint64_t temp; |
|
- | 34 | ||
33 | segments[nsegments][0] = malloc(size + alignment - 1); |
35 | segments[nsegments][0] = malloc(size + alignment - 1); |
34 | segments[nsegments][1] = |
36 | segments[nsegments][1] = segments[nsegments][0]; |
35 |
|
37 | temp = (uint64_t) segments[nsegments][0]; |
36 |
|
38 | temp = (temp + alignment - 1) & ~(alignment - 1); |
- | 39 | segments[nsegments][1] = (void *) temp; |
|
37 | *pointer = segments[nsegments][1]; |
40 | *pointer = segments[nsegments][1]; |
38 | nsegments++; |
41 | nsegments++; |
39 | } |
42 | } |
40 | 43 | ||
41 | /* |
44 | /* |
Line 67... | Line 70... | ||
67 | * AlignedRemalloc() is used to change the size of a memory block that has * |
70 | * AlignedRemalloc() is used to change the size of a memory block that has * |
68 | * previously been allocated using AlignedMalloc(). * |
71 | * previously been allocated using AlignedMalloc(). * |
69 | * * |
72 | * * |
70 | ******************************************************************************* |
73 | ******************************************************************************* |
71 | */ |
74 | */ |
72 | void AlignedRemalloc(void **pointer, |
75 | void AlignedRemalloc(void **pointer, uint64_t alignment, size_t size) { |
- | 76 | uint64_t temp; |
|
73 | int i; |
77 | int i; |
74 | 78 | ||
75 | for (i = 0; i < nsegments; i++) |
79 | for (i = 0; i < nsegments; i++) |
76 | if (segments[i][1] == *pointer) |
80 | if (segments[i][1] == *pointer) |
77 | break; |
81 | break; |
Line 79... | Line 83... | ||
79 | Print(4095, "ERROR AlignedRemalloc() given an invalid pointer\n"); |
83 | Print(4095, "ERROR AlignedRemalloc() given an invalid pointer\n"); |
80 | exit(1); |
84 | exit(1); |
81 | } |
85 | } |
82 | free(segments[i][0]); |
86 | free(segments[i][0]); |
83 | segments[i][0] = malloc(size + alignment - 1); |
87 | segments[i][0] = malloc(size + alignment - 1); |
84 | segments[i][ |
88 | temp = (uint64_t) segments[i][0]; |
85 |
|
89 | temp = (temp + alignment - 1) & ~(alignment - 1); |
86 |
|
90 | segments[i][1] = (void *) temp; |
87 | *pointer = segments[i][1]; |
91 | *pointer = segments[i][1]; |
88 | } |
92 | } |
89 | 93 | ||
90 | /* |
94 | /* |
91 | ******************************************************************************* |
95 | ******************************************************************************* |
Line 266... | Line 270... | ||
266 | int i; |
270 | int i; |
267 | static int init = 0, pipe; |
271 | static int init = 0, pipe; |
268 | static HANDLE inh; |
272 | static HANDLE inh; |
269 | DWORD dw; |
273 | DWORD dw; |
270 | 274 | ||
271 | if (!xboard && ! |
275 | if (!xboard && !isatty(fileno(stdin))) |
272 | return 0; |
276 | return 0; |
273 | if (batch_mode) |
277 | if (batch_mode) |
274 | return 0; |
278 | return 0; |
275 | if (strchr(cmd_buffer, '\n')) |
279 | if (strchr(cmd_buffer, '\n')) |
276 | return 1; |
280 | return 1; |
Line 339... | Line 343... | ||
339 | */ |
343 | */ |
340 | void ClearHashTableScores(void) { |
344 | void ClearHashTableScores(void) { |
341 | int i; |
345 | int i; |
342 | 346 | ||
343 | if (hash_table) |
347 | if (hash_table) |
344 | for (i = 0; i < |
348 | for (i = 0; i < hash_table_size; i++) { |
345 | (hash_table + i)->word2 ^= (hash_table + i)->word1; |
349 | (hash_table + i)->word2 ^= (hash_table + i)->word1; |
346 | (hash_table + i)->word1 = |
350 | (hash_table + i)->word1 = |
347 | ((hash_table + i)->word1 & mask_clear_entry) | (uint64_t) 65536; |
351 | ((hash_table + i)->word1 & mask_clear_entry) | (uint64_t) 65536; |
348 | (hash_table + i)->word2 ^= (hash_table + i)->word1; |
352 | (hash_table + i)->word2 ^= (hash_table + i)->word1; |
349 | } |
353 | } |
Line 717... | Line 721... | ||
717 | * * |
721 | * * |
718 | ******************************************************************************* |
722 | ******************************************************************************* |
719 | */ |
723 | */ |
720 | char *DisplayEvaluation(int value, int wtm) { |
724 | char *DisplayEvaluation(int value, int wtm) { |
721 | int tvalue; |
725 | int tvalue; |
722 | static char out[ |
726 | static char out[20]; |
723 | 727 | ||
724 | tvalue = (wtm) ? value : -value; |
728 | tvalue = (wtm) ? value : -value; |
725 | if (!MateScore(value)) |
729 | if (!MateScore(value) && !EGTBScore(value)) |
726 | sprintf(out, "%7.2f", ((float) tvalue) / 100.0); |
730 | sprintf(out, "%7.2f", ((float) tvalue) / 100.0); |
727 | else if (Abs(value) > MATE) { |
731 | else if (Abs(value) > MATE) { |
728 | if (tvalue < 0) |
732 | if (tvalue < 0) |
729 | sprintf(out, " -infnty"); |
733 | sprintf(out, " -infnty"); |
730 | else |
734 | else |
731 | sprintf(out, " +infnty"); |
735 | sprintf(out, " +infnty"); |
- | 736 | } else { |
|
- | 737 | if (EGTBScore(value)) { |
|
- | 738 | if (wtm) { |
|
- | 739 | if (value == TBWIN) |
|
- | 740 | sprintf(out, " Won "); |
|
- | 741 | else if (value == -TBWIN) |
|
- | 742 | sprintf(out, " Lost "); |
|
- | 743 | } else { |
|
- | 744 | if (value == TBWIN) |
|
- | 745 | sprintf(out, " -Won "); |
|
- | 746 | else if (value == -TBWIN) |
|
- | 747 | sprintf(out, " -Lost "); |
|
- | 748 | } |
|
- | 749 | } |
|
- | 750 | if (MateScore(value)) { |
|
732 |
|
751 | if (value == MATE - 2 && wtm) |
733 | sprintf(out, " Mate"); |
752 | sprintf(out, " Mate"); |
734 | else if (value == MATE - 2 && !wtm) |
753 | else if (value == MATE - 2 && !wtm) |
735 | sprintf(out, " -Mate"); |
754 | sprintf(out, " -Mate"); |
736 | else if (value == -(MATE - 1) && wtm) |
755 | else if (value == -(MATE - 1) && wtm) |
737 | sprintf(out, " -Mate"); |
756 | sprintf(out, " -Mate"); |
738 | else if (value == -(MATE - 1) && !wtm) |
757 | else if (value == -(MATE - 1) && !wtm) |
739 | sprintf(out, " Mate"); |
758 | sprintf(out, " Mate"); |
740 | else if (value > 0 && wtm) |
759 | else if (value > 0 && wtm) |
741 | sprintf(out, " Mat%.2d", (MATE - value) / 2); |
760 | sprintf(out, " Mat%.2d", (MATE - value) / 2); |
742 | else if (value > 0 && !wtm) |
761 | else if (value > 0 && !wtm) |
743 | sprintf(out, " -Mat%.2d", (MATE - value) / 2); |
762 | sprintf(out, " -Mat%.2d", (MATE - value) / 2); |
744 | else if (wtm) |
763 | else if (wtm) |
745 | sprintf(out, " -Mat%.2d", (MATE - Abs(value)) / 2); |
764 | sprintf(out, " -Mat%.2d", (MATE - Abs(value)) / 2); |
746 | else |
765 | else |
747 | sprintf(out, " Mat%.2d", (MATE - Abs(value)) / 2); |
766 | sprintf(out, " Mat%.2d", (MATE - Abs(value)) / 2); |
- | 767 | } |
|
- | 768 | } |
|
748 | return out; |
769 | return out; |
749 | } |
770 | } |
750 | 771 | ||
751 | /* |
772 | /* |
752 | ******************************************************************************* |
773 | ******************************************************************************* |
Line 819... | Line 840... | ||
819 | wtm = Flip(wtm); |
840 | wtm = Flip(wtm); |
820 | if (wtm) |
841 | if (wtm) |
821 | t_move_number++; |
842 | t_move_number++; |
822 | } |
843 | } |
823 | if (pv->pathh == 1) |
844 | if (pv->pathh == 1) |
824 | sprintf(buffer + strlen(buffer), " <HT> |
845 | sprintf(buffer + strlen(buffer), " <HT>"); |
825 | else if (pv->pathh == 2) |
846 | else if (pv->pathh == 2) |
826 | sprintf(buffer + strlen(buffer), " < |
847 | sprintf(buffer + strlen(buffer), " <3-fold>"); |
827 | else if (pv->pathh == 3) |
848 | else if (pv->pathh == 3) |
828 | sprintf(buffer + strlen(buffer), " < |
849 | sprintf(buffer + strlen(buffer), " <50-move>"); |
829 | else if (pv->pathh == 4) |
850 | else if (pv->pathh == 4) |
830 | sprintf(buffer + strlen(buffer), " < |
851 | sprintf(buffer + strlen(buffer), " <EGTB>"); |
831 | if (strlen(buffer) < 30) |
852 | if (strlen(buffer) < 30) |
832 | for (i = 0; i < 30 - |
853 | for (i = 0; i < 30 - strlen(buffer); i++) |
833 | strcat(buffer, " "); |
854 | strcat(buffer, " "); |
834 | strcpy(kibitz_text, buffer); |
855 | strcpy(kibitz_text, buffer); |
835 | for (i = pv->pathl - 1; i > 0; i--) { |
856 | for (i = pv->pathl - 1; i > 0; i--) { |
836 | wtm = Flip(wtm); |
857 | wtm = Flip(wtm); |
837 | UnmakeMove(tree, i, wtm, pv->path[i]); |
858 | UnmakeMove(tree, i, wtm, pv->path[i]); |
Line 840... | Line 861... | ||
840 | } |
861 | } |
841 | 862 | ||
842 | /* |
863 | /* |
843 | ******************************************************************************* |
864 | ******************************************************************************* |
844 | * * |
865 | * * |
845 | * DisplayFail() is used to display a |
866 | * DisplayFail() is used to display a move that fails high or low during * |
- | 867 | * the search. Normally disabled. * |
|
846 | * * |
868 | * * |
847 | ******************************************************************************* |
869 | ******************************************************************************* |
848 | */ |
870 | */ |
849 | void DisplayFail(TREE * RESTRICT tree, int type, int level, int wtm, int time, |
871 | void DisplayFail(TREE * RESTRICT tree, int type, int level, int wtm, int time, |
850 | int move, int value, int force) { |
872 | int move, int value, int force) { |
Line 857... | Line 879... | ||
857 | * return immediately. Otherwise we add the fail high/low * |
879 | * return immediately. Otherwise we add the fail high/low * |
858 | * indicator (++/--) and then display the times. * |
880 | * indicator (++/--) and then display the times. * |
859 | * * |
881 | * * |
860 | ************************************************************ |
882 | ************************************************************ |
861 | */ |
883 | */ |
862 | if (time < |
884 | if (time < noise_level) |
863 | return; |
885 | return; |
864 | if (type == 1) |
886 | if (type == 1) |
865 | fh_indicator = (wtm) ? "++" : "--"; |
887 | fh_indicator = (wtm) ? "++" : "--"; |
866 | else |
888 | else |
867 | fh_indicator = (wtm) ? "--" : "++"; |
889 | fh_indicator = (wtm) ? "--" : "++"; |
Line 889... | Line 911... | ||
889 | sprintf(buffer, "%d. (%s)", move_number, ponder_text); |
911 | sprintf(buffer, "%d. (%s)", move_number, ponder_text); |
890 | } |
912 | } |
891 | sprintf(buffer + strlen(buffer), " %s%c", OutputMove(tree, 1, wtm, move), |
913 | sprintf(buffer + strlen(buffer), " %s%c", OutputMove(tree, 1, wtm, move), |
892 | (type == 1) ? '!' : '?'); |
914 | (type == 1) ? '!' : '?'); |
893 | strcpy(kibitz_text, buffer); |
915 | strcpy(kibitz_text, buffer); |
894 | if (time >= |
916 | if (time >= noise_level || force) { |
895 | noise_block = 0; |
917 | noise_block = 0; |
896 | Lock(lock_io); |
918 | Lock(lock_io); |
897 | Print(4, "%s", buffer); |
919 | Print(4, "%s", buffer); |
898 | Unlock(lock_io); |
920 | Unlock(lock_io); |
899 | if (type == 1) |
921 | if (type == 1) |
Line 954... | Line 976... | ||
954 | t_move_number++; |
976 | t_move_number++; |
955 | } |
977 | } |
956 | if (pv->pathh == 1) |
978 | if (pv->pathh == 1) |
957 | sprintf(buffer + strlen(buffer), " <HT>"); |
979 | sprintf(buffer + strlen(buffer), " <HT>"); |
958 | else if (pv->pathh == 2) |
980 | else if (pv->pathh == 2) |
959 | sprintf(buffer + strlen(buffer), " <EGTB>"); |
- | |
960 | else if (pv->pathh == 3) |
- | |
961 | sprintf(buffer + strlen(buffer), " <3-fold>"); |
981 | sprintf(buffer + strlen(buffer), " <3-fold>"); |
962 | else if (pv->pathh == 3) |
982 | else if (pv->pathh == 3) |
963 | sprintf(buffer + strlen(buffer), " <50-move>"); |
983 | sprintf(buffer + strlen(buffer), " <50-move>"); |
- | 984 | else if (pv->pathh == 4) |
|
- | 985 | sprintf(buffer + strlen(buffer), " <EGTB>"); |
|
964 | if (nskip > 1 && smp_max_threads > 1) |
986 | if (nskip > 1 && smp_max_threads > 1) |
965 | sprintf(buffer + strlen(buffer), " (s=%d)", nskip); |
987 | sprintf(buffer + strlen(buffer), " (s=%d)", nskip); |
966 | if (strlen(buffer) < 30) { |
988 | if (strlen(buffer) < 30) { |
967 | len = 30 - strlen(buffer); |
989 | len = 30 - strlen(buffer); |
968 | for (i = 0; i < len; i++) |
990 | for (i = 0; i < len; i++) |
969 | strcat(buffer, " "); |
991 | strcat(buffer, " "); |
970 | } |
992 | } |
971 | strcpy(kibitz_text, buffer); |
993 | strcpy(kibitz_text, buffer); |
972 | if (time >= |
994 | if (time >= noise_level || force) { |
973 | noise_block = 0; |
995 | noise_block = 0; |
974 | Lock(lock_io); |
996 | Lock(lock_io); |
975 | Print(2, " "); |
997 | Print(2, " "); |
976 | if (level == 6) |
998 | if (level == 6) |
977 | Print(2, "%2i %s%s ", pv_depth, Display2Times(time), |
999 | Print(2, "%2i %s%s ", pv_depth, Display2Times(time), |
Line 998... | Line 1020... | ||
998 | bufftemp = 0; |
1020 | bufftemp = 0; |
999 | if (bufftemp) |
1021 | if (bufftemp) |
1000 | Print(2, " "); |
1022 | Print(2, " "); |
1001 | } while (bufftemp); |
1023 | } while (bufftemp); |
1002 | idle_time = 0; |
1024 | idle_time = 0; |
1003 | for (i = 0; i < |
1025 | for (i = 0; i < smp_max_threads; i++) |
1004 | idle_time += thread[i].idle; |
1026 | idle_time += thread[i].idle; |
1005 | busy_percent = |
1027 | busy_percent = |
1006 | 100 - Min(100, |
1028 | 100 - Min(100, |
1007 | 100 * idle_time / (smp_max_threads * (end_time - start_time) + 1)); |
1029 | 100 * idle_time / (smp_max_threads * (end_time - start_time) + 1)); |
1008 | Kibitz(level, twtm, pv_depth, end_time - start_time, pv->pathv, |
1030 | Kibitz(level, twtm, pv_depth, end_time - start_time, pv->pathv, |
1009 | tree->nodes_searched, busy_percent, |
1031 | tree->nodes_searched, busy_percent, tree->egtb_hits, kibitz_text); |
1010 | Unlock(lock_io); |
1032 | Unlock(lock_io); |
1011 | } |
1033 | } |
1012 | for (i = pv->pathl - 1; i > 0; i--) { |
1034 | for (i = pv->pathl - 1; i > 0; i--) { |
1013 | wtm = Flip(wtm); |
1035 | wtm = Flip(wtm); |
1014 | UnmakeMove(tree, i, wtm, pv->path[i]); |
1036 | UnmakeMove(tree, i, wtm, pv->path[i]); |
Line 1146... | Line 1168... | ||
1146 | sprintf(tout, "%3u:%02u", ttime / 60, ttime % 60); |
1168 | sprintf(tout, "%3u:%02u", ttime / 60, ttime % 60); |
1147 | } |
1169 | } |
1148 | c = strspn(tout, " "); |
1170 | c = strspn(tout, " "); |
1149 | strcat(out, "/"); |
1171 | strcat(out, "/"); |
1150 | strcat(out, tout + c); |
1172 | strcat(out, tout + c); |
1151 | } |
1173 | } else |
- | 1174 | strcat(out, " "); |
|
1152 | spaces = 13 - strlen(out); |
1175 | spaces = 13 - strlen(out); |
1153 | for (c = 0; c < spaces; c++) |
1176 | for (c = 0; c < spaces; c++) |
1154 | strcat(out, " "); |
1177 | strcat(out, " "); |
1155 | return out; |
1178 | return out; |
1156 | } |
1179 | } |
Line 1173... | Line 1196... | ||
1173 | time = time / 100; |
1196 | time = time / 100; |
1174 | sprintf(out, "%u:%02u", time / 60, time % 60); |
1197 | sprintf(out, "%u:%02u", time / 60, time % 60); |
1175 | } |
1198 | } |
1176 | return out; |
1199 | return out; |
1177 | } |
1200 | } |
1178 | - | ||
1179 | /* |
- | |
1180 | ******************************************************************************* |
- | |
1181 | * * |
- | |
1182 | * EGTBPV() is used to display the PV for a known EGTB position. It simply * |
- | |
1183 | * makes moves, looks up the position to find the shortest mate, then it * |
- | |
1184 | * follows that PV. It appends a "!" to a move that is the only move to * |
- | |
1185 | * preserve the shortest path to mate (all other moves lead to longer mates * |
- | |
1186 | * or even draws.) * |
- | |
1187 | * * |
- | |
1188 | ******************************************************************************* |
- | |
1189 | */ |
- | |
1190 | #if !defined(NOEGTB) |
- | |
1191 | void EGTBPV(TREE * RESTRICT tree, int wtm) { |
- | |
1192 | uint64_t hk[1024], phk[1024], pos[1024]; |
- | |
1193 | unsigned moves[1024], current[256], *last; |
- | |
1194 | int value, ply, i, j, nmoves; |
- | |
1195 | int t_move_number, best = 0, bestmv = 0, optimal_mv = 0, legal; |
- | |
1196 | char buffer[16384], *next; |
- | |
1197 | - | ||
1198 | /* |
- | |
1199 | ************************************************************ |
- | |
1200 | * * |
- | |
1201 | * First, see if this is a known EGTB position. If not, * |
- | |
1202 | * we can bug out right now. * |
- | |
1203 | * * |
- | |
1204 | ************************************************************ |
- | |
1205 | */ |
- | |
1206 | if (!EGTB_setup) |
- | |
1207 | return; |
- | |
1208 | tree->status[1] = tree->status[0]; |
- | |
1209 | if (Castle(1, white) + Castle(1, white)) |
- | |
1210 | return; |
- | |
1211 | if (!EGTBProbe(tree, 1, wtm, &value)) |
- | |
1212 | return; |
- | |
1213 | t_move_number = move_number; |
- | |
1214 | sprintf(buffer, "%d.", move_number); |
- | |
1215 | if (!wtm) |
- | |
1216 | sprintf(buffer + strlen(buffer), " ..."); |
- | |
1217 | /* |
- | |
1218 | ************************************************************ |
- | |
1219 | * * |
- | |
1220 | * The rest is simple, but messy. Generate all moves, * |
- | |
1221 | * then find the move with the best egtb score and make it * |
- | |
1222 | * (note that if there is only one that is optimal, it is * |
- | |
1223 | * flagged as such). We then repeat this over and over * |
- | |
1224 | * until we reach the end, or until we repeat a move and * |
- | |
1225 | * can call it a repetition. * |
- | |
1226 | * * |
- | |
1227 | ************************************************************ |
- | |
1228 | */ |
- | |
1229 | for (ply = 1; ply < 1024; ply++) { |
- | |
1230 | pos[ply] = HashKey; |
- | |
1231 | last = GenerateCaptures(tree, 1, wtm, current); |
- | |
1232 | last = GenerateNoncaptures(tree, 1, wtm, last); |
- | |
1233 | nmoves = last - current; |
- | |
1234 | best = -MATE - 1; |
- | |
1235 | legal = 0; |
- | |
1236 | for (i = 0; i < nmoves; i++) { |
- | |
1237 | MakeMove(tree, 1, wtm, current[i]); |
- | |
1238 | if (!Check(wtm)) { |
- | |
1239 | legal++; |
- | |
1240 | if (TotalAllPieces == 2 || EGTBProbe(tree, 2, Flip(wtm), &value)) { |
- | |
1241 | if (TotalAllPieces > 2) |
- | |
1242 | value = -value; |
- | |
1243 | else |
- | |
1244 | value = DrawScore(wtm); |
- | |
1245 | if (value > best) { |
- | |
1246 | best = value; |
- | |
1247 | bestmv = current[i]; |
- | |
1248 | optimal_mv = 1; |
- | |
1249 | } else if (value == best) |
- | |
1250 | optimal_mv = 0; |
- | |
1251 | } |
- | |
1252 | } |
- | |
1253 | UnmakeMove(tree, 1, wtm, current[i]); |
- | |
1254 | } |
- | |
1255 | if (best > -MATE - 1) { |
- | |
1256 | moves[ply] = bestmv; |
- | |
1257 | if (ply > 1 && wtm) |
- | |
1258 | sprintf(buffer + strlen(buffer), " %d.", t_move_number); |
- | |
1259 | sprintf(buffer + strlen(buffer), " %s", OutputMove(tree, 1, wtm, |
- | |
1260 | bestmv)); |
- | |
1261 | if (!strchr(buffer, '#') && legal > 1 && optimal_mv) |
- | |
1262 | sprintf(buffer + strlen(buffer), "!"); |
- | |
1263 | hk[ply] = HashKey; |
- | |
1264 | phk[ply] = PawnHashKey; |
- | |
1265 | MakeMove(tree, 1, wtm, bestmv); |
- | |
1266 | tree->status[1] = tree->status[2]; |
- | |
1267 | wtm = Flip(wtm); |
- | |
1268 | for (j = 2 - (ply & 1); j < ply; j += 2) |
- | |
1269 | if (pos[ply] == pos[j]) |
- | |
1270 | break; |
- | |
1271 | if (j < ply) |
- | |
1272 | break; |
- | |
1273 | if (wtm) |
- | |
1274 | t_move_number++; |
- | |
1275 | if (strchr(buffer, '#')) |
- | |
1276 | break; |
- | |
1277 | } else { |
- | |
1278 | ply--; |
- | |
1279 | break; |
- | |
1280 | } |
- | |
1281 | } |
- | |
1282 | nmoves = ply; |
- | |
1283 | for (; ply > 0; ply--) { |
- | |
1284 | wtm = Flip(wtm); |
- | |
1285 | tree->save_hash_key[1] = hk[ply]; |
- | |
1286 | tree->save_pawn_hash_key[1] = phk[ply]; |
- | |
1287 | UnmakeMove(tree, 1, wtm, moves[ply]); |
- | |
1288 | tree->status[2] = tree->status[1]; |
- | |
1289 | } |
- | |
1290 | next = buffer; |
- | |
1291 | while (nmoves) { |
- | |
1292 | if ((int) strlen(next) > line_length) { // Pierre-Marie Baty -- added type cast |
- | |
1293 | int i; |
- | |
1294 | - | ||
1295 | for (i = 0; i < 16; i++) |
- | |
1296 | if (*(next + 64 + i) == ' ') |
- | |
1297 | break; |
- | |
1298 | *(next + 64 + i) = 0; |
- | |
1299 | printf("%s\n", next); |
- | |
1300 | next += 64 + i + 1; |
- | |
1301 | } else { |
- | |
1302 | printf("%s\n", next); |
- | |
1303 | break; |
- | |
1304 | } |
- | |
1305 | } |
- | |
1306 | } |
- | |
1307 | #endif |
- | |
1308 | 1201 | ||
1309 | /* |
1202 | /* |
1310 | ******************************************************************************* |
1203 | ******************************************************************************* |
1311 | * * |
1204 | * * |
1312 | * FormatPV() is used to display a PV during the search. It will also note * |
1205 | * FormatPV() is used to display a PV during the search. It will also note * |
Line 1417... | Line 1310... | ||
1417 | */ |
1310 | */ |
1418 | unsigned int ReadClock(void) { |
1311 | unsigned int ReadClock(void) { |
1419 | #if defined(UNIX) |
1312 | #if defined(UNIX) |
1420 | struct timeval timeval; |
1313 | struct timeval timeval; |
1421 | struct timezone timezone; |
1314 | struct timezone timezone; |
1422 | #else |
- | |
1423 | //HANDLE hThread; // Pierre-Marie Baty -- unreferenced variable |
- | |
1424 | //FILETIME ftCreate, ftExit, ftKernel, ftUser; // Pierre-Marie Baty -- unreferenced variables |
- | |
1425 | //uint64_t tUser64; // Pierre-Marie Baty -- unreferenced variable |
- | |
1426 | #endif |
1315 | #endif |
1427 | #if defined(UNIX) |
1316 | #if defined(UNIX) |
1428 | gettimeofday(&timeval, &timezone); |
1317 | gettimeofday(&timeval, &timezone); |
1429 | return timeval.tv_sec * 100 + (timeval.tv_usec / 10000); |
1318 | return timeval.tv_sec * 100 + (timeval.tv_usec / 10000); |
1430 | #else |
1319 | #else |
Line 1441... | Line 1330... | ||
1441 | ******************************************************************************* |
1330 | ******************************************************************************* |
1442 | */ |
1331 | */ |
1443 | int FindBlockID(TREE * RESTRICT which) { |
1332 | int FindBlockID(TREE * RESTRICT which) { |
1444 | int i; |
1333 | int i; |
1445 | 1334 | ||
1446 | for (i = 0; i <= |
1335 | for (i = 0; i <= smp_max_threads * 64; i++) |
1447 | if (which == block[i]) |
1336 | if (which == block[i]) |
1448 | return i; |
1337 | return i; |
1449 | return -1; |
1338 | return -1; |
1450 | } |
1339 | } |
1451 | 1340 | ||
Line 1568... | Line 1457... | ||
1568 | pdist = Abs(Rank(pawn) - Rank(queen)) + !ptm; |
1457 | pdist = Abs(Rank(pawn) - Rank(queen)) + !ptm; |
1569 | kdist = Distance(king, queen); |
1458 | kdist = Distance(king, queen); |
1570 | return pdist >= kdist; |
1459 | return pdist >= kdist; |
1571 | } |
1460 | } |
1572 | 1461 | ||
1573 | /* last modified |
1462 | /* last modified 07/13/16 */ |
1574 | /* |
1463 | /* |
1575 | ******************************************************************************* |
1464 | ******************************************************************************* |
1576 | * * |
1465 | * * |
1577 | * |
1466 | * Mated() is used to determine if the game has ended by checkmate. * |
1578 | * |
1467 | * * |
- | 1468 | * We return 0 if the game doesn't end here, 1 if the side on move is mated * |
|
- | 1469 | * and 2 if the side on move is stalemated. * |
|
1579 | * * |
1470 | * * |
1580 | ******************************************************************************* |
1471 | ******************************************************************************* |
1581 | */ |
1472 | */ |
1582 | void NewGame(int save) { |
- | |
1583 |
|
1473 | int Mated(TREE * RESTRICT tree, int ply, int wtm) { |
1584 |
|
1474 | unsigned int rmoves[256], *mvp, *lastm; |
1585 | static int save_resign = 0, save_resign_count = 0, save_draw_count = 0; |
- | |
1586 | static int save_learning = 0, save_learn = 0, save_accept_draws = 0; |
- | |
1587 | int |
1475 | int temp = 0; |
1588 | 1476 | ||
1589 | new_game = 0; |
- | |
1590 |
|
1477 | /* |
1591 |
|
1478 | ************************************************************ |
1592 | save_kibitz = kibitz; |
- | |
1593 | save_resign = resign; |
- | |
1594 |
|
1479 | * * |
1595 |
|
1480 | * first, use GenerateMoves() to generate the set of * |
1596 |
|
1481 | * legal moves from the root position, after making the * |
1597 | save_learn = learn; |
- | |
1598 |
|
1482 | * test move passed in. * |
1599 | } else { |
- | |
1600 |
|
1483 | * * |
1601 | learn_value = |
- | |
1602 |
|
1484 | ************************************************************ |
1603 | LearnBook(); |
- | |
1604 |
|
1485 | */ |
1605 | if (xboard) { |
- | |
1606 |
|
1486 | lastm = GenerateCaptures(tree, ply, wtm, rmoves); |
1607 |
|
1487 | lastm = GenerateNoncaptures(tree, ply, wtm, lastm); |
1608 |
|
1488 | /* |
1609 | over = 0; |
- | |
1610 | moves_out_of_book = 0; |
- | |
1611 | learn_positions_count = 0; |
- | |
1612 | learn_value = 0; |
- | |
1613 | ponder_move = 0; |
- | |
1614 | last_search_value = 0; |
- | |
1615 | last_pv.pathd = 0; |
- | |
1616 | last_pv.pathl = 0; |
- | |
1617 | strcpy(initial_position, ""); |
- | |
1618 | InitializeChessBoard(tree); |
- | |
1619 | InitializeHashTables(0); |
- | |
1620 | force = 0; |
- | |
1621 | books_file = normal_bs_file; |
- | |
1622 | draw_score[0] = 0; |
- | |
1623 | draw_score[1] = 0; |
- | |
1624 | game_wtm = 1; |
- | |
1625 | move_number = 1; |
- | |
1626 | tc_time_remaining[white] = tc_time; |
- | |
1627 | tc_time_remaining[black] = tc_time; |
- | |
1628 | tc_moves_remaining[white] = tc_moves; |
- | |
1629 |
|
1489 | ************************************************************ |
1630 | if (move_actually_played) { |
- | |
1631 | if (log_file) { |
- | |
1632 | fclose(log_file); |
- | |
1633 | fclose(history_file); |
- | |
1634 | id = InitializeGetLogID(); |
- | |
1635 |
|
1490 | * * |
1636 |
|
1491 | * now make each move and use eliminate any that leave * |
1637 |
|
1492 | * king in check (which makes those moves illegal.) * |
1638 |
|
1493 | * * |
1639 | if (!history_file) { |
- | |
1640 |
|
1494 | ************************************************************ |
1641 | CraftyExit(1); |
- | |
1642 | } |
- | |
1643 | } |
- | |
1644 |
|
1495 | */ |
1645 |
|
1496 | for (mvp = rmoves; mvp < lastm; mvp++) { |
1646 | book_selection_width = save_book_selection_width; |
- | |
1647 |
|
1497 | MakeMove(tree, ply, wtm, *mvp); |
1648 |
|
1498 | temp = Check(wtm); |
1649 | resign_count = save_resign_count; |
- | |
1650 | resign_counter = 0; |
- | |
1651 |
|
1499 | UnmakeMove(tree, ply, wtm, *mvp); |
1652 | accept_draws = save_accept_draws; |
- | |
1653 | draw_counter = 0; |
- | |
1654 | usage_level = 0; |
- | |
1655 | learning = save_learning; |
- | |
1656 | learn = save_learn; |
- | |
1657 |
|
1500 | if (!temp) |
1658 |
|
1501 | break; |
1659 | tree->nodes_searched = 0; |
- | |
1660 | kibitz_text[0] = 0; |
- | |
1661 | } |
1502 | } |
- | 1503 | /* |
|
- | 1504 | ************************************************************ |
|
- | 1505 | * * |
|
- | 1506 | * if there is one move that did not leave us in check, * |
|
- | 1507 | * then it can't be checkmate/stalemate. * |
|
- | 1508 | * * |
|
- | 1509 | ************************************************************ |
|
- | 1510 | */ |
|
- | 1511 | if (!temp) |
|
- | 1512 | return 0; |
|
- | 1513 | /* |
|
- | 1514 | ************************************************************ |
|
- | 1515 | * * |
|
- | 1516 | * No legal moves. If we are in check, we have been * |
|
- | 1517 | * checkmated, otherwise we are stalemated. * |
|
- | 1518 | * * |
|
- | 1519 | ************************************************************ |
|
- | 1520 | */ |
|
- | 1521 | if (Check(wtm)) |
|
- | 1522 | return 1; |
|
- | 1523 | return 2; |
|
1662 | } |
1524 | } |
1663 | 1525 | ||
1664 | /* |
1526 | /* |
1665 | ******************************************************************************* |
1527 | ******************************************************************************* |
1666 | * * |
1528 | * * |
Line 1959... | Line 1821... | ||
1959 | int ReadInput(void) { |
1821 | int ReadInput(void) { |
1960 | int bytes; |
1822 | int bytes; |
1961 | char buffer[4096], *end; |
1823 | char buffer[4096], *end; |
1962 | 1824 | ||
1963 | do |
1825 | do |
1964 | bytes = |
1826 | bytes = read(fileno(input_stream), buffer, 2048); |
1965 | while (bytes < 0 && errno == EINTR); |
1827 | while (bytes < 0 && errno == EINTR); |
1966 | if (bytes == 0) { |
1828 | if (bytes == 0) { |
1967 | if (input_stream != stdin) |
1829 | if (input_stream != stdin) |
1968 | fclose(input_stream); |
1830 | fclose(input_stream); |
1969 | input_stream = stdin; |
1831 | input_stream = stdin; |
Line 2082... | Line 1944... | ||
2082 | * If we don't have any data in the buffer, the first step * |
1944 | * If we don't have any data in the buffer, the first step * |
2083 | * is to read the next line. * |
1945 | * is to read the next line. * |
2084 | * * |
1946 | * * |
2085 | ************************************************************ |
1947 | ************************************************************ |
2086 | */ |
1948 | */ |
2087 | while ( |
1949 | while (FOREVER) { |
2088 | if (!data) { |
1950 | if (!data) { |
2089 | eof = fgets(input_buffer, 4096, input); |
1951 | eof = fgets(input_buffer, 4096, input); |
2090 | if (!eof) |
1952 | if (!eof) |
2091 | return -1; |
1953 | return -1; |
2092 | if (strchr(input_buffer, '\n')) |
1954 | if (strchr(input_buffer, '\n')) |
Line 2171... | Line 2033... | ||
2171 | ************************************************************ |
2033 | ************************************************************ |
2172 | */ |
2034 | */ |
2173 | last_good_line = lines_read; |
2035 | last_good_line = lines_read; |
2174 | analysis_move[0] = 0; |
2036 | analysis_move[0] = 0; |
2175 | if (strchr(buffer, '{') || strchr(buffer, '(')) |
2037 | if (strchr(buffer, '{') || strchr(buffer, '(')) |
2176 | while ( |
2038 | while (FOREVER) { |
2177 | char *skip, *ch; |
2039 | char *skip, *ch; |
2178 | 2040 | ||
2179 | analysis = 1; |
2041 | analysis = 1; |
2180 | while ((ch = strpbrk(buffer, "(){}[]"))) { |
2042 | while ((ch = strpbrk(buffer, "(){}[]"))) { |
2181 | if (*ch == '(') { |
2043 | if (*ch == '(') { |
Line 2341... | Line 2203... | ||
2341 | else |
2203 | else |
2342 | sprintf(prefix, "whisper"); |
2204 | sprintf(prefix, "whisper"); |
2343 | switch (level) { |
2205 | switch (level) { |
2344 | case 1: |
2206 | case 1: |
2345 | if ((kibitz & 15) >= 1) { |
2207 | if ((kibitz & 15) >= 1) { |
2346 | if (value > 0) |
2208 | if (value > 0) |
2347 | printf("%s mate in %d moves.\n\n", prefix, value); |
2209 | printf("%s mate in %d moves.\n\n", prefix, value); |
2348 | } |
- | |
2349 | if (value < 0) |
2210 | if (value < 0) |
2350 | printf("%s mated in %d moves.\n\n", prefix, -value); |
2211 | printf("%s mated in %d moves.\n\n", prefix, -value); |
2351 | } |
- | |
2352 | } |
2212 | } |
2353 | break; |
2213 | break; |
2354 | case 2: |
2214 | case 2: |
2355 | if ((kibitz & 15) >= 2) |
2215 | if ((kibitz & 15) >= 2) { |
2356 | printf("%s ply=%d; eval=%s; nps=%s; time=%s(%d%%) |
2216 | printf("%s ply=%d; eval=%s; nps=%s; time=%s(%d%%)", prefix, depth, |
2357 |
|
2217 | DisplayEvaluationKibitz(value, wtm), DisplayKMB(nps, 0), |
2358 |
|
2218 | DisplayTimeKibitz(time), ip); |
- | 2219 | printf("; egtb=%s\n", DisplayKMB(tb_hits, 0)); |
|
- | 2220 | } |
|
- | 2221 | break; |
|
2359 | case 3: |
2222 | case 3: |
2360 | if ((kibitz & 15) >= 3 && (nodes > 5000 || level == 2)) |
2223 | if ((kibitz & 15) >= 3 && (nodes > 5000 || level == 2)) |
2361 | printf("%s %s\n", prefix, pv); |
2224 | printf("%s %s\n", prefix, pv); |
2362 | break; |
2225 | break; |
2363 | case 4: |
2226 | case 4: |
Line 2368... | Line 2231... | ||
2368 | if ((kibitz & 15) >= 5 && nodes > 5000) { |
2231 | if ((kibitz & 15) >= 5 && nodes > 5000) { |
2369 | printf("%s d%d-> %s/s %s(%d%%) %s %s ", prefix, depth, |
2232 | printf("%s d%d-> %s/s %s(%d%%) %s %s ", prefix, depth, |
2370 | DisplayKMB(nps, 0), DisplayTimeKibitz(time), ip, |
2233 | DisplayKMB(nps, 0), DisplayTimeKibitz(time), ip, |
2371 | DisplayEvaluationKibitz(value, wtm), pv); |
2234 | DisplayEvaluationKibitz(value, wtm), pv); |
2372 | if (tb_hits) |
2235 | if (tb_hits) |
2373 | printf(" |
2236 | printf("egtb=%s", DisplayKMB(tb_hits, 0)); |
2374 | printf("\n"); |
2237 | printf("\n"); |
2375 | } |
2238 | } |
2376 | break; |
2239 | break; |
2377 | } |
2240 | } |
2378 | value = (wtm) ? value : -value; |
2241 | value = (wtm) ? value : -value; |
Line 2417... | Line 2280... | ||
2417 | if (tree->pv[1].path[1] == root_moves[i].move) |
2280 | if (tree->pv[1].path[1] == root_moves[i].move) |
2418 | break; |
2281 | break; |
2419 | root_moves[i].path = tree->pv[1]; |
2282 | root_moves[i].path = tree->pv[1]; |
2420 | root_moves[i].bm_age = 4; |
2283 | root_moves[i].bm_age = 4; |
2421 | } |
2284 | } |
2422 | } |
- | |
2423 | - | ||
2424 | /* |
- | |
2425 | ******************************************************************************* |
- | |
2426 | * * |
- | |
2427 | * SortRootMoves() is used to sort the root move list based on the value * |
- | |
2428 | * saved for each move. After a fail high or fail low, we always re-sort * |
- | |
2429 | * the root move list so that the best move found so far is first in the * |
- | |
2430 | * list. This is primarily intended as a defense against getting a score * |
- | |
2431 | * for the first root move, and then getting a fail-high on the second move, * |
- | |
2432 | * which should move this move to the front of the moves. But if the move * |
- | |
2433 | * then fails low, we want to move it back down since a deeper/less-reduced * |
- | |
2434 | * search did not verify the fail-high. * |
- | |
2435 | * * |
- | |
2436 | ******************************************************************************* |
- | |
2437 | */ |
- | |
2438 | void SortRootMoves() { |
- | |
2439 | ROOT_MOVE rtemp; |
- | |
2440 | int mvp, done; |
- | |
2441 | - | ||
2442 | do { |
- | |
2443 | done = 1; |
- | |
2444 | for (mvp = 0; mvp < n_root_moves - 1; mvp++) { |
- | |
2445 | if (root_moves[mvp].path.pathv < root_moves[mvp + 1].path.pathv) { |
- | |
2446 | rtemp = root_moves[mvp]; |
- | |
2447 | root_moves[mvp] = root_moves[mvp + 1]; |
- | |
2448 | root_moves[mvp + 1] = rtemp; |
- | |
2449 | done = 0; |
- | |
2450 | } |
- | |
2451 | } |
- | |
2452 | } while (!done); |
- | |
2453 | } |
2285 | } |
2454 | 2286 | ||
2455 | /* |
2287 | /* |
2456 | ******************************************************************************* |
2288 | ******************************************************************************* |
2457 | * * |
2289 | * * |
Line 2491... | Line 2323... | ||
2491 | ******************************************************************************* |
2323 | ******************************************************************************* |
2492 | */ |
2324 | */ |
2493 | int StrCnt(char *string, char testchar) { |
2325 | int StrCnt(char *string, char testchar) { |
2494 | int count = 0, i; |
2326 | int count = 0, i; |
2495 | 2327 | ||
2496 | for (i = 0; i < |
2328 | for (i = 0; i < strlen(string); i++) |
2497 | if (string[i] == testchar) |
2329 | if (string[i] == testchar) |
2498 | count++; |
2330 | count++; |
2499 | return count; |
2331 | return count; |
2500 | } |
2332 | } |
2501 | 2333 | ||
Line 2574... | Line 2406... | ||
2574 | */ |
2406 | */ |
2575 | case pawn: |
2407 | case pawn: |
2576 | if (((wtm) ? To(move) - From(move) : From(move) - To(move)) < 0) |
2408 | if (((wtm) ? To(move) - From(move) : From(move) - To(move)) < 0) |
2577 | return 0; |
2409 | return 0; |
2578 | if (Abs(From(move) - To(move)) == 8) |
2410 | if (Abs(From(move) - To(move)) == 8) |
2579 | return |
2411 | return PcOnSq(To(move)) ? 0 : 1; |
2580 | if (Abs(From(move) - To(move)) == 16) |
2412 | if (Abs(From(move) - To(move)) == 16) |
2581 | return (PcOnSq(To(move)) || PcOnSq(To(move) + epdir[wtm])) ? 0 : 1; |
2413 | return (PcOnSq(To(move)) || PcOnSq(To(move) + epdir[wtm])) ? 0 : 1; |
2582 | if (!Captured(move)) |
2414 | if (!Captured(move)) |
2583 | return 0; |
2415 | return 0; |
2584 | /* |
2416 | /* |
Line 2674... | Line 2506... | ||
2674 | static ULONG ulNumaNodes; |
2506 | static ULONG ulNumaNodes; |
2675 | static ULONG ulNumaNode = 0; |
2507 | static ULONG ulNumaNode = 0; |
2676 | 2508 | ||
2677 | // Get NUMA-related information from Windows |
2509 | // Get NUMA-related information from Windows |
2678 | static void WinNumaInit(void) { |
2510 | static void WinNumaInit(void) { |
2679 | //DWORD_PTR dwMask; // Pierre-Marie Baty -- unreferenced variable |
- | |
2680 | HMODULE hModule; |
2511 | HMODULE hModule; |
2681 | ULONG ulCPU, ulNode; |
2512 | ULONG ulCPU, ulNode; |
2682 | ULONGLONG ullMask; |
2513 | ULONGLONG ullMask; |
2683 | DWORD dwCPU; |
2514 | DWORD dwCPU; |
2684 | 2515 | ||
Line 2697... | Line 2528... | ||
2697 | if (pGetNumaHighestNodeNumber && pGetNumaNodeProcessorMask && |
2528 | if (pGetNumaHighestNodeNumber && pGetNumaNodeProcessorMask && |
2698 | pGetNumaHighestNodeNumber(&ulNumaNodes) && (ulNumaNodes > 0)) { |
2529 | pGetNumaHighestNodeNumber(&ulNumaNodes) && (ulNumaNodes > 0)) { |
2699 | fSystemIsNUMA = TRUE; |
2530 | fSystemIsNUMA = TRUE; |
2700 | if (ulNumaNodes > 255) |
2531 | if (ulNumaNodes > 255) |
2701 | ulNumaNodes = 255; |
2532 | ulNumaNodes = 255; |
2702 | printf("System is NUMA. |
2533 | printf("System is NUMA. " PRId64 " nodes reported by Windows\n", |
2703 | ulNumaNodes + 1); |
2534 | ulNumaNodes + 1); |
2704 | for (ulNode = 0; ulNode <= ulNumaNodes; ulNode++) { |
2535 | for (ulNode = 0; ulNode <= ulNumaNodes; ulNode++) { |
2705 | pGetNumaNodeProcessorMask((UCHAR) ulNode, |
2536 | pGetNumaNodeProcessorMask((UCHAR) ulNode, |
2706 | &ullProcessorMask[ulNode]); |
2537 | &ullProcessorMask[ulNode]); |
2707 | printf("Node |
2538 | printf("Node " PRId64 " CPUs: ", ulNode); |
2708 | ullMask = ullProcessorMask[ulNode]; |
2539 | ullMask = ullProcessorMask[ulNode]; |
2709 | if (0 == ullMask) |
2540 | if (0 == ullMask) |
2710 | fSystemIsNUMA = FALSE; |
2541 | fSystemIsNUMA = FALSE; |
2711 | else { |
2542 | else { |
2712 | ulCPU = 0; |
2543 | ulCPU = 0; |
2713 | do { |
2544 | do { |
2714 | if (ullMask & 1) |
2545 | if (ullMask & 1) |
2715 | printf(" |
2546 | printf("" PRId64 " ", ulCPU); |
2716 | ulCPU++; |
2547 | ulCPU++; |
2717 | ullMask >>= 1; |
2548 | ullMask >>= 1; |
2718 | } while (ullMask); |
2549 | } while (ullMask); |
2719 | } |
2550 | } |
2720 | printf("\n"); |
2551 | printf("\n"); |
2721 | } |
2552 | } |
2722 | // Thread 0 was already started on some CPU. To simplify things further, |
2553 | // Thread 0 was already started on some CPU. To simplify things further, |
2723 | // exchange |
2554 | // exchange ProcessorMask[0] and ProcessorMask[node for that CPU], |
2724 | // so |
2555 | // so ProcessorMask[0] would always be node for thread 0 |
2725 | dwCPU = |
2556 | dwCPU = |
2726 | pSetThreadIdealProcessor(GetCurrentThread(), MAXIMUM_PROCESSORS); |
2557 | pSetThreadIdealProcessor(GetCurrentThread(), MAXIMUM_PROCESSORS); |
2727 | printf("Current ideal CPU is |
2558 | printf("Current ideal CPU is %llu\n", dwCPU); |
2728 | pSetThreadIdealProcessor(GetCurrentThread(), dwCPU); |
2559 | pSetThreadIdealProcessor(GetCurrentThread(), dwCPU); |
2729 | if ((((DWORD) - 1) != dwCPU) && (MAXIMUM_PROCESSORS != dwCPU) |
2560 | if ((((DWORD) - 1) != dwCPU) && (MAXIMUM_PROCESSORS != dwCPU) |
2730 | && !(ullProcessorMask[0] & ( |
2561 | && !(ullProcessorMask[0] & (1u << dwCPU))) { |
2731 | for (ulNode = 1; ulNode <= ulNumaNodes; ulNode++) { |
2562 | for (ulNode = 1; ulNode <= ulNumaNodes; ulNode++) { |
2732 | if (ullProcessorMask[ulNode] & ( |
2563 | if (ullProcessorMask[ulNode] & (1u << dwCPU)) { |
2733 | printf("Exchanging nodes 0 and |
2564 | printf("Exchanging nodes 0 and " PRId64 "\n", ulNode); |
2734 | ullMask = ullProcessorMask[ulNode]; |
2565 | ullMask = ullProcessorMask[ulNode]; |
2735 | ullProcessorMask[ulNode] = ullProcessorMask[0]; |
2566 | ullProcessorMask[ulNode] = ullProcessorMask[0]; |
2736 | ullProcessorMask[0] = ullMask; |
2567 | ullProcessorMask[0] = ullMask; |
2737 | break; |
2568 | break; |
2738 | } |
2569 | } |
Line 2755... | Line 2586... | ||
2755 | if (fSystemIsNUMA) { |
2586 | if (fSystemIsNUMA) { |
2756 | ulNumaNode++; |
2587 | ulNumaNode++; |
2757 | if (ulNumaNode > ulNumaNodes) |
2588 | if (ulNumaNode > ulNumaNodes) |
2758 | ulNumaNode = 0; |
2589 | ulNumaNode = 0; |
2759 | ullMask = ullProcessorMask[ulNumaNode]; |
2590 | ullMask = ullProcessorMask[ulNumaNode]; |
2760 | printf("Starting thread on node |
2591 | printf("Starting thread on node " PRId64 " CPU mask %I64d\n", ulNumaNode, |
2761 | ullMask); |
2592 | ullMask); |
2762 | SetThreadAffinityMask(GetCurrentThread(), (DWORD_PTR) ullMask); |
2593 | SetThreadAffinityMask(GetCurrentThread(), (DWORD_PTR) ullMask); |
2763 | hThread = (HANDLE) _beginthreadex(0, 0, func, args, CREATE_SUSPENDED, 0); |
2594 | hThread = (HANDLE) _beginthreadex(0, 0, func, args, CREATE_SUSPENDED, 0); |
2764 | SetThreadAffinityMask(hThread, (DWORD_PTR) ullMask); |
2595 | SetThreadAffinityMask(hThread, (DWORD_PTR) ullMask); |
2765 | ResumeThread(hThread); |
2596 | ResumeThread(hThread); |
2766 | SetThreadAffinityMask(GetCurrentThread(), |
2597 | SetThreadAffinityMask(GetCurrentThread(), ullProcessorMask[0]); |
2767 | } else |
2598 | } else |
2768 | hThread = (HANDLE) _beginthreadex(0, 0, func, args, 0, 0); |
2599 | hThread = (HANDLE) _beginthreadex(0, 0, func, args, 0, 0); |
2769 | return hThread; |
2600 | return hThread; |
2770 | } |
2601 | } |
2771 | # endif |
2602 | # endif |
Line 2779... | Line 2610... | ||
2779 | 2610 | ||
2780 | WinNumaInit(); |
2611 | WinNumaInit(); |
2781 | if (fSystemIsNUMA) { |
2612 | if (fSystemIsNUMA) { |
2782 | ulNode = iThread % (ulNumaNodes + 1); |
2613 | ulNode = iThread % (ulNumaNodes + 1); |
2783 | hThread = GetCurrentThread(); |
2614 | hThread = GetCurrentThread(); |
2784 | dwAffinityMask = SetThreadAffinityMask(hThread, |
2615 | dwAffinityMask = SetThreadAffinityMask(hThread, ullProcessorMask[ulNode]); |
2785 | pBytes = VirtualAlloc(NULL, cbBytes, MEM_COMMIT, PAGE_READWRITE); |
2616 | pBytes = VirtualAlloc(NULL, cbBytes, MEM_COMMIT, PAGE_READWRITE); |
2786 | if (pBytes == NULL) |
2617 | if (pBytes == NULL) |
2787 | ExitProcess(GetLastError()); |
2618 | ExitProcess(GetLastError()); |
2788 | memset(pBytes, 0, cbBytes); |
2619 | memset(pBytes, 0, cbBytes); |
2789 | SetThreadAffinityMask(hThread, dwAffinityMask); |
2620 | SetThreadAffinityMask(hThread, dwAffinityMask); |
Line 2825... | Line 2656... | ||
2825 | dwStep = dwPageSize * cThreads; |
2656 | dwStep = dwPageSize * cThreads; |
2826 | pEnd = pBase + cbBytes; |
2657 | pEnd = pBase + cbBytes; |
2827 | for (iThread = 0; iThread < cThreads; iThread++) { |
2658 | for (iThread = 0; iThread < cThreads; iThread++) { |
2828 | ulNode = iThread % (ulNumaNodes + 1); |
2659 | ulNode = iThread % (ulNumaNodes + 1); |
2829 | dwAffinityMask = |
2660 | dwAffinityMask = |
2830 | SetThreadAffinityMask(hThread, |
2661 | SetThreadAffinityMask(hThread, ullProcessorMask[ulNode]); |
2831 | for (pch = pBase + iThread * dwPageSize; pch < pEnd; pch += dwStep) { |
2662 | for (pch = pBase + iThread * dwPageSize; pch < pEnd; pch += dwStep) { |
2832 | lpvResult = VirtualAlloc(pch, // next page to commit |
2663 | lpvResult = VirtualAlloc(pch, // next page to commit |
2833 | dwPageSize, // page size, in bytes |
2664 | dwPageSize, // page size, in bytes |
2834 | MEM_COMMIT, // allocate a committed page |
2665 | MEM_COMMIT, // allocate a committed page |
2835 | PAGE_READWRITE); // read/write access |
2666 | PAGE_READWRITE); // read/write access |