Subversion Repositories Games.Chess Giants

Rev

Rev 154 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
33 pmbaty 1
#include <stddef.h>
108 pmbaty 2
#include <math.h>
33 pmbaty 3
#include "chess.h"
4
#include "data.h"
5
#if defined(UNIX)
6
#  include <unistd.h>
7
#  include <sys/types.h>
8
#else
108 pmbaty 9
#  include <fcntl.h> /* needed for definition of "_O_BINARY" */
33 pmbaty 10
#endif
11
/*
12
 *******************************************************************************
13
 *                                                                             *
14
 *   Initialize() performs routine initialization before anything else is      *
15
 *   attempted.  It uses a group of service routines to initialize various     *
16
 *   data structures that are needed before the engine can do anything at all. *
17
 *                                                                             *
18
 *******************************************************************************
19
 */
20
void Initialize() {
21
  TREE *tree;
154 pmbaty 22
  int j, v, major, id;
23
#if defined(UNIX)
24
  int i, node;
25
#endif
33 pmbaty 26
 
27
  tree = block[0];
108 pmbaty 28
  for (j = 1; j <= MAX_BLOCKS; j++)
33 pmbaty 29
    block[j] = NULL;
30
  InitializeMasks();
31
  InitializeMagic();
32
  InitializeSMP();
33
  InitializeAttackBoards();
34
  InitializePawnMasks();
35
  InitializeChessBoard(tree);
36
  InitializeKillers();
37
#if !defined(UNIX)
108 pmbaty 38
  _fmode = _O_BINARY; /* set file mode binary to avoid text translation */
33 pmbaty 39
#endif
40
#if defined(EPD)
41
  EGInit();
42
#endif
43
  tree->last[0] = tree->move_list;
44
  tree->last[1] = tree->move_list;
45
  sprintf(log_filename, "%s/book.bin", book_path);
46
  book_file = fopen(log_filename, "rb+");
47
  if (!book_file) {
48
    book_file = fopen(log_filename, "rb");
49
    if (!book_file) {
108 pmbaty 50
      Print(2048, "unable to open book file [%s/book.bin].\n", book_path);
51
      Print(32, "book is disabled\n");
33 pmbaty 52
    } else {
108 pmbaty 53
      Print(2048, "unable to open book file [%s/book.bin] for \"write\".\n",
33 pmbaty 54
          book_path);
108 pmbaty 55
      Print(32, "learning is disabled\n");
33 pmbaty 56
    }
57
  }
58
  sprintf(log_filename, "%s/books.bin", book_path);
59
  normal_bs_file = fopen(log_filename, "rb");
60
  books_file = normal_bs_file;
61
  if (!normal_bs_file)
108 pmbaty 62
    Print(32, "unable to open book file [%s/books.bin].\n", book_path);
33 pmbaty 63
  sprintf(log_filename, "%s/bookc.bin", book_path);
64
  computer_bs_file = fopen(log_filename, "rb");
65
  if (computer_bs_file)
108 pmbaty 66
    Print(32, "found computer opening book file [%s/bookc.bin].\n",
33 pmbaty 67
        book_path);
68
  if (book_file) {
69
    int maj_min;
154 pmbaty 70
    fseek(book_file, - (long) sizeof(int), SEEK_END);
108 pmbaty 71
    v = fread(&maj_min, 4, 1, book_file);
72
    if (v <= 0)
73
      perror("Initialize() fread error: ");
33 pmbaty 74
    major = BookIn32((unsigned char *) &maj_min);
75
    major = major >> 16;
76
    if (major < 23) {
77
      Print(4095, "\nERROR!  book.bin not made by version 23.0 or later\n");
78
      fclose(book_file);
79
      fclose(books_file);
80
      book_file = 0;
81
      books_file = 0;
82
    }
83
  }
84
  id = InitializeGetLogID();
85
  sprintf(log_filename, "%s/log.%03d", log_path, id);
86
  sprintf(history_filename, "%s/game.%03d", log_path, id);
87
  log_file = fopen(log_filename, "w");
88
  history_file = fopen(history_filename, "w+");
89
  if (!history_file) {
90
    printf("ERROR, unable to open game history file, exiting\n");
91
    CraftyExit(1);
92
  }
154 pmbaty 93
  AlignedMalloc((void *) &hash_table, 64,
33 pmbaty 94
      sizeof(HASH_ENTRY) * hash_table_size);
154 pmbaty 95
  AlignedMalloc((void *) &hash_path, 64,
33 pmbaty 96
      sizeof(HPATH_ENTRY) * hash_path_size);
154 pmbaty 97
  AlignedMalloc((void *) &pawn_hash_table, 64,
33 pmbaty 98
      sizeof(PAWN_HASH_ENTRY) * pawn_hash_table_size);
108 pmbaty 99
  if (!hash_table) {
100
    Print(2048,
33 pmbaty 101
        "AlignedMalloc() failed, not enough memory (primary trans/ref table).\n");
102
    hash_table_size = 0;
108 pmbaty 103
    hash_table = 0;
33 pmbaty 104
  }
105
  if (!pawn_hash_table) {
108 pmbaty 106
    Print(2048,
33 pmbaty 107
        "AlignedMalloc() failed, not enough memory (pawn hash table).\n");
108
    pawn_hash_table_size = 0;
109
    pawn_hash_table = 0;
110
  }
111
/*
112
 ************************************************************
113
 *                                                          *
114
 *  Now for some NUMA stuff.  We need to allocate the local *
115
 *  memory for each processor, but we can't touch it here   *
116
 *  or it will be faulted in and be allocated on the        *
117
 *  current CPU, which is not where it should be located    *
118
 *  for optimal NUMA performance.  ThreadInit() will do the *
119
 *  actual initialization after each new process is created *
120
 *  so that the pages of local memory will be faulted in on *
121
 *  the correct processor and use local node memory for     *
122
 *  optimal performance.                                    *
123
 *                                                          *
124
 *  If we are using CPU affinity, we need to set this up    *
125
 *  for thread 0 BEFORE we initialize the split blocks so   *
108 pmbaty 126
 *  that they will page fault in on the correct NUMA node.  *
33 pmbaty 127
 *                                                          *
128
 ************************************************************
129
 */
108 pmbaty 130
#if (CPUS > 1)
131
  ThreadAffinity(smp_affinity);
132
#  if !defined(UNIX)
33 pmbaty 133
  ThreadMalloc((int) 0);
108 pmbaty 134
#  else
33 pmbaty 135
  for (i = 0; i < CPUS; i++) {
108 pmbaty 136
    for (j = 0; j < 64; j++) {
137
      AlignedMalloc((void **) &block[i * 64 + j + 1], 2048,
33 pmbaty 138
          (size_t) sizeof(TREE));
139
    }
140
  }
108 pmbaty 141
  for (i = 1; i < 64; i++) {
154 pmbaty 142
    memset((char *) block[i], 0, sizeof(TREE));
33 pmbaty 143
    LockInit(block[i]->lock);
144
  }
108 pmbaty 145
  for (node = 1; node < CPUS; node++) {
146
    ThreadAffinity(node);
147
    for (i = 0; i < 64; i++) {
154 pmbaty 148
      memset((char *) block[node * 64 + i], 0, sizeof(TREE));
108 pmbaty 149
      LockInit(block[node * 64 + i]->lock);
150
    }
151
  }
154 pmbaty 152
  ThreadAffinity(0);
108 pmbaty 153
#  endif
33 pmbaty 154
#endif
108 pmbaty 155
  thread[0].blocks = 0xffffffffffffffffull;
33 pmbaty 156
  initialized_threads++;
108 pmbaty 157
  InitializeHashTables(1);
33 pmbaty 158
  InitializeKingSafety();
154 pmbaty 159
  InitializeLMP();
160
  InitializeLMR();
33 pmbaty 161
}
162
 
