+
    \vj                     H    R t ^ RIt^ RItR tR tR tR	tR tR tR t	R t
R# )
zShared stall detectors for process trees and cgroup sampling.

`stall-guard` keeps the existing process-tree detector, while `pids-guard`
uses the same accumulator logic for cgroup counters.
Nc                P   V Uu/ uF  q"R.\        V 4      ,          bK  	  pp\        ^\        V 4      4       Fe  pV F\  pW,          V,          W^,
          ,          V,          ,
          pW2,          V^,
          ,          V^ 8  d   TMR,           W2,          V&   K^  	  Kg  	  V# u upi )zPer-signal cumulative sum of positive deltas only.

Raw counters can decrease when tasks exit or logs rotate. Only increases are
treated as progress.
g        )lenrange)sampleskeyskey
cumulativeirises   &&    G/home/user/Projects/overdeck/modules/monitor/bin/../lib/stall_detect.py
accumulater      s     8<<tus7|++tJ<1c'l#C:c?WU^C%88D!+Q!74!84QT!UJOA  $  =s   B#c                      \        V 4      ;_uu_ 4       p\        VP                  4       P                  4       4      uuR R R 4       #   + '       g   i     R # ; i  \        \
        3 d     R # i ; iN)openintreadstripOSError
ValueError)pathhandles   & r   _read_counterr      sK    $ZZ6v{{}**,- ZZZZ  s-   A 'A
A A	A A A0/A0c                 0    \        V 4      ;_uu_ 4       pV FF  pVP                  R 4      '       g   K  \        VP                  4       ^,          4      u uuRRR4       # 	  RRR4       R#   + '       g   i     R# ; i  \        \
        3 d     R# i ; i)
usage_usecN)r   
startswithr   splitr   r   )r   r   lines   &  r   _read_cpu_usecsr   !   st    $ZZ6??<00tzz|A// Z   Z  Z  s?   B  A,!A,
B   A,"B  ,A=	7B  =B   BBc                   ^ p^ p^ pV  F  p \        VP                  4       4      pT^ 8:  d   K&  T^,          p \        RT R24      ;_uu_ 4       pT F9  pTP	                  R4      w  rp
TR8X  g
   TR8X  g   K'  T\        T
4      ,          pK;  	  RRR4       T^,          pK  	  V'       d   V'       g   R# V#   \         d     K  i ; i  + '       g   i     LC; i  \
        \        3 d     K  i ; i)a1  Sum rchar+wchar over the cgroup's tasks, or None when nothing was readable.

/proc/<pid>/io is ptrace-gated: a bwrap-confined agent tree denies it to its
own uid. A denied read is not evidence of zero IO, so a cgroup whose tasks
are all unreadable reports the signal as absent rather than as a flat zero.
z/proc/z/io:rcharwcharN)r   r   r   r   	partitionr   )raw_pidstotaltasksreadableraw_pidpidr   r   name_values   &          r   _read_proc_ior,   /   s     EEH	gmmo&C !8
	se3'((F"D%)^^C%8NDUw$'/U+ # )
 MH " XL!  		 )( $ 		s@   B9C%C:CC9CCCCC32C3c                x   a  \         ;QJ d    . V 3R l\         4       F  NK  	  5# ! V 3R l\         4       4      # )zISignals that failed to produce a real observation in at least one sample.c              3      <a"   T FI  o\         ;QJ d    V3R  lS 4       F  '       g   K   RM	  RM! V3R  lS 4       4      '       g   KE  Sx  KK  	  R# 5i)c              3   H   <"   T F  qP                  S4      R J x  K  	  R # 5ir   )get).0sampler   s   & r   	<genexpr>0unavailable_signals.<locals>.<genexpr>.<genexpr>R   s     %TG&jjo&=Gs   "TFN)any)r1   r   r   s   &@r   r3   &unavailable_signals.<locals>.<genexpr>Q   s3      ##%TG%T###%TG%T"Tws   AAA
A)tupleSIGNALS)r   s   fr   unavailable_signalsr9   O   s5    5 5 5       c           
     p   \         P                  P                  V R4      p \        V4      ;_uu_ 4       pVP	                  4       P                  4       pRRR4       \        \         P                  P                  T R4      4      pTf   R# \        \         P                  P                  T R4      4      pTf   R# \        \         P                  P                  T R4      4      pTf   R# \        X4      pR\        P                  ! 4       RTRTR	TR
T/#   + '       g   i     L; i  \         d     R# i ; i)u   Read cgroup counters for a single cgroup directory.

Returns None when required counters cannot be read. `io` is None when the
kernel refused every per-task read — see _read_proc_io.
zcgroup.procsNzcpu.statzpids.currentzmemory.currenttcpuiopidsmem)osr   joinr   r   
splitlinesr   r   r   r,   time)r   
procs_pathr   r#   r=   r?   r@   r>   s   &       r   sample_cgrouprF   V   s     dN3J*{{}//1H 
 "'',,tZ8
9C
{dN;<D|
T+;<
=C
{	x	 B 	TYY[sbs '  s.   D& DD& D#	D& #D& &D54D5c                  a aaa \        S 4      ^8  d   R# \        S 4      '       d   R# \        S \        4      oS R
,          oVV 3R lpV! V4      oSf   R# \        ;QJ d$    VV3R l\         4       F  '       d   K   RM	  RM! VV3R l\         4       4      '       d&   SR,          S S,          R,          ,
          pRVR R	2# R# )zReturn a reason string when all three counters are flat for the window.

Refuses to answer while any signal is absent: an unobserved counter is
constant, and a constant counter can never dissent from the others.
Nc                 z   < SR ,          V ,
          pRp\        S4       F  w  r4VR ,          V8  d    V# TpK  	  V# )r<   N)	enumerate)window_swindow_startfoundr	   r2   lastr   s   &    r   anchor_index%classify_cgroup.<locals>.anchor_index   sI    Cy8+"7+IAc{\) E , r:   c              3   f   <"   T F&  pSV,          S,          SV,          R,          8H  x  K(  	  R# 5i)   N )r1   r   r   indexs   & r   r3   "classify_cgroup.<locals>.<genexpr>   s(     
LGS:c?5!Z_R%88Gs   .1FTr<   zno progress on cpu+io+pids for z.0fsrR   )r   r9   r   r8   all)r   idle_window_srN   idle_forr   rT   rM   s   f&  @@@r   classify_cgrouprZ   z   s     7|a7##GW-J2;D 'E}
s
LG
Lsss
LG
LLL9wu~c220#a@@r:   )r=   r>   r?   )__doc__rA   rD   r   r   r   r8   r,   r9   rF   rZ   rS   r:   r   <module>r\      s>    
   @!Hr:   