… | |
… | |
120 | |
120 | |
121 | #define EIO_TICKS ((1000000 + 1023) >> 10) |
121 | #define EIO_TICKS ((1000000 + 1023) >> 10) |
122 | |
122 | |
123 | /*****************************************************************************/ |
123 | /*****************************************************************************/ |
124 | |
124 | |
|
|
125 | #if __GNUC__ >= 3 |
|
|
126 | # define expect(expr,value) __builtin_expect ((expr),(value)) |
|
|
127 | #else |
|
|
128 | # define expect(expr,value) (expr) |
|
|
129 | #endif |
|
|
130 | |
|
|
131 | #define expect_false(expr) expect ((expr) != 0, 0) |
|
|
132 | #define expect_true(expr) expect ((expr) != 0, 1) |
|
|
133 | |
|
|
134 | /*****************************************************************************/ |
|
|
135 | |
125 | #define ETP_PRI_MIN EIO_PRI_MIN |
136 | #define ETP_PRI_MIN EIO_PRI_MIN |
126 | #define ETP_PRI_MAX EIO_PRI_MAX |
137 | #define ETP_PRI_MAX EIO_PRI_MAX |
127 | |
138 | |
128 | struct etp_worker; |
139 | struct etp_worker; |
129 | |
140 | |
… | |
… | |
411 | X_UNLOCK (wrklock); |
422 | X_UNLOCK (wrklock); |
412 | } |
423 | } |
413 | |
424 | |
414 | static void etp_maybe_start_thread (void) |
425 | static void etp_maybe_start_thread (void) |
415 | { |
426 | { |
416 | if (etp_nthreads () >= wanted) |
427 | if (expect_true (etp_nthreads () >= wanted)) |
417 | return; |
428 | return; |
418 | |
429 | |
419 | /* todo: maybe use idle here, but might be less exact */ |
430 | /* todo: maybe use idle here, but might be less exact */ |
420 | if (0 <= (int)etp_nthreads () + (int)etp_npending () - (int)etp_nreqs ()) |
431 | if (expect_true (0 <= (int)etp_nthreads () + (int)etp_npending () - (int)etp_nreqs ())) |
421 | return; |
432 | return; |
422 | |
433 | |
423 | etp_start_thread (); |
434 | etp_start_thread (); |
424 | } |
435 | } |
425 | |
436 | |
… | |
… | |
478 | |
489 | |
479 | X_LOCK (reqlock); |
490 | X_LOCK (reqlock); |
480 | --nreqs; |
491 | --nreqs; |
481 | X_UNLOCK (reqlock); |
492 | X_UNLOCK (reqlock); |
482 | |
493 | |
483 | if (req->type == EIO_GROUP && req->size) |
494 | if (expect_false (req->type == EIO_GROUP && req->size)) |
484 | { |
495 | { |
485 | req->int1 = 1; /* mark request as delayed */ |
496 | req->int1 = 1; /* mark request as delayed */ |
486 | continue; |
497 | continue; |
487 | } |
498 | } |
488 | else |
499 | else |
489 | { |
500 | { |
490 | int res = ETP_FINISH (req); |
501 | int res = ETP_FINISH (req); |
491 | if (res) |
502 | if (expect_false (res)) |
492 | return res; |
503 | return res; |
493 | } |
504 | } |
494 | |
505 | |
495 | if (maxreqs && !--maxreqs) |
506 | if (expect_false (maxreqs && !--maxreqs)) |
496 | break; |
507 | break; |
497 | |
508 | |
498 | if (maxtime) |
509 | if (maxtime) |
499 | { |
510 | { |
500 | gettimeofday (&tv_now, 0); |
511 | gettimeofday (&tv_now, 0); |
… | |
… | |
519 | |
530 | |
520 | static void etp_submit (ETP_REQ *req) |
531 | static void etp_submit (ETP_REQ *req) |
521 | { |
532 | { |
522 | req->pri -= ETP_PRI_MIN; |
533 | req->pri -= ETP_PRI_MIN; |
523 | |
534 | |
524 | if (req->pri < ETP_PRI_MIN - ETP_PRI_MIN) req->pri = ETP_PRI_MIN - ETP_PRI_MIN; |
535 | if (expect_false (req->pri < ETP_PRI_MIN - ETP_PRI_MIN)) req->pri = ETP_PRI_MIN - ETP_PRI_MIN; |
525 | if (req->pri > ETP_PRI_MAX - ETP_PRI_MIN) req->pri = ETP_PRI_MAX - ETP_PRI_MIN; |
536 | if (expect_false (req->pri > ETP_PRI_MAX - ETP_PRI_MIN)) req->pri = ETP_PRI_MAX - ETP_PRI_MIN; |
526 | |
537 | |
|
|
538 | if (expect_false (req->type == EIO_GROUP)) |
|
|
539 | { |
|
|
540 | /* I hope this is worth it :/ */ |
527 | X_LOCK (reqlock); |
541 | X_LOCK (reqlock); |
528 | ++nreqs; |
542 | ++nreqs; |
|
|
543 | X_UNLOCK (reqlock); |
|
|
544 | |
|
|
545 | X_LOCK (reslock); |
|
|
546 | |
|
|
547 | ++npending; |
|
|
548 | |
|
|
549 | if (!reqq_push (&res_queue, req) && want_poll_cb) |
|
|
550 | want_poll_cb (); |
|
|
551 | |
|
|
552 | X_UNLOCK (reslock); |
|
|
553 | } |
|
|
554 | else |
|
|
555 | { |
|
|
556 | X_LOCK (reqlock); |
|
|
557 | ++nreqs; |
529 | ++nready; |
558 | ++nready; |
530 | reqq_push (&req_queue, req); |
559 | reqq_push (&req_queue, req); |
531 | X_COND_SIGNAL (reqwait); |
560 | X_COND_SIGNAL (reqwait); |
532 | X_UNLOCK (reqlock); |
561 | X_UNLOCK (reqlock); |
533 | |
562 | |
534 | etp_maybe_start_thread (); |
563 | etp_maybe_start_thread (); |
|
|
564 | } |
535 | } |
565 | } |
536 | |
566 | |
537 | static void etp_set_max_poll_time (double nseconds) |
567 | static void etp_set_max_poll_time (double nseconds) |
538 | { |
568 | { |
539 | if (WORDACCESS_UNSAFE) X_LOCK (reslock); |
569 | if (WORDACCESS_UNSAFE) X_LOCK (reslock); |
… | |
… | |
1198 | ? futimes (req->int1, times) |
1228 | ? futimes (req->int1, times) |
1199 | : utimes (req->ptr1, times); |
1229 | : utimes (req->ptr1, times); |
1200 | } |
1230 | } |
1201 | |
1231 | |
1202 | case EIO_GROUP: |
1232 | case EIO_GROUP: |
|
|
1233 | abort (); /* handled in eio_request */ |
|
|
1234 | |
1203 | case EIO_NOP: |
1235 | case EIO_NOP: |
1204 | req->result = 0; |
1236 | req->result = 0; |
1205 | break; |
1237 | break; |
1206 | |
1238 | |
1207 | case EIO_CUSTOM: |
1239 | case EIO_CUSTOM: |