163
/*
164
 *******************************************************************************
165
 *                                                                             *
166
 *   InitializeAttackBoards() is used to initialize the basic bitboards that   *
167
 *   deal with what squares a piece attacks.                                   *
168
 *                                                                             *
169
 *******************************************************************************
170
 */
171
void InitializeAttackBoards(void) {
108 pmbaty 172
  int i, j, d, s, t, frank, ffile, trank, tfile;
33 pmbaty 173
  int sq, lastsq;
174
  static const int knightsq[8] = { -17, -15, -10, -6, 6, 10, 15, 17 };
175
  static const int bishopsq[4] = { -9, -7, 7, 9 };
176
  static const int rooksq[4] = { -8, -1, 1, 8 };
177
  uint64_t sqs;
178
 
179
/*
180
 initialize pawn attack boards
181
 */
182
  for (i = 0; i < 64; i++) {
183
    pawn_attacks[white][i] = 0;
184
    if (i < 56)
185
      for (j = 2; j < 4; j++) {
186
        sq = i + bishopsq[j];
187
        if (Abs(Rank(sq) - Rank(i)) == 1 && Abs(File(sq) - File(i)) == 1 &&
188
            sq < 64 && sq > -1)
189
          pawn_attacks[white][i] =
190
              pawn_attacks[white][i] | (uint64_t) 1 << sq;
191
      }
192
    pawn_attacks[black][i] = 0;
193
    if (i > 7)
194
      for (j = 0; j < 2; j++) {
195
        sq = i + bishopsq[j];
196
        if (Abs(Rank(sq) - Rank(i)) == 1 && Abs(File(sq) - File(i)) == 1 &&
197
            sq < 64 && sq > -1)
198
          pawn_attacks[black][i] =
199
              pawn_attacks[black][i] | (uint64_t) 1 << sq;
200
      }
201
  }
202
/*
203
 initialize knight attack board
204
 */
205
  for (i = 0; i < 64; i++) {
206
    knight_attacks[i] = 0;
207
    frank = Rank(i);
208
    ffile = File(i);
209
    for (j = 0; j < 8; j++) {
210
      sq = i + knightsq[j];
211
      if (sq < 0 || sq > 63)
212
        continue;
213
      trank = Rank(sq);
214
      tfile = File(sq);
215
      if (Abs(frank - trank) > 2 || Abs(ffile - tfile) > 2)
216
        continue;
217
      knight_attacks[i] = knight_attacks[i] | (uint64_t) 1 << sq;
218
    }
219
  }
220
/*
221
 initialize bishop/queen attack boards and masks
222
 */
223
  for (i = 0; i < 64; i++) {
224
    for (j = 0; j < 4; j++) {
225
      sq = i;
226
      lastsq = sq;
227
      sq = sq + bishopsq[j];
228
      while (Abs(Rank(sq) - Rank(lastsq)) == 1 &&
229
          Abs(File(sq) - File(lastsq)) == 1 && sq < 64 && sq > -1) {
230
        if (bishopsq[j] == 7)
231
          plus7dir[i] = plus7dir[i] | (uint64_t) 1 << sq;
232
        else if (bishopsq[j] == 9)
233
          plus9dir[i] = plus9dir[i] | (uint64_t) 1 << sq;
234
        else if (bishopsq[j] == -7)
235
          minus7dir[i] = minus7dir[i] | (uint64_t) 1 << sq;
236
        else
237
          minus9dir[i] = minus9dir[i] | (uint64_t) 1 << sq;
238
        lastsq = sq;
239
        sq = sq + bishopsq[j];
240
      }
241
    }
242
  }
243
  plus1dir[64] = 0;
244
  plus7dir[64] = 0;
245
  plus8dir[64] = 0;
246
  plus9dir[64] = 0;
247
  minus1dir[64] = 0;
248
  minus7dir[64] = 0;
249
  minus8dir[64] = 0;
250
  minus9dir[64] = 0;
251
/*
252
 initialize rook/queen attack boards
253
 */
254
  for (i = 0; i < 64; i++) {
255
    for (j = 0; j < 4; j++) {
256
      sq = i;
257
      lastsq = sq;
258
      sq = sq + rooksq[j];
259
      while (((Abs(Rank(sq) - Rank(lastsq)) == 1 &&
260
                  Abs(File(sq) - File(lastsq)) == 0)
261
              || (Abs(Rank(sq) - Rank(lastsq)) == 0 &&
262
                  Abs(File(sq) - File(lastsq)) == 1)) && sq < 64 && sq > -1) {
263
        if (rooksq[j] == 1)
264
          plus1dir[i] = plus1dir[i] | (uint64_t) 1 << sq;
265
        else if (rooksq[j] == 8)
266
          plus8dir[i] = plus8dir[i] | (uint64_t) 1 << sq;
267
        else if (rooksq[j] == -1)
268
          minus1dir[i] = minus1dir[i] | (uint64_t) 1 << sq;
269
        else
270
          minus8dir[i] = minus8dir[i] | (uint64_t) 1 << sq;
271
        lastsq = sq;
272
        sq = sq + rooksq[j];
273
      }
274
    }
275
  }
276
/*
277
 initialize bishop attack board
278
 */
279
  for (i = 0; i < 64; i++) {
280
    bishop_attacks[i] =
281
        plus9dir[i] | minus9dir[i] | plus7dir[i] | minus7dir[i];
282
  }
283
/*
284
 initialize rook attack board
285
 */
286
  for (i = 0; i < 64; i++) {
287
    rook_attacks[i] = file_mask[File(i)] | rank_mask[Rank(i)];
288
  }
289
/*
290
 initialize king attack board
291
 */
292
  for (i = 0; i < 64; i++) {
293
    king_attacks[i] = 0;
294
    for (j = 0; j < 64; j++) {
295
      if (Distance(i, j) == 1)
296
        king_attacks[i] = king_attacks[i] | SetMask(j);
297
    }
298
  }
299
/*
108 pmbaty 300
 directions[sq1][sq2] gives the "move direction" to move from
33 pmbaty 301
 sq1 to sq2.  intervening[sq1][sq2] gives a bit vector that indicates
302
 which squares must be unoccupied in order for <sq1> to attack <sq2>,
108 pmbaty 303
 assuming a sliding piece is involved.  To use this, you simply have
33 pmbaty 304
 to Or(intervening[sq1][sq2],occupied_squares) and if the result is
305
 "0" then a sliding piece on sq1 would attack sq2 and vice-versa.
306
 */
307
  for (i = 0; i < 64; i++) {
308
    for (j = 0; j < 64; j++)
309
      intervening[i][j] = 0;
310
    sqs = plus1dir[i];
311
    while (sqs) {
312
      j = LSB(sqs);
313
      directions[i][j] = 1;
314
      intervening[i][j] = plus1dir[i] ^ plus1dir[j - 1];
315
      sqs &= sqs - 1;
316
    }
317
    sqs = plus7dir[i];
318
    while (sqs) {
319
      j = LSB(sqs);
320
      directions[i][j] = 7;
321
      intervening[i][j] = plus7dir[i] ^ plus7dir[j - 7];
322
      sqs &= sqs - 1;
323
    }
324
    sqs = plus8dir[i];
325
    while (sqs) {
326
      j = LSB(sqs);
327
      directions[i][j] = 8;
328
      intervening[i][j] = plus8dir[i] ^ plus8dir[j - 8];
329
      sqs &= sqs - 1;
330
    }
331
    sqs = plus9dir[i];
332
    while (sqs) {
333
      j = LSB(sqs);
334
      directions[i][j] = 9;
335
      intervening[i][j] = plus9dir[i] ^ plus9dir[j - 9];
336
      sqs &= sqs - 1;
337
    }
338
    sqs = minus1dir[i];
339
    while (sqs) {
340
      j = LSB(sqs);
341
      directions[i][j] = -1;
342
      intervening[i][j] = minus1dir[i] ^ minus1dir[j + 1];
343
      sqs &= sqs - 1;
344
    }
345
    sqs = minus7dir[i];
346
    while (sqs) {
347
      j = LSB(sqs);
348
      directions[i][j] = -7;
349
      intervening[i][j] = minus7dir[i] ^ minus7dir[j + 7];
350
      sqs &= sqs - 1;
351
    }
352
    sqs = minus8dir[i];
353
    while (sqs) {
354
      j = LSB(sqs);
355
      directions[i][j] = -8;
356
      intervening[i][j] = minus8dir[i] ^ minus8dir[j + 8];
357
      sqs &= sqs - 1;
358
    }
359
    sqs = minus9dir[i];
360
    while (sqs) {
361
      j = LSB(sqs);
362
      directions[i][j] = -9;
363
      intervening[i][j] = minus9dir[i] ^ minus9dir[j + 9];
364
      sqs &= sqs - 1;
365
    }
366
  }
108 pmbaty 367
/*
368
  distance_ring[square][distance] has a ring of 1's around "square" with a
369
  distance of "distance".  IE for e4, we have a ring of adjacent squares
370
  [e4][1], the next ring (2 squares away) for [e4][2], etc.  In this code,
371
  s = square being set up, d = distance from square to "ring" and t = target
372
  square that is on the ring if distance is correct.
373
 */
374
  for (s = 0; s < 64; s++) {
375
    distance_ring[s][0] = SetMask(s);
376
    for (d = 1; d < 8; d++) {
377
      distance_ring[s][d] = 0;
378
      for (t = 0; t < 64; t++)
379
        if (Distance(s, t) == d)
380
          distance_ring[s][d] |= SetMask(t);
381
    }
382
  }
33 pmbaty 383
}
384
 
