35
36:- module(procps,
37 [ procps_stat/1, 38 procps_stat/2, 39 procps_thread_stat/2, 40 procps_status/1, 41 procps_status/2 42 ]). 43:- if(exists_source(library(unix))). 44:- use_module(library(unix)). 45:- endif. 46:- use_module(library(lists)). 47
50
51 54
66
67procps_stat(Stat) :-
68 stat_file_dict('/proc/self/stat', Stat).
69procps_stat(Pid, Stat) :-
70 atomic_list_concat(['/proc/', Pid, '/stat'], StatFile),
71 stat_file_dict(StatFile, Stat).
72
73procps_thread_stat(Thread, Stat) :-
74 thread_property(Thread, system_thread_id(TID)),
75 atomic_list_concat(['/proc/self/task/', TID, '/stat'], StatFile),
76 stat_file_dict(StatFile, Stat).
77
78stat_file_dict(StatFile, Stat) :-
79 setup_call_cleanup(
80 open(StatFile, read, In),
81 read_string(In, _, String),
82 close(In)),
83 split_string(String, " ", " \n", Parts),
84 parts_pairs(Parts, 1, Pairs),
85 dict_pairs(Stat, stat, Pairs).
86
87parts_pairs([], _, []).
88parts_pairs([H0|T0], I0, [H|T]) :-
89 part_pair(H0, I0, H),
90 I is I0+1,
91 parts_pairs(T0, I, T).
92
93part_pair(String, I, Key-Value) :-
94 stat_field(Key, I), !,
95 stat_field_value(Key, String, Value).
96part_pair(String, I, I-String).
97
98stat_field_value(comm, String, Command) :- !,
99 sub_string(String, 1, _, 1, Command).
100stat_field_value(state, String, Atom) :- !,
101 atom_string(Atom, String).
102stat_field_value(Field, String, Seconds) :-
103 time_field(Field), !,
104 number_string(ClockTicks, String),
105 clockticks(TicksPerSec),
106 Seconds is ClockTicks/TicksPerSec.
107stat_field_value(Field, String, Bytes) :-
108 page_field(Field), !,
109 number_string(Pages, String),
110 pagesize(BytesPerPage),
111 Bytes is Pages*BytesPerPage.
112stat_field_value(_, String, Number) :-
113 number_string(Number, String).
114
115:- if(current_predicate(sysconf/1)). 118term_expansion(clockticks(sysconf), Expansion) :-
119 ( member(Sysconf, [sysconf(clk_tck(TicksPerSec))]),
120 call(Sysconf)
121 -> Expansion = clockticks(TicksPerSec)
122 ; Expansion = clockticks(100)
123 ).
124term_expansion(pagesize(sysconf), Expansion) :-
125 ( member(Sysconf, [sysconf(pagesize(Bytes))]),
126 call(Sysconf)
127 -> Expansion = pagesize(Bytes)
128 ; Expansion = pagesize(4096)
129 ).
130clockticks(sysconf).
131pagesize(sysconf).
132:- else. 133clockticks(100).
134pagesize(4096).
135:- endif. 136
137time_field(utime).
138time_field(stime).
139time_field(cutime).
140time_field(cstime).
141time_field(starttime).
142
143page_field(rss).
144
145stat_field(pid, 1).
146stat_field(comm, 2).
147stat_field(state, 3).
148stat_field(ppid, 4).
149stat_field(pgrp, 5).
150stat_field(session, 6).
151stat_field(tty_nr, 7).
152stat_field(tpgid, 8).
153stat_field(flags, 9).
154stat_field(minflt, 10).
155stat_field(cminflt, 11).
156stat_field(majflt, 12).
157stat_field(cmajflt, 13).
158stat_field(utime, 14).
159stat_field(stime, 15).
160stat_field(cutime, 16).
161stat_field(cstime, 17).
162stat_field(priority, 18).
163stat_field(nice, 19).
164stat_field(num_threads, 20).
165stat_field(itrealvalue, 21).
166stat_field(starttime, 22).
167stat_field(vsize, 23).
168stat_field(rss, 24).
169stat_field(rsslim, 25).
170stat_field(startcode, 26).
171stat_field(endcode, 27).
172stat_field(startstack, 28).
173stat_field(kstkesp, 29).
174stat_field(kstkeip, 30).
175stat_field(signal, 31).
176stat_field(blocked, 32).
177stat_field(sigignore, 33).
178stat_field(sigcatch, 34).
179stat_field(wchan, 35).
180stat_field(nswap, 36).
181stat_field(cnswap, 37).
182stat_field(exit_signal, 38).
183stat_field(processor, 39).
184stat_field(rt_priority, 40).
185stat_field(policy, 41).
186stat_field(delayacct_blkio_ticks, 42).
187stat_field(guest_time, 43).
188stat_field(cguest_time, 44).
189stat_field(start_data, 45).
190stat_field(end_data, 46).
191stat_field(start_brk, 47).
192stat_field(arg_start, 48).
193stat_field(arg_end, 49).
194stat_field(env_start, 50).
195stat_field(env_end, 51).
196stat_field(exit_code, 52).
197
198
199 202
209
210procps_status(Stat) :-
211 status_file_dict('/proc/self/status', Stat).
212procps_status(Pid, Stat) :-
213 atomic_list_concat(['/proc/', Pid, '/status'], StatFile),
214 status_file_dict(StatFile, Stat).
215
216status_file_dict(StatFile, Status) :-
217 setup_call_cleanup(
218 open(StatFile, read, In),
219 read_string(In, _, String),
220 close(In)),
221 split_string(String, "\n", " \n", Lines),
222 status_line_pairs(Lines, Pairs),
223 dict_pairs(Status, status, Pairs).
224
225status_line_pairs([], []).
226status_line_pairs([H0|T0], [Name-Value|T]) :-
227 split_string(H0, ":", " \t", [NameS, ValueS]),
228 string_lower(NameS, NameLS),
229 atom_string(Name, NameLS),
230 status_value(Name, ValueS, Value), !,
231 status_line_pairs(T0, T).
232status_line_pairs([_|T0], T) :-
233 status_line_pairs(T0, T).
234
235status_value(state, ValueS, State) :- !,
236 split_string(ValueS, " ", " ", [Vs|_]),
237 atom_string(State, Vs).
238status_value(Name, ValueS, Bytes) :-
239 sub_atom(Name, 0, _, _, vm), !,
240 split_string(ValueS, " ", " ", [Vs,"kB"]),
241 number_string(Kb, Vs),
242 Bytes is Kb*1024.
243status_value(Name, ValueS, Value) :-
244 status_field(Name, list(Type)),
245 !,
246 split_string(ValueS, " \t", " \t", Values),
247 maplist(to_type(Type), Values, Value).
248status_value(Name, ValueS, Value) :-
249 status_field(Name, Type),
250 to_type(Type, ValueS, Value).
251
252to_type(integer, String, Int) :-
253 number_string(Int, String).
254to_type(hex, String, Int) :-
255 string_concat('0x', String, Hex),
256 number_string(Int, Hex).
257
258status_field(uid, list(integer)).
259status_field(gid, list(integer)).
260status_field(groups, list(integer)).
261status_field(cpus_allowed, hex).
262status_field(fdsize, integer).
263status_field(threads, integer)