Read FD and return a summary. */
| 302 | |
| 303 | /* Read FD and return a summary. */ |
| 304 | static struct wc_lines |
| 305 | wc_lines (int fd) |
| 306 | { |
| 307 | #ifdef USE_AVX512_WC_LINECOUNT |
| 308 | static signed char use_avx512; |
| 309 | if (!use_avx512) |
| 310 | use_avx512 = avx512_supported () ? 1 : -1; |
| 311 | if (0 < use_avx512) |
| 312 | return wc_lines_avx512 (fd); |
| 313 | #endif |
| 314 | #ifdef USE_AVX2_WC_LINECOUNT |
| 315 | static signed char use_avx2; |
| 316 | if (!use_avx2) |
| 317 | use_avx2 = avx2_supported () ? 1 : -1; |
| 318 | if (0 < use_avx2) |
| 319 | return wc_lines_avx2 (fd); |
| 320 | #endif |
| 321 | #ifdef USE_NEON_WC_LINECOUNT |
| 322 | static signed char use_neon; |
| 323 | if (!use_neon) |
| 324 | use_neon = neon_supported () ? 1 : -1; |
| 325 | if (0 < use_neon) |
| 326 | return wc_lines_neon (fd); |
| 327 | #endif |
| 328 | |
| 329 | intmax_t lines = 0, bytes = 0; |
| 330 | bool long_lines = false; |
| 331 | |
| 332 | while (true) |
| 333 | { |
| 334 | char buf[IO_BUFSIZE + 1]; |
| 335 | ssize_t bytes_read = read (fd, buf, IO_BUFSIZE); |
| 336 | if (bytes_read <= 0) |
| 337 | return (struct wc_lines) { bytes_read == 0 ? 0 : errno, lines, bytes }; |
| 338 | |
| 339 | bytes += bytes_read; |
| 340 | char *end = buf + bytes_read; |
| 341 | idx_t buflines = 0; |
| 342 | |
| 343 | if (! long_lines) |
| 344 | { |
| 345 | /* Avoid function call overhead for shorter lines. */ |
| 346 | for (char *p = buf; p < end; p++) |
| 347 | buflines += *p == '\n'; |
| 348 | } |
| 349 | else |
| 350 | { |
| 351 | /* rawmemchr is more efficient with longer lines. */ |
| 352 | *end = '\n'; |
| 353 | for (char *p = buf; (p = rawmemchr (p, '\n')) < end; p++) |
| 354 | buflines++; |
| 355 | } |
| 356 | |
| 357 | /* If the average line length in the block is >= 15, then use |
| 358 | memchr for the next block, where system specific optimizations |
| 359 | may outweigh function call overhead. |
| 360 | FIXME: This line length was determined in 2015, on both |
| 361 | x86_64 and ppc64, but it's worth re-evaluating in future with |
no test coverage detected