385
/*
386
 *******************************************************************************
387
 *                                                                             *
388
 *   InitializeMagic() initializes the magic number tables used in the new     *
389
 *   magic move generation algorithm.  We also initialize a set of parallel    *
390
 *   tables that contain mobility scores for each possible set of magic attack *
391
 *   vectors, which saves significant time in the evaluation, since it is done *
392
 *   here before the game actually starts.                                     *
393
 *                                                                             *
394
 *******************************************************************************
395
 */
396
void InitializeMagic(void) {
108 pmbaty 397
  int i, j, m;
33 pmbaty 398
  int initmagicmoves_bitpos64_database[64] = {
399
    63, 0, 58, 1, 59, 47, 53, 2,
400
    60, 39, 48, 27, 54, 33, 42, 3,
401
    61, 51, 37, 40, 49, 18, 28, 20,
402
    55, 30, 34, 11, 43, 14, 22, 4,
403
    62, 57, 46, 52, 38, 26, 32, 41,
404
    50, 36, 17, 19, 29, 10, 13, 21,
405
    56, 45, 25, 31, 35, 16, 9, 12,
406
    44, 24, 15, 8, 23, 7, 6, 5
407
  };
408
/*
409
 Bishop attacks and mobility
410
 */
411
  for (i = 0; i < 64; i++) {
412
    int squares[64];
413
    int numsquares = 0;
414
    uint64_t temp = magic_bishop_mask[i];
415
 
416
    while (temp) {
156 pmbaty 417
      uint64_t abit = temp & (0-temp); // Pierre-Marie Baty -- signedness fix
33 pmbaty 418
 
419
      squares[numsquares++] =
420
          initmagicmoves_bitpos64_database[(abit *
421
              0x07EDD5E59A4E28C2ull) >> 58];
422
      temp ^= abit;
423
    }
424
    for (temp = 0; temp < (uint64_t) 1 << numsquares; temp++) {
425
      uint64_t moves;
426
      uint64_t tempoccupied =
427
          InitializeMagicOccupied(squares, numsquares, temp);
428
      moves = InitializeMagicBishop(i, tempoccupied);
429
      *(magic_bishop_indices[i] +
430
          (tempoccupied * magic_bishop[i] >> magic_bishop_shift[i])) = moves;
431
      moves |= SetMask(i);
108 pmbaty 432
      m = -lower_b;
33 pmbaty 433
      for (j = 0; j < 4; j++)
108 pmbaty 434
        m += PopCnt(moves & mobility_mask_b[j]) * mobility_score_b[j];
435
      if (m < 0)
436
        m *= 2;
33 pmbaty 437
      *(magic_bishop_mobility_indices[i] +
108 pmbaty 438
          (tempoccupied * magic_bishop[i] >> magic_bishop_shift[i])) = m;
33 pmbaty 439
    }
440
  }
441
/*
442
 Rook attacks and mobility
443
 */
444
  for (i = 0; i < 64; i++) {
445
    int squares[64];
446
    int numsquares = 0;
447
    uint64_t temp = magic_rook_mask[i];
448
 
449
    while (temp) {
156 pmbaty 450
      uint64_t abit = temp & (0-temp); // Pierre-Marie Baty -- signedness fix
33 pmbaty 451
 
452
      squares[numsquares++] =
453
          initmagicmoves_bitpos64_database[(abit *
454
              0x07EDD5E59A4E28C2ull) >> 58];
455
      temp ^= abit;
456
    }
457
    for (temp = 0; temp < (uint64_t) 1 << numsquares; temp++) {
458
      uint64_t tempoccupied =
459
          InitializeMagicOccupied(squares, numsquares, temp);
460
      uint64_t moves = InitializeMagicRook(i, tempoccupied);
461
      *(magic_rook_indices[i] +
462
          (tempoccupied * magic_rook[i] >> magic_rook_shift[i])) = moves;
463
      moves |= SetMask(i);
108 pmbaty 464
      m = -1;
33 pmbaty 465
      for (j = 0; j < 4; j++)
108 pmbaty 466
        m += PopCnt(moves & mobility_mask_r[j]) * mobility_score_r[j];
33 pmbaty 467
      *(magic_rook_mobility_indices[i] +
468
          (tempoccupied * magic_rook[i] >> magic_rook_shift[i])) =
108 pmbaty 469
          mob_curve_r[m];
33 pmbaty 470
    }
471
  }
472
}
473
 
