Subversion Repositories Games.Chess Giants

Rev

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 2... Line 2...
2
#include "data.h"
2
#include "data.h"
3
#include "epdglue.h"
3
#include "epdglue.h"
4
#if (CPUS > 1)
-
 
5
/* modified 11/04/15 */
4
/* modified 08/03/16 */
6
/*
5
/*
7
 *******************************************************************************
6
 *******************************************************************************
8
 *                                                                             *
7
 *                                                                             *
9
 *   Split() is the driver for the threaded parallel search in Crafty.  The    *
8
 *   Split() is the driver for the threaded parallel search in Crafty.  The    *
10
 *   basic idea is that whenever we notice that one (or more) threads are in   *
9
 *   basic idea is that whenever we notice that one (or more) threads are in   *
Line 74... Line 73...
74
 *                                                                             *
73
 *                                                                             *
75
 *   There are a number of settable options via the command-line or .craftyrc  *
74
 *   There are a number of settable options via the command-line or .craftyrc  *
76
 *   initialization file.  Here's a concise explanation for each option and an *
75
 *   initialization file.  Here's a concise explanation for each option and an *
77
 *   occasional suggestion for testing/tuning.                                 *
76
 *   occasional suggestion for testing/tuning.                                 *
78
 *                                                                             *
77
 *                                                                             *
79
 *   smp_affinity (command = smpaffinity=<n> is used to enable or disable      *
78
 *   smp_affinity (command = smpaffinity=<n> <p> is used to enable or disable  *
80
 *      processor affinity.  -1 disables affinity and lets threads run on any  *
79
 *      processor affinity.  -1 disables affinity and lets threads run on any  *
81
 *      available core.  If you use an integer <n> then thread zero will bind  *
80
 *      available core.  If you use an integer <n> then thread zero will bind  *
82
 *      itself to cpu <n> and each additional thread will bind to the next     *
81
 *      itself to cpu <n> and each additional thread will bind to the next     *
83
 *      higher cpu number.  This is useful if you try to run two copies of     *
82
 *      higher cpu number.  This is useful if you try to run two copies of     *
84
 *      crafty on the same machine, now you can cause one to bind to the first *
83
 *      crafty on the same machine, now you can cause one to bind to the first *
Line 197... Line 196...
197
 *                                                          *
196
 *                                                          *
198
 ************************************************************
197
 ************************************************************
199
 */
198
 */
200
  tstart = ReadClock();
199
  tstart = ReadClock();
201
  tree->nprocs = 0;
200
  tree->nprocs = 0;
202
  for (tid = 0; tid < (int) smp_max_threads; tid++) // Pierre-Marie Baty -- added type cast
201
  for (tid = 0; tid < smp_max_threads; tid++)
203
    tree->siblings[tid] = 0;
202
    tree->siblings[tid] = 0;
204
  child = GetBlock(tree, tree->thread_id);
203
  child = GetBlock(tree, tree->thread_id);
205
  if (!child)
204
  if (!child)
206
    return 0;
205
    return 0;
207
  CopyFromParent(child);
206
  CopyFromParent(child);
Line 240... Line 239...
240
  if (!tree->joined)
239
  if (!tree->joined)
241
    parallel_splits_wasted++;
240
    parallel_splits_wasted++;
242
  return 1;
241
  return 1;
243
}
242
}
244
 
243
 
