572 if (delta < 0) {
573 newtime = gethrtime_unscaled();
574 delta = newtime - hrlb;
575 }
576 t->t_hrtime = newtime;
577 scalehrtime(&delta);
578 pctcpu = t->t_pctcpu;
579 npctcpu = cpu_grow(pctcpu, delta);
580 } else {
581 hrlb = t->t_hrtime;
582 delta = newtime - hrlb;
583 if (delta < 0) {
584 newtime = gethrtime_unscaled();
585 delta = newtime - hrlb;
586 }
587 t->t_hrtime = newtime;
588 scalehrtime(&delta);
589 pctcpu = t->t_pctcpu;
590 npctcpu = cpu_decay(pctcpu, delta);
591 }
592 } while (cas32(&t->t_pctcpu, pctcpu, npctcpu) != pctcpu);
593
594 return (npctcpu);
595 }
596
597 /*
598 * Change the microstate level for the LWP and update the
599 * associated accounting information. Return the previous
600 * LWP state.
601 */
602 int
603 new_mstate(kthread_t *t, int new_state)
604 {
605 struct mstate *ms;
606 unsigned state;
607 hrtime_t *mstimep;
608 hrtime_t curtime;
609 hrtime_t newtime;
610 hrtime_t oldtime;
611 hrtime_t ztime;
612 hrtime_t origstart;
640 case LMS_TFAULT:
641 case LMS_DFAULT:
642 case LMS_KFAULT:
643 case LMS_USER_LOCK:
644 mstimep = &ms->ms_acct[LMS_SYSTEM];
645 break;
646 default:
647 mstimep = &ms->ms_acct[state];
648 break;
649 }
650 ztime = newtime = curtime - ms->ms_state_start;
651 if (newtime < 0) {
652 curtime = gethrtime_unscaled();
653 oldtime = *mstimep - 1; /* force CAS to fail */
654 continue;
655 }
656 oldtime = *mstimep;
657 newtime += oldtime;
658 t->t_mstate = new_state;
659 ms->ms_state_start = curtime;
660 } while (cas64((uint64_t *)mstimep, oldtime, newtime) != oldtime);
661
662 /*
663 * When the system boots the initial startup thread will have a
664 * ms_state_start of 0 which would add a huge system time to the global
665 * zone. We want to skip aggregating that initial bit of work.
666 */
667 if (origstart != 0) {
668 z = ttozone(t);
669 if (state == LMS_USER)
670 atomic_add_64(&z->zone_utime, ztime);
671 else if (state == LMS_SYSTEM)
672 atomic_add_64(&z->zone_stime, ztime);
673 }
674
675 /*
676 * Remember the previous running microstate.
677 */
678 if (state != LMS_SLEEP && state != LMS_STOPPED)
679 ms->ms_prev = state;
680
764 case LMS_USER_LOCK:
765 mstimep = &ms->ms_acct[LMS_SYSTEM];
766 break;
767 default:
768 mstimep = &ms->ms_acct[t->t_mstate];
769 break;
770 }
771 waitrq = t->t_waitrq; /* hopefully atomic */
772 if (waitrq == 0) {
773 waitrq = curtime;
774 }
775 t->t_waitrq = 0;
776 newtime = waitrq - ms->ms_state_start;
777 if (newtime < 0) {
778 curtime = gethrtime_unscaled();
779 oldtime = *mstimep - 1; /* force CAS to fail */
780 continue;
781 }
782 oldtime = *mstimep;
783 newtime += oldtime;
784 } while (cas64((uint64_t *)mstimep, oldtime, newtime) != oldtime);
785
786 /*
787 * Update the WAIT_CPU timer and per-cpu waitrq total.
788 */
789 z = ttozone(t);
790 waittime = curtime - waitrq;
791 ms->ms_acct[LMS_WAIT_CPU] += waittime;
792 atomic_add_64(&z->zone_wtime, waittime);
793 CPU->cpu_waitrq += waittime;
794 ms->ms_state_start = curtime;
795 }
796
797 /*
798 * Copy lwp microstate accounting and resource usage information
799 * to the process. (lwp is terminating)
800 */
801 void
802 term_mstate(kthread_t *t)
803 {
804 struct mstate *ms;
|
572 if (delta < 0) {
573 newtime = gethrtime_unscaled();
574 delta = newtime - hrlb;
575 }
576 t->t_hrtime = newtime;
577 scalehrtime(&delta);
578 pctcpu = t->t_pctcpu;
579 npctcpu = cpu_grow(pctcpu, delta);
580 } else {
581 hrlb = t->t_hrtime;
582 delta = newtime - hrlb;
583 if (delta < 0) {
584 newtime = gethrtime_unscaled();
585 delta = newtime - hrlb;
586 }
587 t->t_hrtime = newtime;
588 scalehrtime(&delta);
589 pctcpu = t->t_pctcpu;
590 npctcpu = cpu_decay(pctcpu, delta);
591 }
592 } while (atomic_cas_32(&t->t_pctcpu, pctcpu, npctcpu) != pctcpu);
593
594 return (npctcpu);
595 }
596
597 /*
598 * Change the microstate level for the LWP and update the
599 * associated accounting information. Return the previous
600 * LWP state.
601 */
602 int
603 new_mstate(kthread_t *t, int new_state)
604 {
605 struct mstate *ms;
606 unsigned state;
607 hrtime_t *mstimep;
608 hrtime_t curtime;
609 hrtime_t newtime;
610 hrtime_t oldtime;
611 hrtime_t ztime;
612 hrtime_t origstart;
640 case LMS_TFAULT:
641 case LMS_DFAULT:
642 case LMS_KFAULT:
643 case LMS_USER_LOCK:
644 mstimep = &ms->ms_acct[LMS_SYSTEM];
645 break;
646 default:
647 mstimep = &ms->ms_acct[state];
648 break;
649 }
650 ztime = newtime = curtime - ms->ms_state_start;
651 if (newtime < 0) {
652 curtime = gethrtime_unscaled();
653 oldtime = *mstimep - 1; /* force CAS to fail */
654 continue;
655 }
656 oldtime = *mstimep;
657 newtime += oldtime;
658 t->t_mstate = new_state;
659 ms->ms_state_start = curtime;
660 } while (atomic_cas_64((uint64_t *)mstimep, oldtime, newtime) !=
661 oldtime);
662
663 /*
664 * When the system boots the initial startup thread will have a
665 * ms_state_start of 0 which would add a huge system time to the global
666 * zone. We want to skip aggregating that initial bit of work.
667 */
668 if (origstart != 0) {
669 z = ttozone(t);
670 if (state == LMS_USER)
671 atomic_add_64(&z->zone_utime, ztime);
672 else if (state == LMS_SYSTEM)
673 atomic_add_64(&z->zone_stime, ztime);
674 }
675
676 /*
677 * Remember the previous running microstate.
678 */
679 if (state != LMS_SLEEP && state != LMS_STOPPED)
680 ms->ms_prev = state;
681
765 case LMS_USER_LOCK:
766 mstimep = &ms->ms_acct[LMS_SYSTEM];
767 break;
768 default:
769 mstimep = &ms->ms_acct[t->t_mstate];
770 break;
771 }
772 waitrq = t->t_waitrq; /* hopefully atomic */
773 if (waitrq == 0) {
774 waitrq = curtime;
775 }
776 t->t_waitrq = 0;
777 newtime = waitrq - ms->ms_state_start;
778 if (newtime < 0) {
779 curtime = gethrtime_unscaled();
780 oldtime = *mstimep - 1; /* force CAS to fail */
781 continue;
782 }
783 oldtime = *mstimep;
784 newtime += oldtime;
785 } while (atomic_cas_64((uint64_t *)mstimep, oldtime, newtime) !=
786 oldtime);
787
788 /*
789 * Update the WAIT_CPU timer and per-cpu waitrq total.
790 */
791 z = ttozone(t);
792 waittime = curtime - waitrq;
793 ms->ms_acct[LMS_WAIT_CPU] += waittime;
794 atomic_add_64(&z->zone_wtime, waittime);
795 CPU->cpu_waitrq += waittime;
796 ms->ms_state_start = curtime;
797 }
798
799 /*
800 * Copy lwp microstate accounting and resource usage information
801 * to the process. (lwp is terminating)
802 */
803 void
804 term_mstate(kthread_t *t)
805 {
806 struct mstate *ms;
|