474
/*
475
 *******************************************************************************
476
 *                                                                             *
477
 *   InitializeMagicBishop() does the bishop-specific initialization for a     *
478
 *   particular square on the board.                                           *
479
 *                                                                             *
480
 *******************************************************************************
481
 */
482
uint64_t InitializeMagicBishop(int square, uint64_t occupied) {
483
  uint64_t ret = 0;
484
  uint64_t abit;
485
  uint64_t abit2;
486
  uint64_t rowbits = (uint64_t) 0xFF << 8 * (square / 8);
487
 
488
  abit = (uint64_t) 1 << square;
489
  abit2 = abit;
490
  do {
491
    abit <<= 8 - 1;
492
    abit2 >>= 1;
493
    if (abit2 & rowbits)
494
      ret |= abit;
495
    else
496
      break;
497
  } while (abit && !(abit & occupied));
498
  abit = (uint64_t) 1 << square;
499
  abit2 = abit;
500
  do {
501
    abit <<= 8 + 1;
502
    abit2 <<= 1;
503
    if (abit2 & rowbits)
504
      ret |= abit;
505
    else
506
      break;
507
  } while (abit && !(abit & occupied));
508
  abit = (uint64_t) 1 << square;
509
  abit2 = abit;
510
  do {
511
    abit >>= 8 - 1;
512
    abit2 <<= 1;
513
    if (abit2 & rowbits)
514
      ret |= abit;
515
    else
516
      break;
517
  } while (abit && !(abit & occupied));
518
  abit = (uint64_t) 1 << square;
519
  abit2 = abit;
520
  do {
521
    abit >>= 8 + 1;
522
    abit2 >>= 1;
523
    if (abit2 & rowbits)
524
      ret |= abit;
525
    else
526
      break;
527
  } while (abit && !(abit & occupied));
528
  return ret;
529
}
530
 
531
/*
532
 *******************************************************************************
533
 *                                                                             *
534
 *   InitializeMagicOccupied() generates a specific occupied-square bitboard   *
535
 *   needed during initialization.                                             *
536
 *                                                                             *
537
 *******************************************************************************
538
 */
539
uint64_t InitializeMagicOccupied(int *squares, int numSquares,
540
    uint64_t linoccupied) {
541
  int i;
542
  uint64_t ret = 0;
543
 
544
  for (i = 0; i < numSquares; i++)
545
    if (linoccupied & (uint64_t) 1 << i)
546
      ret |= (uint64_t) 1 << squares[i];
547
  return ret;
548
}
549
 
550
/*
551
 *******************************************************************************
552
 *                                                                             *
553
 *   InitializeMagicRook() does the rook-specific initialization for a         *
554
 *   particular square on the board.                                           *
555
 *                                                                             *
556
 *******************************************************************************
557
 */
558
uint64_t InitializeMagicRook(int square, uint64_t occupied) {
559
  uint64_t ret = 0;
560
  uint64_t abit;
561
  uint64_t rowbits = (uint64_t) 0xFF << 8 * (square / 8);
562
 
563
  abit = (uint64_t) 1 << square;
564
  do {
565
    abit <<= 8;
566
    ret |= abit;
567
  } while (abit && !(abit & occupied));
568
  abit = (uint64_t) 1 << square;
569
  do {
570
    abit >>= 8;
571
    ret |= abit;
572
  } while (abit && !(abit & occupied));
573
  abit = (uint64_t) 1 << square;
574
  do {
575
    abit <<= 1;
576
    if (abit & rowbits)
577
      ret |= abit;
578
    else
579
      break;
580
  } while (!(abit & occupied));
581
  abit = (uint64_t) 1 << square;
582
  do {
583
    abit >>= 1;
584
    if (abit & rowbits)
585
      ret |= abit;
586
    else
587
      break;
588
  } while (!(abit & occupied));
589
  return ret;
590
}
591
 
592
/*
593
 *******************************************************************************
594
 *                                                                             *
595
 *   InitializeChessBoard() initializes the chess board to the normal starting *
108 pmbaty 596
 *   position.  It then calls SetChessBitboards() to correctly set the usual   *
33 pmbaty 597
 *   occupied-square bitboards to correspond to the starting position.         *
598
 *                                                                             *
599
 *******************************************************************************
600
 */