245
/* modified 12/16/15 */
244
/* modified 08/03/16 */
246
/*
245
/*
247
 *******************************************************************************
246
 *******************************************************************************
248
 *                                                                             *
247
 *                                                                             *
249
 *   Join() is called just when we enter the usual spin-loop waiting for work. *
248
 *   Join() is called just when we enter the usual spin-loop waiting for work. *
250
 *   We take a quick look at all active split blocks to see if any look        *
249
 *   We take a quick look at all active split blocks to see if any look        *
Line 282... Line 281...
282
 *  joinable once we acquire the lock, we abort joining     *
281
 *  joinable once we acquire the lock, we abort joining     *
283
 *  since it is futile.  Note that if this happens, we will *
282
 *  since it is futile.  Note that if this happens, we will *
284
 *  try to find an existing split point we can join three   *
283
 *  try to find an existing split point we can join three   *
285
 *  times before we exit, setting split to 1 to ask other   *
284
 *  times before we exit, setting split to 1 to ask other   *
286
 *  threads to produce more candidate split points.         *
285
 *  threads to produce more candidate split points.         *
-
 
286
 *                                                          *
-
 
287
 *  Special case:  We don't want to join a split point that *
-
 
288
 *  was created by this thread.  While it works, it can add *
-
 
289
 *  overhead since we can encounter a later split point     *
-
 
290
 *  that originated at the current split point, and we      *
-
 
291
 *  would continue searching even though most of the work   *
-
 
292
 *  has already been completed.  The hash table would help  *
-
 
293
 *  avoid most (if not all) of this overhead, but there is  *
-
 
294
 *  no good reason to take the chance of this happening.    *
287
 *                                                          *
295
 *                                                          *
288
 ************************************************************
296
 ************************************************************
289
 */
297
 */
