rpoll.c (155420) | rpoll.c (165009) |
---|---|
1/* 2 * Copyright (c)1996-2002 by Hartmut Brandt 3 * All rights reserved. 4 * 5 * Author: Hartmut Brandt 6 * 7 * Redistribution of this software and documentation and use in source and 8 * binary forms, with or without modification, are permitted provided that --- 87 unchanged lines hidden (view full) --- 96 97# ifdef BROKEN_SELECT_PROTO 98# define SELECT_CAST(P) (int *)P 99# else 100# define SELECT_CAST(P) P 101# endif 102 103 | 1/* 2 * Copyright (c)1996-2002 by Hartmut Brandt 3 * All rights reserved. 4 * 5 * Author: Hartmut Brandt 6 * 7 * Redistribution of this software and documentation and use in source and 8 * binary forms, with or without modification, are permitted provided that --- 87 unchanged lines hidden (view full) --- 96 97# ifdef BROKEN_SELECT_PROTO 98# define SELECT_CAST(P) (int *)P 99# else 100# define SELECT_CAST(P) P 101# endif 102 103 |
104typedef signed long long tval_t; | 104typedef int64_t tval_t; |
105 | 105 |
106static inline tval_t GETMSECS(void); | 106static inline tval_t GETUSECS(void); |
107 108static inline tval_t | 107 108static inline tval_t |
109GETMSECS(void) { | 109GETUSECS(void) { |
110 struct timeval tval; 111 112 (void)gettimeofday(&tval, NULL); | 110 struct timeval tval; 111 112 (void)gettimeofday(&tval, NULL); |
113 return (tval_t)tval.tv_sec*1000+tval.tv_usec/1000; | 113 return (tval_t)tval.tv_sec * 1000000 + tval.tv_usec; |
114} 115 116/* 117 * Simple fatal exit. 118 */ 119static void 120_panic(const char *fmt, ...) 121{ --- 43 unchanged lines hidden (view full) --- 165 struct pollfd *pfd; /* pointer to corresponding poll() structure */ 166# endif 167} PollReg_t; 168 169/* 170 * Now for timers 171 */ 172typedef struct { | 114} 115 116/* 117 * Simple fatal exit. 118 */ 119static void 120_panic(const char *fmt, ...) 121{ --- 43 unchanged lines hidden (view full) --- 165 struct pollfd *pfd; /* pointer to corresponding poll() structure */ 166# endif 167} PollReg_t; 168 169/* 170 * Now for timers 171 */ 172typedef struct { |
173 u_int msecs; /* millisecond value of the timer */ | 173 uint64_t usecs; /* microsecond value of the timer */ |
174 int repeat; /* one shot or repeat? */ 175 void *arg; /* client arg */ 176 timer_f func; /* handler, 0 means disfunct */ | 174 int repeat; /* one shot or repeat? */ 175 void *arg; /* client arg */ 176 timer_f func; /* handler, 0 means disfunct */ |
177 tval_t when; /* next time to trigger in msecs! */ | 177 tval_t when; /* next time to trigger in usecs! */ |
178} PollTim_t; 179 180/* how many records should our table grow at once? */ 181# define POLL_REG_GROW 100 182 183# ifdef USE_POLL 184static struct pollfd * pfd; /* fd list for poll() */ 185# endif --- 105 unchanged lines hidden (view full) --- 291 292 regs_used++; 293 rebuild = 1; 294 } 295 296 poll_unblocksig(); 297 298 if(rpoll_trace) | 178} PollTim_t; 179 180/* how many records should our table grow at once? */ 181# define POLL_REG_GROW 100 182 183# ifdef USE_POLL 184static struct pollfd * pfd; /* fd list for poll() */ 185# endif --- 105 unchanged lines hidden (view full) --- 291 292 regs_used++; 293 rebuild = 1; 294 } 295 296 poll_unblocksig(); 297 298 if(rpoll_trace) |
299 fprintf(stderr, "poll_register(%d, %#lx, %#lx, %#x)->%d", 300 fd, (u_long)func, (u_long)arg, mask, p - regs); | 299 fprintf(stderr, "poll_register(%d, %p, %p, %#x)->%tu", 300 fd, (void *)func, (void *)arg, mask, p - regs); |
301 return p - regs; 302} 303 304/* 305 * remove registration 306 */ 307void 308poll_unregister(int handle) --- 59 unchanged lines hidden (view full) --- 368 FD_SET(p->fd, &xset); 369 } 370# endif 371} 372 373int 374poll_start_timer(u_int msecs, int repeat, timer_f func, void *arg) 375{ | 301 return p - regs; 302} 303 304/* 305 * remove registration 306 */ 307void 308poll_unregister(int handle) --- 59 unchanged lines hidden (view full) --- 368 FD_SET(p->fd, &xset); 369 } 370# endif 371} 372 373int 374poll_start_timer(u_int msecs, int repeat, timer_f func, void *arg) 375{ |
376 return (poll_start_utimer((unsigned long long)msecs * 1000, 377 repeat, func, arg)); 378} 379 380int 381poll_start_utimer(unsigned long long usecs, int repeat, timer_f func, void *arg) 382{ |
|
376 PollTim_t *p; 377 378 /* find unused entry */ 379 for(p = tims; p < &tims[tims_alloc]; p++) 380 if(p->func == NULL) 381 break; 382 383 if(p == &tims[tims_alloc]) { 384 if(tims_alloc == tims_used) { 385 size_t newsize = tims_alloc + POLL_REG_GROW; 386 tims = _xrealloc(tims, sizeof(tims[0]) * newsize); 387 for(p = &tims[tims_alloc]; p < &tims[newsize]; p++) 388 p->func = NULL; 389 p = &tims[tims_alloc]; 390 tims_alloc = newsize; 391 } 392 } 393 394 /* create entry */ | 383 PollTim_t *p; 384 385 /* find unused entry */ 386 for(p = tims; p < &tims[tims_alloc]; p++) 387 if(p->func == NULL) 388 break; 389 390 if(p == &tims[tims_alloc]) { 391 if(tims_alloc == tims_used) { 392 size_t newsize = tims_alloc + POLL_REG_GROW; 393 tims = _xrealloc(tims, sizeof(tims[0]) * newsize); 394 for(p = &tims[tims_alloc]; p < &tims[newsize]; p++) 395 p->func = NULL; 396 p = &tims[tims_alloc]; 397 tims_alloc = newsize; 398 } 399 } 400 401 /* create entry */ |
395 p->msecs = msecs; | 402 p->usecs = usecs; |
396 p->repeat = repeat; 397 p->arg = arg; 398 p->func = func; | 403 p->repeat = repeat; 404 p->arg = arg; 405 p->func = func; |
399 p->when = GETMSECS() + msecs; | 406 p->when = GETUSECS() + usecs; |
400 401 tims_used++; 402 403 resort = 1; 404 405 if(rpoll_trace) | 407 408 tims_used++; 409 410 resort = 1; 411 412 if(rpoll_trace) |
406 fprintf(stderr, "poll_start_timer(%u, %d, %#lx, %#lx)->%u", 407 msecs, repeat, (u_long)func, (u_long)arg, p - tims); | 413 fprintf(stderr, "poll_start_utimer(%llu, %d, %p, %p)->%tu", 414 usecs, repeat, (void *)func, (void *)arg, p - tims); |
408 409 return p - tims; 410} 411 412/* 413 * Here we have to look into the sorted table, whether any entry there points 414 * into the registration table for the deleted entry. This is needed, 415 * because a unregistration can occure while we are scanning through the --- 76 unchanged lines hidden (view full) --- 492 * to be called. So we clear pfd in unregister and check here. 493 */ 494void 495poll_dispatch(int wait) 496{ 497 u_int i, idx; 498 int ret; 499 tval_t now; | 415 416 return p - tims; 417} 418 419/* 420 * Here we have to look into the sorted table, whether any entry there points 421 * into the registration table for the deleted entry. This is needed, 422 * because a unregistration can occure while we are scanning through the --- 76 unchanged lines hidden (view full) --- 499 * to be called. So we clear pfd in unregister and check here. 500 */ 501void 502poll_dispatch(int wait) 503{ 504 u_int i, idx; 505 int ret; 506 tval_t now; |
500 int tout; | 507 tval_t tout; |
501 static u_int last_index; 502 503# ifdef USE_SELECT 504 fd_set nrset, nwset, nxset; 505 struct timeval tv; 506# endif 507 508 in_dispatch = 1; --- 5 unchanged lines hidden (view full) --- 514 if(resort) { 515 resort = 0; 516 sort_timers(); 517 } 518 519 /* in wait mode - compute the timeout */ 520 if(wait) { 521 if(tfd_used) { | 508 static u_int last_index; 509 510# ifdef USE_SELECT 511 fd_set nrset, nwset, nxset; 512 struct timeval tv; 513# endif 514 515 in_dispatch = 1; --- 5 unchanged lines hidden (view full) --- 521 if(resort) { 522 resort = 0; 523 sort_timers(); 524 } 525 526 /* in wait mode - compute the timeout */ 527 if(wait) { 528 if(tfd_used) { |
522 now = GETMSECS(); | 529 now = GETUSECS(); |
523# ifdef DEBUG 524 { | 530# ifdef DEBUG 531 { |
525 fprintf(stderr, "now=%"QUADFMT"u", now); | 532 fprintf(stderr, "now=%llu", now); |
526 for(i = 0; i < tims_used; i++) | 533 for(i = 0; i < tims_used; i++) |
527 fprintf(stderr, "timers[%2d] = %"QUADFMT"d", i, tfd[i]->when - now); | 534 fprintf(stderr, "timers[%2d] = %lld", 535 i, tfd[i]->when - now); |
528 } 529# endif 530 if((tout = tims[tfd[0]].when - now) < 0) 531 tout = 0; 532 } else 533 tout = INFTIM; 534 } else 535 tout = 0; 536 537# ifdef DEBUG 538 fprintf(stderr, "rpoll -- selecting with tout=%u", tout); 539# endif 540 541# ifdef USE_POLL | 536 } 537# endif 538 if((tout = tims[tfd[0]].when - now) < 0) 539 tout = 0; 540 } else 541 tout = INFTIM; 542 } else 543 tout = 0; 544 545# ifdef DEBUG 546 fprintf(stderr, "rpoll -- selecting with tout=%u", tout); 547# endif 548 549# ifdef USE_POLL |
542 ret = poll(pfd, regs_used, tout); | 550 ret = poll(pfd, regs_used, tout == INFTIM ? INFTIM : (tout / 1000)); |
543# endif 544 545# ifdef USE_SELECT 546 nrset = rset; 547 nwset = wset; 548 nxset = xset; 549 if(tout != INFTIM) { | 551# endif 552 553# ifdef USE_SELECT 554 nrset = rset; 555 nwset = wset; 556 nxset = xset; 557 if(tout != INFTIM) { |
550 tv.tv_sec = tout / 1000; 551 tv.tv_usec = (tout % 1000) * 1000; | 558 tv.tv_sec = tout / 1000000; 559 tv.tv_usec = tout % 1000000; |
552 } 553 ret = select(maxfd+1, 554 SELECT_CAST(&nrset), 555 SELECT_CAST(&nwset), | 560 } 561 ret = select(maxfd+1, 562 SELECT_CAST(&nrset), 563 SELECT_CAST(&nwset), |
556 SELECT_CAST(&nxset), (tout==INFTIM) ? 0 : &tv); | 564 SELECT_CAST(&nxset), (tout==INFTIM) ? NULL : &tv); |
557# endif 558 559 if(ret == -1) { 560 if(errno == EINTR) 561 return; 562 _panic("poll/select: %s", strerror(errno)); 563 } 564 --- 4 unchanged lines hidden (view full) --- 569 570 assert(idx < regs_alloc); 571 572 if(regs[idx].fd >= 0) { 573 int mask = 0; 574 575# ifdef USE_POLL 576 if(regs[idx].pfd) { | 565# endif 566 567 if(ret == -1) { 568 if(errno == EINTR) 569 return; 570 _panic("poll/select: %s", strerror(errno)); 571 } 572 --- 4 unchanged lines hidden (view full) --- 577 578 assert(idx < regs_alloc); 579 580 if(regs[idx].fd >= 0) { 581 int mask = 0; 582 583# ifdef USE_POLL 584 if(regs[idx].pfd) { |
577 if(regs[idx].pfd->revents & poll_in) | 585 if ((regs[idx].mask & POLL_IN) && 586 (regs[idx].pfd->revents & poll_in)) |
578 mask |= POLL_IN; | 587 mask |= POLL_IN; |
579 if(regs[idx].pfd->revents & poll_out) | 588 if ((regs[idx].mask & POLL_OUT) && 589 (regs[idx].pfd->revents & poll_out)) |
580 mask |= POLL_OUT; | 590 mask |= POLL_OUT; |
581 if(regs[idx].pfd->revents & poll_except) | 591 if((regs[idx].mask & POLL_EXCEPT) && 592 (regs[idx].pfd->revents & poll_except)) |
582 mask |= POLL_EXCEPT; 583 } 584# endif 585# ifdef USE_SELECT | 593 mask |= POLL_EXCEPT; 594 } 595# endif 596# ifdef USE_SELECT |
586 if(FD_ISSET(regs[idx].fd, &nrset)) | 597 if ((regs[idx].mask & POLL_IN) && 598 FD_ISSET(regs[idx].fd, &nrset)) |
587 mask |= POLL_IN; | 599 mask |= POLL_IN; |
588 if(FD_ISSET(regs[idx].fd, &nwset)) | 600 if ((regs[idx].mask & POLL_OUT) && 601 FD_ISSET(regs[idx].fd, &nwset)) |
589 mask |= POLL_OUT; | 602 mask |= POLL_OUT; |
590 if(FD_ISSET(regs[idx].fd, &nxset)) | 603 if ((regs[idx].mask & POLL_EXCEPT) && 604 FD_ISSET(regs[idx].fd, &nxset)) |
591 mask |= POLL_EXCEPT; 592# endif 593 assert(idx < regs_alloc); 594 595 if(mask) { 596 if(rpoll_trace) 597 fprintf(stderr, "poll_dispatch() -- " | 605 mask |= POLL_EXCEPT; 606# endif 607 assert(idx < regs_alloc); 608 609 if(mask) { 610 if(rpoll_trace) 611 fprintf(stderr, "poll_dispatch() -- " |
598 "file %d/%d", 599 regs[idx].fd, idx); | 612 "file %d/%d %x", 613 regs[idx].fd, idx, mask); |
600 (*regs[idx].func)(regs[idx].fd, mask, regs[idx].arg); 601 } 602 } 603 604 } 605 last_index++; 606 } 607 608 /* dispatch timeouts */ 609 if(tfd_used) { | 614 (*regs[idx].func)(regs[idx].fd, mask, regs[idx].arg); 615 } 616 } 617 618 } 619 last_index++; 620 } 621 622 /* dispatch timeouts */ 623 if(tfd_used) { |
610 now = GETMSECS(); | 624 now = GETUSECS(); |
611 for(i = 0; i < tfd_used; i++) { 612 if(tfd[i] < 0) 613 continue; 614 if(tims[tfd[i]].when > now) 615 break; 616 if(rpoll_trace) 617 fprintf(stderr, "rpoll_dispatch() -- timeout %d",tfd[i]); 618 (*tims[tfd[i]].func)(tfd[i], tims[tfd[i]].arg); 619 if(tfd[i] < 0) 620 continue; 621 if(tims[tfd[i]].repeat) | 625 for(i = 0; i < tfd_used; i++) { 626 if(tfd[i] < 0) 627 continue; 628 if(tims[tfd[i]].when > now) 629 break; 630 if(rpoll_trace) 631 fprintf(stderr, "rpoll_dispatch() -- timeout %d",tfd[i]); 632 (*tims[tfd[i]].func)(tfd[i], tims[tfd[i]].arg); 633 if(tfd[i] < 0) 634 continue; 635 if(tims[tfd[i]].repeat) |
622 tims[tfd[i]].when = now + tims[tfd[i]].msecs; | 636 tims[tfd[i]].when = now + tims[tfd[i]].usecs; |
623 else { 624 tims[tfd[i]].func = NULL; 625 tims_used--; 626 tfd[i] = -1; 627 } 628 resort = 1; 629 } 630 } --- 8 unchanged lines hidden (view full) --- 639double elaps(void); 640void infunc(int fd, int mask, void *arg); 641 642double 643elaps(void) 644{ 645 gettimeofday(&now, NULL); 646 | 637 else { 638 tims[tfd[i]].func = NULL; 639 tims_used--; 640 tfd[i] = -1; 641 } 642 resort = 1; 643 } 644 } --- 8 unchanged lines hidden (view full) --- 653double elaps(void); 654void infunc(int fd, int mask, void *arg); 655 656double 657elaps(void) 658{ 659 gettimeofday(&now, NULL); 660 |
647 return (double)(10 * now.tv_sec + now.tv_usec / 100000 - 10 * start.tv_sec - start.tv_usec / 100000) 648 / 10; | 661 return (double)(10 * now.tv_sec + now.tv_usec / 100000 - 662 10 * start.tv_sec - start.tv_usec / 100000) / 10; |
649} 650 651void 652infunc(int fd, int mask, void *arg) 653{ 654 char buf[1024]; 655 int ret; 656 --- 13 unchanged lines hidden (view full) --- 670{ 671 printf("%4.1f -- %d: %s\n", elaps(), tid, (char *)arg); 672} 673void 674tfunc1(int tid, void *arg) 675{ 676 printf("%4.1f -- %d: %s\n", elaps(), tid, (char *)arg); 677} | 663} 664 665void 666infunc(int fd, int mask, void *arg) 667{ 668 char buf[1024]; 669 int ret; 670 --- 13 unchanged lines hidden (view full) --- 684{ 685 printf("%4.1f -- %d: %s\n", elaps(), tid, (char *)arg); 686} 687void 688tfunc1(int tid, void *arg) 689{ 690 printf("%4.1f -- %d: %s\n", elaps(), tid, (char *)arg); 691} |
692void 693tfunc2(int tid, void *arg) 694{ 695 static u_int count = 0; |
|
678 | 696 |
697 if (++count % 10000 == 0) 698 printf("%4.1f -- %d\n", elaps(), tid); 699} 700 |
|
679void first(int tid, void *arg); 680void second(int tid, void *arg); 681 682void 683second(int tid, void *arg) 684{ 685 printf("%4.1f -- %d: %s\n", elaps(), tid, (char *)arg); | 701void first(int tid, void *arg); 702void second(int tid, void *arg); 703 704void 705second(int tid, void *arg) 706{ 707 printf("%4.1f -- %d: %s\n", elaps(), tid, (char *)arg); |
686 poll_start_timer(5500, 0, first, "first"); | 708 poll_start_utimer(5500000, 0, first, "first"); |
687 poll_stop_timer(t1); 688 t0 = poll_start_timer(1000, 1, tfunc0, "1 second"); 689} 690void 691first(int tid, void *arg) 692{ 693 printf("%4.1f -- %d: %s\n", elaps(), tid, (char *)arg); 694 poll_start_timer(3700, 0, second, "second"); 695 poll_stop_timer(t0); 696 t1 = poll_start_timer(250, 1, tfunc1, "1/4 second"); 697} 698 699int 700main(int argc, char *argv[]) 701{ | 709 poll_stop_timer(t1); 710 t0 = poll_start_timer(1000, 1, tfunc0, "1 second"); 711} 712void 713first(int tid, void *arg) 714{ 715 printf("%4.1f -- %d: %s\n", elaps(), tid, (char *)arg); 716 poll_start_timer(3700, 0, second, "second"); 717 poll_stop_timer(t0); 718 t1 = poll_start_timer(250, 1, tfunc1, "1/4 second"); 719} 720 721int 722main(int argc, char *argv[]) 723{ |
702 argc = argc; | |
703 argv = argv; 704 gettimeofday(&start, NULL); 705 poll_register(0, infunc, NULL, POLL_IN); | 724 argv = argv; 725 gettimeofday(&start, NULL); 726 poll_register(0, infunc, NULL, POLL_IN); |
706 t0 = poll_start_timer(1000, 1, tfunc0, "1 second"); 707 poll_start_timer(2500, 0, first, "first"); | |
708 | 727 |
728 if (argc < 2) { 729 t0 = poll_start_timer(1000, 1, tfunc0, "1 second"); 730 poll_start_timer(2500, 0, first, "first"); 731 } else { 732 t0 = poll_start_utimer(300, 1, tfunc2, NULL); 733 } 734 |
|
709 while(1) 710 poll_dispatch(1); 711 712 return 0; 713} 714# endif | 735 while(1) 736 poll_dispatch(1); 737 738 return 0; 739} 740# endif |