601
void InitializeChessBoard(TREE * tree) {
602
  int i;
603
 
604
  if (strlen(initial_position)) {
605
    int nargs;
606
 
108 pmbaty 607
    nargs = ReadParse(initial_position, args, " \t;");
33 pmbaty 608
    SetBoard(tree, nargs, args, 1);
609
  } else {
610
    for (i = 0; i < 64; i++)
611
      PcOnSq(i) = empty;
612
    game_wtm = 1;
613
/*
614
 place pawns
615
 */
616
    for (i = 0; i < 8; i++) {
617
      PcOnSq(i + 8) = pawn;
618
      PcOnSq(i + 48) = -pawn;
619
    }
620
/*
621
 place knights
622
 */
623
    PcOnSq(B1) = knight;
624
    PcOnSq(G1) = knight;
625
    PcOnSq(B8) = -knight;
626
    PcOnSq(G8) = -knight;
627
/*
628
 place bishops
629
 */
630
    PcOnSq(C1) = bishop;
631
    PcOnSq(F1) = bishop;
632
    PcOnSq(C8) = -bishop;
633
    PcOnSq(F8) = -bishop;
634
/*
635
 place rooks
636
 */
637
    PcOnSq(A1) = rook;
638
    PcOnSq(H1) = rook;
639
    PcOnSq(A8) = -rook;
640
    PcOnSq(H8) = -rook;
641
/*
642
 place queens
643
 */
644
    PcOnSq(D1) = queen;
645
    PcOnSq(D8) = -queen;
646
/*
647
 place kings
648
 */
649
    PcOnSq(E1) = king;
650
    PcOnSq(E8) = -king;
651
/*
652
 initialize castling status so all castling is legal.
653
 */
654
    Castle(0, black) = 3;
655
    Castle(0, white) = 3;
656
/*
657
 initialize enpassant status.
658
 */
659
    EnPassant(0) = 0;
660
/*
661
 now, set the bit-boards.
662
 */
663
    SetChessBitBoards(tree);
664
  }
665
/*
666
 initialize 50 move counter and repetition list/index.
667
 */
668
  Reversible(0) = 0;
108 pmbaty 669
  rep_index = 0;
33 pmbaty 670
  tree->rep_list[0] = HashKey;
671
}
672
 
673
/*
674
 *******************************************************************************
675
 *                                                                             *
676
 *   SetChessBitBoards() is used to set the occupied-square bitboards so that  *
677
 *   they agree with the current real chessboard.                              *
678
 *                                                                             *
679
 *******************************************************************************
680
 */
681
void SetChessBitBoards(TREE * tree) {
682
  int side, piece, square;
683
 
684
  HashKey = 0;
685
  PawnHashKey = 0;
686
  Material = 0;
687
  for (side = black; side <= white; side++)
688
    for (piece = empty; piece <= king; piece++)
689
      Pieces(side, piece) = 0;
690
  for (square = 0; square < 64; square++) {
691
    if (!PcOnSq(square))
692
      continue;
693
    piece = PcOnSq(square);
694
    side = (piece > 0) ? 1 : 0;
695
    Pieces(side, Abs(piece)) |= SetMask(square);
696
    Occupied(side) |= SetMask(square);
697
    Hash(side, Abs(piece), square);
698
    if (Abs(piece) == pawn)
699
      HashP(side, square);
700
    Material += PieceValues(side, Abs(piece));
701
  }
702
  if (Pieces(white, king))
703
    KingSQ(white) = LSB(Pieces(white, king));
704
  if (Pieces(black, king))
705
    KingSQ(black) = LSB(Pieces(black, king));
706
  if (EnPassant(0))
707
    HashEP(EnPassant(0));
708
  if (!(Castle(0, white) & 1))
709
    HashCastle(0, white);
710
  if (!(Castle(0, white) & 2))
711
    HashCastle(1, white);
712
  if (!(Castle(0, black) & 1))
713
    HashCastle(0, black);
714
  if (!(Castle(0, black) & 2))
715
    HashCastle(1, black);
716
/*
717
 initialize black/white piece counts.
718
 */
719
  for (side = black; side <= white; side++)
720
    for (piece = pawn; piece <= king; piece++)
721
      TotalPieces(side, piece) = PopCnt(Pieces(side, piece));
722
  for (side = black; side <= white; side++) {
723
    TotalPieces(side, occupied) = 0;
724
    for (piece = knight; piece < king; piece++)
725
      TotalPieces(side, occupied) +=
726
          PopCnt(Pieces(side, piece)) * p_vals[piece];
727
  }
728
  TotalAllPieces = PopCnt(OccupiedSquares);
108 pmbaty 729
  rep_index = 0;
33 pmbaty 730
  tree->rep_list[0] = HashKey;
731
}
732
 
733
/*
734
 *******************************************************************************
735
 *                                                                             *
736
 *   InitializeGetLogID() is used to determine the nnn (in log.nnn) to use for *
737
 *   the current game.  It is typically the ID of the last log + 1, but we do  *
738
 *   not know what that is if we just started the engine.  We simply look thru *
739
 *   existing log files in the current directory and use the next un-used name *
740
 *   in sequence.                                                              *
741
 *                                                                             *
742
 *******************************************************************************
743
 */
744
int InitializeGetLogID(void) {
154 pmbaty 745
  int t, total_files = 0;
33 pmbaty 746
#if defined(UNIX)
747
  struct stat *fileinfo = malloc(sizeof(struct stat));
748
#endif
749
 
154 pmbaty 750
  for (; total_files < 300; log_id++) {
751
    sprintf(log_filename, "%s/log.%03d", log_path, log_id);
752
    sprintf(history_filename, "%s/game.%03d", log_path, log_id);
753
    log_file = fopen(log_filename, "r");
754
    if (!log_file)
755
      break;
756
    fclose(log_file);
757
    total_files++;
108 pmbaty 758
  }
33 pmbaty 759
#if defined(UNIX)
760
/*  a kludge to work around an xboard 4.2.3 problem.  It sends two "quit"
761
   commands, which causes every other log.nnn file to be empty.  this code
762
   looks for a very small log.nnn file as the last one, and if it is small,
763
   then we simply overwrite it to solve this problem temporarily.  this will
764
   be removed when the nexto xboard version comes out to fix this extra quit
108 pmbaty 765
   problem.                                                                  */
766
  {
767
    char tfn[128];
768
    FILE *tlog;
33 pmbaty 769
 
108 pmbaty 770
    sprintf(tfn, "%s/log.%03d", log_path, log_id - 1);
771
    tlog = fopen(tfn, "r+");
772
    if (tlog) {
773
      fstat(fileno(tlog), fileinfo);
774
      if (fileinfo->st_size < 2000)
775
        log_id--;
33 pmbaty 776
    }
108 pmbaty 777
  }
33 pmbaty 778
#endif
779
  t = log_id++;
780
  return t;
781
}
782
 