290
  for (pass = 0; pass < 3; pass++) {
298
  for (pass = 0; pass < 3; pass++) {
291
    best_interest = -999999;
299
    best_interest = -999999;
292
    join_block = 0;
300
    join_block = 0;
293
    for (current = 0; current <= (int) smp_max_threads * 64; current++) { // Pierre-Marie Baty -- added type cast
301
    for (current = 0; current <= smp_max_threads * 64; current++) {
294
      tree = block[current];
302
      tree = block[current];
295
      if (tree->joinable && (tree->ply <= tree->depth / 2 ||
303
      if (tree->joinable && (tree->ply <= tree->depth / 2 ||
296
              tree->nprocs < (int) smp_split_group)) { // Pierre-Marie Baty -- added type cast
304
              tree->nprocs < smp_split_group) && tree->thread_id != tid) {
297
        interest = tree->depth * 2 - tree->searched[0];
305
        interest = tree->depth * 2 - tree->searched[0];
298
        if (interest > best_interest) {
306
        if (interest > best_interest) {
299
          best_interest = interest;
307
          best_interest = interest;
300
          join_block = tree;
308
          join_block = tree;
301
        }
309
        }
Line 336... Line 344...
336
 ************************************************************
344
 ************************************************************
337
 */
345
 */
338
    if (join_block) {
346
    if (join_block) {
339
      Lock(join_block->lock);
347
      Lock(join_block->lock);
340
      if (join_block->joinable) {
348
      if (join_block->joinable) {
341
        child = GetBlock(join_block, (int) tid); // Pierre-Marie Baty -- added type cast
349
        child = GetBlock(join_block, tid);
342
        Unlock(join_block->lock);
350
        Unlock(join_block->lock);
343
        if (child) {
351
        if (child) {
344
          CopyFromParent(child);
352
          CopyFromParent(child);
345
          thread[tid].tree = child;
353
          thread[tid].tree = child;
346
          parallel_joins++;
354
          parallel_joins++;
Line 363... Line 371...
363
 */
371
 */
364
  smp_split = 1;
372
  smp_split = 1;
365
  return 0;
373
  return 0;
366
}
374
}
367
 
375
 
368
/* modified 11/04/15 */
376
/* modified 08/03/16 */
-
 
377
/*
-
 
378
 *******************************************************************************
-
 
379
 *                                                                             *
-
 
380
 *   ThreadAffinity() is called to "pin" a thread to a specific processor.  It *
-
 
381
 *   is a "noop" (no-operation) if Crafty was not compiled with -DAFFINITY, or *
-
 
382
 *   if smp_affinity is negative (smpaffinity=-1 disables affinity).  It       *
-
 
383
 *   simply sets the affinity for the current thread to the requested CPU and  *
-
 
384
 *   returns.  NOTE:  If hyperthreading is enabled, there is no guarantee that *
-
 
385
 *   this will work as expected and pin one thread per physical core.  It      *
-
 
386
 *   depends on how the O/S numbers the SMT cores.                             *
-
 
387
 *                                                                             *
-
 
388
 *******************************************************************************
-
 
389
 */
-
 
390
void ThreadAffinity(int cpu) {
-
 
391
#if defined(AFFINITY)
-
 
392
  cpu_set_t cpuset;
-
 
393
  pthread_t current_thread = pthread_self();
-
 
394
 
-
 
395
  if (smp_affinity >= 0) {
-
 
396
    CPU_ZERO(&cpuset);
-
 
397
    CPU_SET(smp_affinity_increment * (cpu + smp_affinity), &cpuset);
-
 
398
    pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset);
-
 
399
  }
-
 
400
#endif
-
 
401
}
-
 
402
 
-
 
403
/* modified 08/03/16 */
369
/*
404
/*
370
 *******************************************************************************
405
 *******************************************************************************
371
 *                                                                             *
406
 *                                                                             *
372
 *   ThreadInit() is called after a process is created.  Its main task is to   *
407
 *   ThreadInit() is called after a process is created.  Its main task is to   *
373
 *   initialize the process local memory so that it will fault in and be       *
408
 *   initialize the process local memory so that it will fault in and be       *
Line 380... Line 415...
380
 */
415
 */
381
void *STDCALL ThreadInit(void *t) {
416
void *STDCALL ThreadInit(void *t) {
382
  int tid = (int64_t) t;
417
  int tid = (int64_t) t;
383
 
418
 
384
  ThreadAffinity(tid);
419
  ThreadAffinity(tid);
385
#  if !defined(UNIX)
420
#if !defined(UNIX)
386
  ThreadMalloc((uint64_t) tid);
421
  ThreadMalloc((uint64_t) tid);
387
#  endif
422
#endif
388
  thread[tid].blocks = 0xffffffffffffffffull;
423
  thread[tid].blocks = 0xffffffffffffffffull;
389
  Lock(lock_smp);
424
  Lock(lock_smp);
390
  initialized_threads++;
425
  initialized_threads++;
391
  Unlock(lock_smp);
426
  Unlock(lock_smp);
392
  WaitForAllThreadsInitialized();
427
  WaitForAllThreadsInitialized();
Line 395... Line 430...
395
  smp_threads--;
430
  smp_threads--;
396
  Unlock(lock_smp);
431
  Unlock(lock_smp);
397
  return 0;
432
  return 0;
398
}
433
}
399
 
434
 
400
/* modified 01/08/15 */
435
/* modified 08/03/16 */
401
/*
-
 
402
 *******************************************************************************
-
 
403
 *                                                                             *
-
 
404
 *   ThreadAffinity() is called to "pin" a thread to a specific processor.  It *
-
 
405
 *   is a "noop" (no-operation) if Crafty was not compiled with -DAFFINITY, or *
-
 
406
 *   if smp_affinity is negative (smpaffinity=-1 disables affinity).  It       *
-
 
407
 *   simply sets the affinity for the current thread to the requested CPU and  *
-
 
408
 *   returns.  NOTE:  If hyperthreading is enabled, there is no guarantee that *
-
 
409
 *   this will work as expected and pin one thread per physical core.  It      *
-
 
410
 *   depends on how the O/S numbers the SMT cores.                             *
-
 
411
 *                                                                             *
-
 
412
 *******************************************************************************
-
 
413
 */
-
 
414
void ThreadAffinity(int cpu) {
-
 
415
#  if defined(AFFINITY)
-
 
416
  cpu_set_t cpuset;
-
 
417
  pthread_t current_thread = pthread_self();
-
 
418
 
-
 
419
  if (smp_affinity >= 0) {
-
 
420
    CPU_ZERO(&cpuset);
-
 
421
    CPU_SET(cpu + smp_affinity, &cpuset);
-
 
422
    pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset);
-
 
423
  }
-
 
424
#  endif
-
 
425
}
-
 
426
 
-
 
427
/* modified 11/04/15 */
-
 
428
/*
436
/*
429
 *******************************************************************************
437
 *******************************************************************************
430
 *                                                                             *
438
 *                                                                             *
431
 *   ThreadSplit() is used to determine if we should split at the current ply. *
439
 *   ThreadSplit() is used to determine if we should split at the current ply. *
432
 *   There are some basic constraints on when splits can be done, such as the  *
440
 *   There are some basic constraints on when splits can be done, such as the  *
Line 441... Line 449...
441
 *   thread becomes idle, it will find these split points immediately and not  *
449
 *   thread becomes idle, it will find these split points immediately and not  *
442
 *   have to wait for a split after the fact.                                  *
450
 *   have to wait for a split after the fact.                                  *
443
 *                                                                             *
451
 *                                                                             *
444
 *******************************************************************************
452
 *******************************************************************************
445
 */
453
 */
446
int ThreadSplit(TREE *RESTRICT tree, int ply, int depth, int alpha, int o_alpha, // Pierre-Marie Baty -- missing keyword
454
int ThreadSplit(TREE * tree, int ply, int depth, int alpha, int o_alpha,
447
    int done) {
455
    int done) {
448
  TREE *used;
456
  TREE *used;
449
  int64_t tblocks;
457
  int64_t tblocks;
450
  int temp, unused = 0;
458
  int temp, unused = 0;
451
 
459
 
Line 456... Line 464...
456
 *  split point, that being that we must not be too far     *
464
 *  split point, that being that we must not be too far     *
457
 *  from the root (smp_min_split_depth).                    *
465
 *  from the root (smp_min_split_depth).                    *
458
 *                                                          *
466
 *                                                          *
459
 ************************************************************
467
 ************************************************************
460
 */
468
 */
461
  if (depth < (int) smp_min_split_depth) // Pierre-Marie Baty -- added type cast
469
  if (depth < smp_min_split_depth)
462
    return 0;
470
    return 0;
463
/*
471
/*
464
 ************************************************************
472
 ************************************************************
465
 *                                                          *
473
 *                                                          *
466
 *  If smp_split is NOT set, we are checking to see if it   *
474
 *  If smp_split is NOT set, we are checking to see if it   *
Line 482... Line 490...
482
 *      just add to the overhead with no benefit.           *
490
 *      just add to the overhead with no benefit.           *
483
 *                                                          *
491
 *                                                          *
484
 ************************************************************
492
 ************************************************************
485
 */
493
 */
486
  if (!smp_split) {
494
  if (!smp_split) {
487
    if (depth < (int) smp_gratuitous_depth || done > 1) // Pierre-Marie Baty -- added type cast
495
    if (depth < smp_gratuitous_depth || done > 1)
488
      return 0;
496
      return 0;
489
    tblocks = ~thread[tree->thread_id].blocks;
497
    tblocks = ~thread[tree->thread_id].blocks;
490
    while (tblocks) {
498
    while (tblocks) {
491
      temp = LSB(tblocks);
499
      temp = LSB(tblocks);
492
      used = block[temp + tree->thread_id * 64 + 1];
500
      used = block[temp + tree->thread_id * 64 + 1];
493
      if (used->joinable && !used->joined)
501
      if (used->joinable && !used->joined)
494
        unused++;
502
        unused++;
495
      Clear(temp, tblocks);
503
      Clear(temp, tblocks);
496
    }
504
    }
497
    if (unused > (int) smp_gratuitous_limit) // Pierre-Marie Baty -- added type cast
505
    if (unused > smp_gratuitous_limit)
498
      return 0;
506
      return 0;
499
  }
507
  }
500
/*
508
/*
501
 ************************************************************
509
 ************************************************************
502
 *                                                          *
510
 *                                                          *
Line 525... Line 533...
525
      used = block[temp + tree->thread_id * 64 + 1];
533
      used = block[temp + tree->thread_id * 64 + 1];
526
      if (used->joinable && !used->joined)
534
      if (used->joinable && !used->joined)
527
        unused++;
535
        unused++;
528
      Clear(temp, tblocks);
536
      Clear(temp, tblocks);
529
    }
537
    }
530
    if (unused > (int) smp_gratuitous_limit) // Pierre-Marie Baty -- added type cast
538
    if (unused > smp_gratuitous_limit)
531
      return 0;
539
      return 0;
532
  }
540
  }
533
  return 1;
541
  return 1;
534
}
542
}
535
 
543
 
536
/* modified 11/04/15 */
544
/* modified 08/03/16 */
537
/*
545
/*
538
 *******************************************************************************
546
 *******************************************************************************
539
 *                                                                             *
547
 *                                                                             *
540
 *   ThreadStop() is called from SearchMoveList() when it detects a beta       *
548
 *   ThreadStop() is called from SearchMoveList() when it detects a beta       *
541
 *   cutoff (fail high) at a node that is being searched in parallel.  We need *
549
 *   cutoff (fail high) at a node that is being searched in parallel.  We need *
Line 551... Line 559...
551
  int proc;
559
  int proc;
552
 
560
 
553
  Lock(tree->lock);
561
  Lock(tree->lock);
554
  tree->stop = 1;
562
  tree->stop = 1;
555
  tree->joinable = 0;
563
  tree->joinable = 0;
556
  for (proc = 0; proc < (int) smp_max_threads; proc++) // Pierre-Marie Baty -- added type cast
564
  for (proc = 0; proc < smp_max_threads; proc++)
557
    if (tree->siblings[proc])
565
    if (tree->siblings[proc])
558
      ThreadStop(tree->siblings[proc]);
566
      ThreadStop(tree->siblings[proc]);
559
  Unlock(tree->lock);
567
  Unlock(tree->lock);
560
}
568
}
561
 
569
 
562
/* modified 11/04/15 */
570
/* modified 08/03/16 */
563
/*
571
/*
564
 *******************************************************************************
572
 *******************************************************************************
565
 *                                                                             *
573
 *                                                                             *
566
 *   ThreadTrace() is a debugging tool that simply walks the split block tree  *
574
 *   ThreadTrace() is a debugging tool that simply walks the split block tree  *
567
 *   and displays interesting data to help debug the parallel search whenever  *
575
 *   and displays interesting data to help debug the parallel search whenever  *
Line 595... Line 603...
595
    if (!brief) {
603
    if (!brief) {
596
      for (i = 0; i < 4 * depth; i++)
604
      for (i = 0; i < 4 * depth; i++)
597
        Print(4095, " ");
605
        Print(4095, " ");
598
      Print(4095, "          parent=%d  sibling threads=",
606
      Print(4095, "          parent=%d  sibling threads=",
599
          FindBlockID(tree->parent));
607
          FindBlockID(tree->parent));
600
      for (proc = 0; proc < (int) smp_max_threads; proc++) // Pierre-Marie Baty -- added type cast
608
      for (proc = 0; proc < smp_max_threads; proc++)
601
        if (tree->siblings[proc])
609
        if (tree->siblings[proc])
602
          Print(4095, " %d(%d)", proc, FindBlockID(tree->siblings[proc]));
610
          Print(4095, " %d(%d)", proc, FindBlockID(tree->siblings[proc]));
603
      Print(4095, "\n");
611
      Print(4095, "\n");
604
    } else {
612
    } else {
605
      if (tree->nprocs > 1) {
613
      if (tree->nprocs > 1) {
606
        Print(4095, " helping= ");
614
        Print(4095, " helping= ");
607
        for (proc = 0; proc < (int) smp_max_threads; proc++) // Pierre-Marie Baty -- added type cast
615
        for (proc = 0; proc < smp_max_threads; proc++)
608
          if (tree->siblings[proc]) {
616
          if (tree->siblings[proc]) {
609
            if (proc == tree->thread_id)
617
            if (proc == tree->thread_id)
610
              Print(4095, "[");
618
              Print(4095, "[");
611
            Print(4095, "%d", proc);
619
            Print(4095, "%d", proc);
612
            if (proc == tree->thread_id)
620
            if (proc == tree->thread_id)
Line 616... Line 624...
616
        Print(4095, "\n");
624
        Print(4095, "\n");
617
      }
625
      }
618
    }
626
    }
619
  }
627
  }
620
  Unlock(lock_io);
628
  Unlock(lock_io);
621
  for (proc = 0; proc < (int) smp_max_threads; proc++) // Pierre-Marie Baty -- added type cast
629
  for (proc = 0; proc < smp_max_threads; proc++)
622
    if (tree->siblings[proc])
630
    if (tree->siblings[proc])
623
      ThreadTrace(tree->siblings[proc], depth, brief);
631
      ThreadTrace(tree->siblings[proc], depth, brief);
624
  Unlock(tree->lock);
632
  Unlock(tree->lock);
625
}
633
}
626
 
634
 
627
/* modified 11/04/15 */
635
/* modified 08/03/16 */
628
/*
636
/*
629
 *******************************************************************************
637
 *******************************************************************************
630
 *                                                                             *
638
 *                                                                             *
631
 *   ThreadWait() is the idle loop for the N threads that are created at the   *
639
 *   ThreadWait() is the idle loop for the N threads that are created at the   *
632
 *   beginning when Crafty searches.  Threads are "parked" here waiting on a   *
640
 *   beginning when Crafty searches.  Threads are "parked" here waiting on a   *
Line 667... Line 675...
667
 *  falls through the while spin loop below because its     *
675
 *  falls through the while spin loop below because its     *
668
 *  "tree" pointer is already non-zero.                     *
676
 *  "tree" pointer is already non-zero.                     *
669
 *                                                          *
677
 *                                                          *
670
 ************************************************************
678
 ************************************************************
671
 */
679
 */
672
  while (1) {
680
  while (FOREVER) {
673
    tstart = ReadClock();
681
    tstart = ReadClock();
674
    while (!thread[tid].tree && (!waiting || waiting->nprocs) && !Join(tid) &&
682
    while (!thread[tid].tree && (!waiting || waiting->nprocs) && !Join(tid) &&
675
        !thread[tid].terminate)
683
        !thread[tid].terminate);
676
      Pause();
-
 
677
    tend = ReadClock();
684
    tend = ReadClock();
678
    if (!thread[tid].tree)
685
    if (!thread[tid].tree)
679
      thread[tid].tree = waiting;
686
      thread[tid].tree = waiting;
680
    thread[tid].idle += tend - tstart;
687
    thread[tid].idle += tend - tstart;
681
    if (thread[tid].tree == waiting || thread[tid].terminate)
688
    if (thread[tid].tree == waiting || thread[tid].terminate)
Line 717... Line 724...
717
    tend = ReadClock();
724
    tend = ReadClock();
718
    thread[tid].idle += tend - tstart;
725
    thread[tid].idle += tend - tstart;
719
  }
726
  }
720
}
727
}
721
 
728
 
722
/* modified 11/04/15 */
729
/* modified 08/03/16 */
723
/*
730
/*
724
 *******************************************************************************
731
 *******************************************************************************
725
 *                                                                             *
732
 *                                                                             *
726
 *   CopyFromParent() is used to copy data from a parent thread to a child     *
733
 *   CopyFromParent() is used to copy data from a parent thread to a child     *
727
 *   thread.  This only copies the appropriate parts of the TREE structure to  *
734
 *   thread.  This only copies the appropriate parts of the TREE structure to  *
Line 747... Line 754...
747
  child->position = parent->position;
754
  child->position = parent->position;
748
  for (i = 0; i <= rep_index + parent->ply; i++)
755
  for (i = 0; i <= rep_index + parent->ply; i++)
749
    child->rep_list[i] = parent->rep_list[i];
756
    child->rep_list[i] = parent->rep_list[i];
750
  for (i = ply - 1; i < MAXPLY; i++)
757
  for (i = ply - 1; i < MAXPLY; i++)
751
    child->killers[i] = parent->killers[i];
758
    child->killers[i] = parent->killers[i];
-
 
759
  for (i = 0; i < 4096; i++) {
-
 
760
    child->counter_move[i] = parent->counter_move[i];
-
 
761
    child->move_pair[i] = parent->move_pair[i];
-
 
762
  }
752
  for (i = ply - 1; i <= ply; i++) {
763
  for (i = ply - 1; i <= ply; i++) {
753
    child->curmv[i] = parent->curmv[i];
764
    child->curmv[i] = parent->curmv[i];
754
    child->pv[i] = parent->pv[i];
765
    child->pv[i] = parent->pv[i];
755
  }
766
  }
756
  child->in_check = parent->in_check;
767
  child->in_check = parent->in_check;
Line 781... Line 792...
781
  child->searched = parent->searched;
792
  child->searched = parent->searched;
782
  strcpy(child->root_move_text, parent->root_move_text);
793
  strcpy(child->root_move_text, parent->root_move_text);
783
  strcpy(child->remaining_moves_text, parent->remaining_moves_text);
794
  strcpy(child->remaining_moves_text, parent->remaining_moves_text);
784
}
795
}
785
 
796
 
786
/* modified 11/04/15 */
797
/* modified 08/03/16 */
787
/*
798
/*
788
 *******************************************************************************
799
 *******************************************************************************
789
 *                                                                             *
800
 *                                                                             *
790
 *   CopyToParent() is used to copy data from a child thread to a parent       *
801
 *   CopyToParent() is used to copy data from a child thread to a parent       *
791
 *   thread.  This only copies the appropriate parts of the TREE structure to  *
802
 *   thread.  This only copies the appropriate parts of the TREE structure to  *
Line 826... Line 837...
826
  if (child->nodes_searched && !child->stop && value > parent->value &&
837
  if (child->nodes_searched && !child->stop && value > parent->value &&
827
      !abort_search) {
838
      !abort_search) {
828
    parent->pv[ply] = child->pv[ply];
839
    parent->pv[ply] = child->pv[ply];
829
    parent->value = value;
840
    parent->value = value;
830
    parent->cutmove = child->curmv[ply];
841
    parent->cutmove = child->curmv[ply];
-
 
842
    for (i = 0; i < 4096; i++) {
-
 
843
      parent->counter_move[i] = child->counter_move[i];
-
 
844
      parent->move_pair[i] = child->move_pair[i];
-
 
845
    }
831
  }
846
  }
832
  if (child->stop && ply == 1)
847
  if (child->stop && ply == 1)
833
    for (which = 0; which < n_root_moves; which++)
848
    for (which = 0; which < n_root_moves; which++)
834
      if (root_moves[which].move == child->curmv[ply]) {
849
      if (root_moves[which].move == child->curmv[ply]) {
835
        root_moves[which].status &= 7;
850
        root_moves[which].status &= 7;
Line 851... Line 866...
851
  }
866
  }
852
  which = FindBlockID(child) - 64 * child->thread_id - 1;
867
  which = FindBlockID(child) - 64 * child->thread_id - 1;
853
  Set(which, thread[child->thread_id].blocks);
868
  Set(which, thread[child->thread_id].blocks);
854
}
869
}
855
 
870
 
856
/* modified 11/04/15 */
871
/* modified 08/03/16 */
857
/*
872
/*
858
 *******************************************************************************
873
 *******************************************************************************
859
 *                                                                             *
874
 *                                                                             *
860
 *   GetBlock() is used to allocate a split block and fill in only SMP-        *
875
 *   GetBlock() is used to allocate a split block and fill in only SMP-        *
861
 *   critical information.  The child process will copy the rest of the split  *
876
 *   critical information.  The child process will copy the rest of the split  *
Line 868... Line 883...
868
 *   means no locks are needed until after the "joinable" flag is set, which   *
883
 *   means no locks are needed until after the "joinable" flag is set, which   *
869
 *   exposes this split point to other threads instantly.                      *
884
 *   exposes this split point to other threads instantly.                      *
870
 *                                                                             *
885
 *                                                                             *
871
 *******************************************************************************
886
 *******************************************************************************
872
 */
887
 */
873
TREE *GetBlock(TREE * /*RESTRICT*/ parent, int tid) { // Pierre-Marie Baty -- keyword not present in declaration
888
TREE *GetBlock(TREE * RESTRICT parent, int tid) {
874
  TREE *child;
889
  TREE *child;
875
  static int warnings = 0;
890
  static int warnings = 0;
876
  int i, unused;
891
  int i, unused;
877
/*
892
/*
878
 ************************************************************
893
 ************************************************************
Line 927... Line 942...
927
 *  of processors working here, etc, without any ugly race  *
942
 *  of processors working here, etc, without any ugly race  *
928
 *  conditions that would corrupt this critical data.       *
943
 *  conditions that would corrupt this critical data.       *
929
 *                                                          *
944
 *                                                          *
930
 ************************************************************
945
 ************************************************************
931
 */
946
 */
932
  for (i = 0; i < (int) smp_max_threads; i++) // Pierre-Marie Baty -- added type cast
947
  for (i = 0; i < smp_max_threads; i++)
933
    child->siblings[i] = 0;
948
    child->siblings[i] = 0;
934
  child->nprocs = 0;
949
  child->nprocs = 0;
935
  child->stop = 0;
950
  child->stop = 0;
936
  child->joinable = 0;
951
  child->joinable = 0;
937
  child->joined = 0;
952
  child->joined = 0;
Line 952... Line 967...
952
 *   invalid memory accesses and crash instantly.                              *
967
 *   invalid memory accesses and crash instantly.                              *
953
 *                                                                             *
968
 *                                                                             *
954
 *******************************************************************************
969
 *******************************************************************************
955
 */
970
 */
956
void WaitForAllThreadsInitialized(void) {
971
void WaitForAllThreadsInitialized(void) {
957
  while (initialized_threads < (int) smp_max_threads); /* Do nothing */ // Pierre-Marie Baty -- added type cast
972
  while (initialized_threads < smp_max_threads); /* Do nothing */
958
}
973
}
959
 
974
 
960
#  if !defined (UNIX)
975
#if !defined (UNIX)
961
/* modified 01/17/09 */
976
/* modified 08/03/16 */
962
/*
977
/*
963
 *******************************************************************************
978
 *******************************************************************************
964
 *                                                                             *
979
 *                                                                             *
965
 *   ThreadMalloc() is called from the ThreadInit() function.  It malloc's the *
980
 *   ThreadMalloc() is called from the ThreadInit() function.  It malloc's the *
966
 *   split blocks in the local memory for the processor associated with the    *
981
 *   split blocks in the local memory for the processor associated with the    *
Line 970... Line 985...
970
 */
985
 */
971
extern void *WinMalloc(size_t, int);
986
extern void *WinMalloc(size_t, int);
972
void ThreadMalloc(int64_t tid) {
987
void ThreadMalloc(int64_t tid) {
973
  int i;
988
  int i;
974
 
989
 
975
  for (i = (int) tid * 64 + 1; i < (int) tid * 64 + 65; i++) { // Pierre-Marie Baty -- added type casts
990
  for (i = tid * 64 + 1; i < tid * 64 + 65; i++) {
976
    if (block[i] == NULL)
991
    if (block[i] == NULL)
977
      block[i] =
992
      block[i] =
978
          (TREE *) ((~(size_t) 127) & (127 + (size_t) WinMalloc(sizeof(TREE) +
993
          (TREE *) ((~(size_t) 127) & (127 + (size_t) WinMalloc(sizeof(TREE) +
979
                  127, (int) tid))); // Pierre-Marie Baty -- added type cast
994
                  127, tid)));
980
    block[i]->parent = NULL;
995
    block[i]->parent = NULL;
981
    LockInit(block[i]->lock);
996
    LockInit(block[i]->lock);
982
  }
997
  }
983
}
998
}
984
#  endif
-
 
985
#endif
999
#endif