783
/*
784
 *******************************************************************************
785
 *                                                                             *
786
 *   InitializeHashTables() is used to clear all hash entries completely, so   *
787
 *   that no old information remains to interefere with a new game or test     *
788
 *   position.                                                                 *
789
 *                                                                             *
108 pmbaty 790
 *   Whenever any hash table size is changed, they are initialized by calling  *
791
 *   this procedure to make sure that in the case of NUMA hardware, the trick  *
792
 *   explained below is always executed.                                       *
793
 *                                                                             *
794
 *   This code uses the NUMA fix when using MT threads.  It clears size / MT   *
795
 *   bytes per cpu, after pinning the current thread to the correct cpu, so    *
796
 *   that the data will fault in to the correct NUMA node.  If the size is not *
797
 *   perfectly divisible by MT (max threads) it clears the final piece at the  *
798
 *   end of each loop.                                                         *
799
 *                                                                             *
800
 *   Note that if no size has changed, (fault_in = 0) then we skip the NUMA    *
801
 *   stuff and just clear the tables, period.                                  *
802
 *                                                                             *
33 pmbaty 803
 *******************************************************************************
804
 */
154 pmbaty 805
void InitializeHashTables(int fault_in) {
108 pmbaty 806
  uint64_t mem_per_node;
807
  int node;
33 pmbaty 808
 
809
  transposition_age = 0;
108 pmbaty 810
  if (fault_in && smp_numa) {
811
/*
812
 ************************************************************
813
 *                                                          *
814
 *  First, initialize the primary transposition/refutation  *
815
 *  (hash) table, using the NUMA trick to place part of     *
816
 *  the trans/ref on each node of the NUMA system.          *
817
 *                                                          *
818
 ************************************************************
819
 */
820
    mem_per_node =
821
        hash_table_size * sizeof(HASH_ENTRY) / Max(smp_max_threads, 1);
154 pmbaty 822
    for (node = 0; node < smp_max_threads; node++) {
108 pmbaty 823
      ThreadAffinity(node);
156 pmbaty 824
      memset((char *) hash_table + node * mem_per_node, 0, (size_t) mem_per_node); // Pierre-Marie Baty -- added type cast
33 pmbaty 825
    }
108 pmbaty 826
    ThreadAffinity(0);
827
    if (mem_per_node * Max(smp_max_threads,
828
            1) < hash_table_size * sizeof(HASH_ENTRY))
154 pmbaty 829
      memset((char *) hash_table + smp_max_threads * mem_per_node, 0,
156 pmbaty 830
          (size_t) (hash_table_size * sizeof(HASH_ENTRY) - // Pierre-Marie Baty -- added type cast
831
          mem_per_node * smp_max_threads));
108 pmbaty 832
/*
833
 ************************************************************
834
 *                                                          *
835
 *  Second, initialize the primary hash path table, using   *
836
 *  the NUMA trick to place part of the hash path table on  *
837
 *  each node of the NUMA system.                           *
838
 *                                                          *
839
 ************************************************************
840
 */
841
    mem_per_node =
842
        hash_path_size * sizeof(HPATH_ENTRY) / Max(smp_max_threads, 1);
154 pmbaty 843
    for (node = 0; node < smp_max_threads; node++) {
108 pmbaty 844
      ThreadAffinity(node);
156 pmbaty 845
      memset((char *) hash_path + node * mem_per_node, 0, (size_t) mem_per_node); // Pierre-Marie Baty -- added type cast
108 pmbaty 846
    }
154 pmbaty 847
    ThreadAffinity(0);
108 pmbaty 848
    if (mem_per_node * Max(smp_max_threads,
849
            1) < hash_path_size * sizeof(HPATH_ENTRY))
154 pmbaty 850
      memset((char *) hash_path + smp_max_threads * mem_per_node, 0,
156 pmbaty 851
          (size_t) (hash_path_size * sizeof(HPATH_ENTRY) -
852
          mem_per_node * smp_max_threads)); // Pierre-Marie Baty -- added type cast
108 pmbaty 853
/*
854
 ************************************************************
855
 *                                                          *
154 pmbaty 856
 *  Finally, initialize the primary pawn hash table, using  *
108 pmbaty 857
 *  the NUMA trick to place part of the pawn hash table on  *
858
 *  each node of the NUMA system.                           *
859
 *                                                          *
860
 ************************************************************
861
 */
862
    mem_per_node =
863
        pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY) / Max(smp_max_threads,
864
        1);
154 pmbaty 865
    for (node = 0; node < smp_max_threads; node++) {
108 pmbaty 866
      ThreadAffinity(node);
156 pmbaty 867
      memset((char *) pawn_hash_table + node * mem_per_node, 0, (size_t) mem_per_node); // Pierre-Marie Baty -- added type cast
108 pmbaty 868
    }
154 pmbaty 869
    ThreadAffinity(0);
108 pmbaty 870
    if (mem_per_node * Max(smp_max_threads,
871
            1) < pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY))
154 pmbaty 872
      memset((char *) pawn_hash_table + smp_max_threads * mem_per_node, 0,
156 pmbaty 873
          (size_t) (pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY) -
874
          mem_per_node * smp_max_threads)); // Pierre-Marie Baty -- added type cast
108 pmbaty 875
/*
876
 ************************************************************
877
 *                                                          *
878
 *  Before we return, we need to re-pin this thread to the  *
879
 *  correct processor.                                      *
880
 *                                                          *
881
 ************************************************************
882
 */
883
    ThreadAffinity(smp_affinity);
884
  } else {
885
/*
886
 ************************************************************
887
 *                                                          *
888
 *  Otherwise we only need to use memset() to clear the     *
889
 *  tables since they have already been faulted in to the   *
890
 *  correct NUMA node.                                      *
891
 *                                                          *
892
 ************************************************************
893
 */
154 pmbaty 894
    memset((char *) hash_table, 0, hash_table_size * sizeof(HASH_ENTRY));
895
    memset((char *) hash_path, 0, hash_path_size * sizeof(HPATH_ENTRY));
896
    memset((char *) pawn_hash_table, 0,
108 pmbaty 897
        pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY));
33 pmbaty 898
  }
899
}
900
 
901
/*
902
 *******************************************************************************
903
 *                                                                             *
904
 *   InitializeKillers() is used to zero the killer moves so that old killers  *
108 pmbaty 905
 *   don't screw up ordering while processing test suites.  Ditto for history  *
906
 *   counters.                                                                 *
33 pmbaty 907
 *                                                                             *
908
 *******************************************************************************
909
 */
910
void InitializeKillers(void) {
911
  int i;
912
 
913
  for (i = 0; i < MAXPLY; i++) {
914
    block[0]->killers[i].move1 = 0;
915
    block[0]->killers[i].move2 = 0;
916
  }
108 pmbaty 917
  for (i = 0; i < 1024; i++)
918
    history[i] = 1024;
33 pmbaty 919
}
920
 
921
/*
922
 *******************************************************************************
923
 *                                                                             *
924
 *   InitializeMasks() is used to initialize the various bitboard masks that   *
925
 *   are used throughout Crafty.                                               *
926
 *                                                                             *
927
 *******************************************************************************
928
 */
929
void InitializeMasks(void) {
930
  int i, j;
931
 
932
/*
933
 masks to set/clear a bit on a specific square
934
 */
935
  for (i = 0; i < 64; i++) {
936
    ClearMask(i) = ~((uint64_t) 1 << i);
937
    SetMask(i) = (uint64_t) 1 << i;
938
  }
939
  ClearMask(BAD_SQUARE) = 0;
940
  SetMask(BAD_SQUARE) = 0;
941
/*
942
 masks to select bits on a specific rank or file
943
 */
944
  rank_mask[0] = (uint64_t) 255;
945
  for (i = 1; i < 8; i++)
946
    rank_mask[i] = rank_mask[i - 1] << 8;
947
  file_mask[FILEA] = (uint64_t) 1;
948
  for (i = 1; i < 8; i++)
949
    file_mask[FILEA] = file_mask[FILEA] | file_mask[FILEA] << 8;
950
  for (i = 1; i < 8; i++)
951
    file_mask[i] = file_mask[i - 1] << 1;
952
/*
953
 masks to determine if a pawn has nearby neighbors or not.
954
 */
955
#if !defined(INLINEASM)
956
  msb[0] = 64;
957
  lsb[0] = 16;
958
  for (i = 1; i < 65536; i++) {
959
    lsb[i] = 16;
960
    for (j = 0; j < 16; j++)
961
      if (i & (1 << j)) {
962
        msb[i] = j;
963
        if (lsb[i] == 16)
964
          lsb[i] = j;
965
      }
966
  }
967
#endif
968
  msb_8bit[0] = 8;
969
  lsb_8bit[0] = 8;
970
  pop_cnt_8bit[0] = 0;
971
  for (i = 1; i < 256; i++) {
972
    pop_cnt_8bit[i] = 0;
973
    for (j = 0; j < 8; j++)
974
      if (i & (1 << j))
975
        pop_cnt_8bit[i]++;
976
    lsb_8bit[i] = 8;
977
    for (j = 0; j < 8; j++) {
978
      if (i & (1 << j)) {
979
        msb_8bit[i] = j;
980
        if (lsb_8bit[i] == 8)
981
          lsb_8bit[i] = j;
982
      }
983
    }
984
  }
985
}
986
 
987
/*
988
 *******************************************************************************
989
 *                                                                             *
990
 *   InitializePawnMasks() is used to initialize the various bitboard masks    *
991
 *   that are used in pawn evaluation.                                         *
992
 *                                                                             *
993
 *******************************************************************************
994
 */
995
void InitializePawnMasks(void) {
996
  int i, j;
997
 
998
/*
999
 initialize isolated pawn masks, which are nothing more than 1's on
1000
 the files adjacent to the pawn file.
1001
 */
1002
  for (i = 0; i < 64; i++) {
1003
    if (!File(i))
1004
      mask_pawn_isolated[i] = file_mask[File(i) + 1];
1005
    else if (File(i) == 7)
1006
      mask_pawn_isolated[i] = file_mask[File(i) - 1];
1007
    else
1008
      mask_pawn_isolated[i] = file_mask[File(i) - 1] | file_mask[File(i) + 1];
1009
  }
1010
/*
1011
 initialize passed pawn masks, which are nothing more than 1's on
1012
 the pawn's file and the adjacent files, but only on ranks that are
1013
 in "front" of the pawn.
1014
 */
1015
  for (i = 0; i < 64; i++) {
1016
    if (!File(i)) {
1017
      mask_passed[white][i] = plus8dir[i] | plus8dir[i + 1];
1018
      mask_passed[black][i] = minus8dir[i] | minus8dir[i + 1];
1019
    } else if (File(i) == 7) {
1020
      mask_passed[white][i] = plus8dir[i - 1] | plus8dir[i];
1021
      mask_passed[black][i] = minus8dir[i - 1] | minus8dir[i];
1022
    } else {
1023
      mask_passed[white][i] = plus8dir[i - 1] | plus8dir[i] | plus8dir[i + 1];
1024
      mask_passed[black][i] =
1025
          minus8dir[i - 1] | minus8dir[i] | minus8dir[i + 1];
1026
    }
1027
  }
1028
/*
108 pmbaty 1029
 masks to determine if a pawn has supporting contact with friendly pawns.
33 pmbaty 1030
 */
108 pmbaty 1031
  for (i = 8; i < 56; i++) {
1032
    if (File(i) > 0 && File(i) < 7) {
1033
      mask_pawn_connected[white][i] =
1034
          SetMask(i - 1) | SetMask(i + 1) | SetMask(i - 9) | SetMask(i - 7);
1035
      mask_pawn_connected[black][i] =
1036
          SetMask(i - 1) | SetMask(i + 1) | SetMask(i + 9) | SetMask(i + 7);
1037
    } else if (File(i) == 0) {
1038
      mask_pawn_connected[white][i] = SetMask(i + 1) | SetMask(i - 7);
1039
      mask_pawn_connected[black][i] = SetMask(i + 1) | SetMask(i + 9);
1040
    } else if (File(i) == 7) {
1041
      mask_pawn_connected[white][i] = SetMask(i - 1) | SetMask(i - 9);
1042
      mask_pawn_connected[black][i] = SetMask(i - 1) | SetMask(i + 7);
33 pmbaty 1043
    }
1044
  }
1045
/*
1046
 these masks are used to determine if the other side has any pawns
1047
 that can attack [square].
1048
 */
1049
  for (i = 8; i < 56; i++) {
1050
    if (!File(i)) {
108 pmbaty 1051
      mask_pattacks[white][i] = minus8dir[i + 1];
1052
      mask_pattacks[black][i] = plus8dir[i + 1];
33 pmbaty 1053
    } else if (File(i) == 7) {
108 pmbaty 1054
      mask_pattacks[white][i] = minus8dir[i - 1];
1055
      mask_pattacks[black][i] = plus8dir[i - 1];
33 pmbaty 1056
    } else {
108 pmbaty 1057
      mask_pattacks[white][i] = minus8dir[i - 1] | minus8dir[i + 1];
1058
      mask_pattacks[black][i] = plus8dir[i + 1] | plus8dir[i - 1];
33 pmbaty 1059
    }
1060
  }
1061
/*
1062
 enpassant pawns are on either file adjacent to the current file, and
1063
 on the same rank.
1064
 */
1065
  for (i = 0; i < 64; i++)
1066
    mask_eptest[i] = 0;
1067
  for (i = 25; i < 31; i++)
1068
    mask_eptest[i] = SetMask(i - 1) | SetMask(i + 1);
1069
  for (i = 33; i < 39; i++)
1070
    mask_eptest[i] = SetMask(i - 1) | SetMask(i + 1);
1071
  mask_eptest[A4] = SetMask(B4);
1072
  mask_eptest[H4] = SetMask(G4);
1073
  mask_eptest[A5] = SetMask(B5);
1074
  mask_eptest[H5] = SetMask(G5);
1075
/*
108 pmbaty 1076
 Initialize masks used to evaluate pawn races.  These masks are
33 pmbaty 1077
 used to determine if the opposing king is in a position to stop a
108 pmbaty 1078
 passed pawn from racing down and queening.  The data is organized
33 pmbaty 1079
 as pawn_race[side][onmove][square], where side is black or white,
108 pmbaty 1080
 and onmove indicates which side is to move for proper tempo
33 pmbaty 1081
 evaluation.
1082
 */
1083
  for (i = 0; i < 64; i++) {
1084
    pawn_race[white][white][i] = 0;
1085
    pawn_race[white][black][i] = 0;
1086
    pawn_race[black][white][i] = 0;
1087
    pawn_race[black][black][i] = 0;
1088
  }
1089
  for (j = 8; j < 56; j++) {
1090
    for (i = 0; i < 64; i++) {
1091
/* white pawn, wtm */
1092
      if (j < 16) {
1093
        if (KingPawnSquare(j + 8, i, File(j) + 56, 1))
1094
          pawn_race[white][white][j] |= SetMask(i);
1095
      } else {
1096
        if (KingPawnSquare(j, i, File(j) + 56, 1))
1097
          pawn_race[white][white][j] |= SetMask(i);
1098
      }
1099
/* white pawn, btm */
1100
      if (j < 16) {
1101
        if (KingPawnSquare(j + 8, i, File(j) + 56, 0))
1102
          pawn_race[white][black][j] |= SetMask(i);
1103
      } else {
1104
        if (KingPawnSquare(j, i, File(j) + 56, 0))
1105
          pawn_race[white][black][j] |= SetMask(i);
1106
      }
1107
/* black pawn, wtm */
1108
      if (j > 47) {
1109
        if (KingPawnSquare(j - 8, i, File(j), 0))
1110
          pawn_race[black][white][j] |= SetMask(i);
1111
      } else {
1112
        if (KingPawnSquare(j, i, File(j), 0))
1113
          pawn_race[black][white][j] |= SetMask(i);
1114
      }
1115
/* black pawn, btm */
1116
      if (j > 47) {
1117
        if (KingPawnSquare(j - 8, i, File(j), 1))
1118
          pawn_race[black][black][j] |= SetMask(i);
1119
      } else {
1120
        if (KingPawnSquare(j, i, File(j), 1))
1121
          pawn_race[black][black][j] |= SetMask(i);
1122
      }
1123
    }
1124
  }
108 pmbaty 1125
}
1126
 
33 pmbaty 1127
/*
108 pmbaty 1128
 *******************************************************************************
1129
 *                                                                             *
154 pmbaty 1130
 *   InitializeLMP() is used to initialize the LMP thresholds used to decide   *
1131
 *   when to stop searching additional branches near the tips of the tree.     *
1132
 *                                                                             *
1133
 *******************************************************************************
1134
 */
1135
void InitializeLMP() {
1136
  int i;
1137
 
1138
  for (i = 0; i < LMP_depth; i++)
156 pmbaty 1139
    LMP[i] = (int) (LMP_base + pow(i + .5, LMP_scale)); // Pierre-Marie Baty -- added type cast
154 pmbaty 1140
}
1141
 
1142
/*
1143
 *******************************************************************************
1144
 *                                                                             *
1145
 *   InitializeLMR() is used to initialize the reduction matrix used to set    *
1146
 *   the reduction value for LMR for each move searched.  It is indexed by     *
108 pmbaty 1147
 *   depth remaining and # moves searched.                                     *
1148
 *                                                                             *
1149
 *******************************************************************************
33 pmbaty 1150
 */
154 pmbaty 1151
void InitializeLMR() {
108 pmbaty 1152
  int d, m;
33 pmbaty 1153
 
108 pmbaty 1154
  for (d = 0; d < 32; d++)
1155
    for (m = 0; m < 64; m++)
1156
      LMR[d][m] = 0;
1157
  for (d = 3; d < 32; d++)
1158
    for (m = 1; m < 64; m++) {
156 pmbaty 1159
      LMR[d][m] = (uint8_t) // Pierre-Marie Baty -- added type cast
1160
          (Max(Min(log(d * LMR_db) * log(m * LMR_mb) / LMR_s, LMR_max),
1161
          LMR_min));
108 pmbaty 1162
      LMR[d][m] = Min(LMR[d][m], Max(d - 1 - LMR_rdepth, 0));
33 pmbaty 1163
    }
1164
}
1165
 
1166
/*
1167
 *******************************************************************************
1168
 *                                                                             *
1169
 *   InitlializeSMP() is used to initialize the pthread lock variables.        *
1170
 *                                                                             *
1171
 *******************************************************************************
1172
 */
1173
void InitializeSMP(void) {
1174
  LockInit(lock_smp);
1175
  LockInit(lock_io);
1176
  LockInit(block[0]->lock);
1177
#if defined(UNIX) && (CPUS > 1)
1178
  pthread_attr_init(&attributes);
1179
  pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
1180
#endif
1181
}