Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
htop
Commits
907f8298
Commit
907f8298
authored
Jul 14, 2015
by
David Hunt
Committed by
Hisham Muhammad
Aug 19, 2015
Browse files
CPU per process implemented
parent
57ab332d
Changes
4
Hide whitespace changes
Inline
Side-by-side
darwin/DarwinProcess.c
View file @
907f8298
...
...
@@ -11,6 +11,7 @@ in the source distribution for its full text.
#include <stdlib.h>
#include <libproc.h>
#include <string.h>
#include <stdio.h>
/*{
#include "Settings.h"
...
...
@@ -18,24 +19,45 @@ in the source distribution for its full text.
#include <sys/sysctl.h>
typedef struct DarwinProcess_ {
Process super;
uint64_t utime;
uint64_t stime;
} DarwinProcess;
}*/
Process
*
DarwinProcess_new
(
Settings
*
settings
)
{
Process
*
this
=
calloc
(
sizeof
(
Process
),
1
);
Object_setClass
(
this
,
Class
(
Process
));
Process_init
(
this
,
settings
);
ProcessClass
DarwinProcess_class
=
{
.
super
=
{
.
extends
=
Class
(
Process
),
.
display
=
Process_display
,
.
delete
=
Process_delete
,
.
compare
=
Process_compare
},
.
writeField
=
Process_writeField
,
};
DarwinProcess
*
DarwinProcess_new
(
Settings
*
settings
)
{
DarwinProcess
*
this
=
calloc
(
sizeof
(
DarwinProcess
),
1
);
Object_setClass
(
this
,
Class
(
DarwinProcess
));
Process_init
(
&
this
->
super
,
settings
);
this
->
utime
=
0
;
this
->
stime
=
0
;
return
this
;
}
void
Process_delete
(
Object
*
cast
)
{
Process
*
this
=
(
Process
*
)
cast
;
Object_setClass
(
this
,
Class
(
Process
));
Process_done
((
Process
*
)
cast
);
DarwinProcess
*
this
=
(
DarwinProcess
*
)
cast
;
Process_done
(
&
this
->
super
);
// free platform-specific fields here
free
(
this
);
}
bool
Process_isThread
(
Process
*
this
)
{
(
void
)
this
;
return
false
;
}
...
...
@@ -47,7 +69,7 @@ void DarwinProcess_setStartTime(Process *proc, struct extern_proc *ep, time_t no
strftime
(
proc
->
starttime_show
,
7
,
((
proc
->
starttime_ctime
>
now
-
86400
)
?
"%R "
:
"%b%d "
),
&
date
);
}
char
*
DarwinProcess
List
_getCmdLine
(
struct
kinfo_proc
*
k
,
int
show_args
)
{
char
*
DarwinProcess_getCmdLine
(
struct
kinfo_proc
*
k
,
int
show_args
)
{
/* This function is from the old Mac version of htop. Originally from ps? */
int
mib
[
3
],
argmax
,
nargs
,
c
=
0
;
size_t
size
;
...
...
@@ -264,7 +286,7 @@ void DarwinProcess_setFromKInfoProc(Process *proc, struct kinfo_proc *ps, time_t
/* The command is from the old Mac htop */
char
*
slash
;
proc
->
comm
=
DarwinProcess
List
_getCmdLine
(
ps
,
false
);
proc
->
comm
=
DarwinProcess_getCmdLine
(
ps
,
false
);
slash
=
strrchr
(
proc
->
comm
,
'/'
);
proc
->
basenameOffset
=
(
NULL
!=
slash
)
?
(
slash
-
proc
->
comm
)
:
0
;
}
...
...
@@ -287,36 +309,36 @@ void DarwinProcess_setFromKInfoProc(Process *proc, struct kinfo_proc *ps, time_t
proc
->
updated
=
true
;
}
void
DarwinProcess_setFromLibprocPidinfo
(
Process
*
proc
,
DarwinProcessList
*
dpl
,
bool
preExisting
)
{
void
DarwinProcess_setFromLibprocPidinfo
(
Darwin
Process
*
proc
,
DarwinProcessList
*
dpl
)
{
struct
proc_taskinfo
pti
;
if
(
sizeof
(
pti
)
==
proc_pidinfo
(
proc
->
pid
,
PROC_PIDTASKINFO
,
0
,
&
pti
,
sizeof
(
pti
)))
{
proc
->
time
=
(
pti
.
pti_total_system
+
pti
.
pti_total_user
)
/
10000000
;
proc
->
nlwp
=
pti
.
pti_threadnum
;
proc
->
m_size
=
pti
.
pti_virtual_size
/
1024
;
proc
->
m_resident
=
pti
.
pti_resident_size
/
1024
;
proc
->
majflt
=
pti
.
pti_faults
;
proc
->
percent_mem
=
(
double
)
pti
.
pti_resident_size
*
100
.
0
if
(
sizeof
(
pti
)
==
proc_pidinfo
(
proc
->
super
.
pid
,
PROC_PIDTASKINFO
,
0
,
&
pti
,
sizeof
(
pti
)))
{
if
(
0
!=
proc
->
utime
||
0
!=
proc
->
stime
)
{
uint64_t
diff
=
(
pti
.
pti_total_system
-
proc
->
stime
)
+
(
pti
.
pti_total_user
-
proc
->
utime
);
proc
->
super
.
percent_cpu
=
(
double
)
diff
*
(
double
)
dpl
->
super
.
cpuCount
/
((
double
)
dpl
->
global_diff
*
100000
.
0
);
// fprintf(stderr, "%f %llu %llu %llu %llu %llu\n", proc->super.percent_cpu,
// proc->stime, proc->utime, pti.pti_total_system, pti.pti_total_user, dpl->global_diff);
// exit(7);
}
proc
->
super
.
time
=
(
pti
.
pti_total_system
+
pti
.
pti_total_user
)
/
10000000
;
proc
->
super
.
nlwp
=
pti
.
pti_threadnum
;
proc
->
super
.
m_size
=
pti
.
pti_virtual_size
/
1024
;
proc
->
super
.
m_resident
=
pti
.
pti_resident_size
/
1024
;
proc
->
super
.
majflt
=
pti
.
pti_faults
;
proc
->
super
.
percent_mem
=
(
double
)
pti
.
pti_resident_size
*
100
.
0
/
(
double
)
dpl
->
host_info
.
max_mem
;
proc
->
stime
=
pti
.
pti_total_system
;
proc
->
utime
=
pti
.
pti_total_user
;
dpl
->
super
.
kernelThreads
+=
0
;
/*pti.pti_threads_system;*/
dpl
->
super
.
userlandThreads
+=
pti
.
pti_threadnum
;
/*pti.pti_threads_user;*/
dpl
->
super
.
totalTasks
+=
pti
.
pti_threadnum
;
dpl
->
super
.
runningTasks
+=
pti
.
pti_numrunning
;
}
}
void
DarwinProcess_parseThreads
(
Process
*
proc
,
time_t
now
,
bool
preExisting
)
{
static
const
size_t
IDS_SZ
=
sizeof
(
uint64_t
)
*
2048
;
uint64_t
*
thread_ids
=
(
uint64_t
*
)
malloc
(
IDS_SZ
);
size_t
bytes
=
proc_pidinfo
(
proc
->
pid
,
PROC_PIDLISTTHREADS
,
0
,
thread_ids
,
IDS_SZ
);
if
(
0
<
bytes
)
{
size_t
count
=
bytes
/
sizeof
(
uint64_t
);
proc
->
nlwp
=
count
;
}
free
(
thread_ids
);
/* TODO Keep reusing this block */
}
darwin/DarwinProcess.h
View file @
907f8298
...
...
@@ -14,8 +14,17 @@ in the source distribution for its full text.
#include <sys/sysctl.h>
typedef
struct
DarwinProcess_
{
Process
super
;
Process
*
DarwinProcess_new
(
Settings
*
settings
);
uint64_t
utime
;
uint64_t
stime
;
}
DarwinProcess
;
extern
ProcessClass
DarwinProcess_class
;
DarwinProcess
*
DarwinProcess_new
(
Settings
*
settings
);
void
Process_delete
(
Object
*
cast
);
...
...
@@ -23,12 +32,10 @@ bool Process_isThread(Process* this);
void
DarwinProcess_setStartTime
(
Process
*
proc
,
struct
extern_proc
*
ep
,
time_t
now
);
char
*
DarwinProcess
List
_getCmdLine
(
struct
kinfo_proc
*
k
,
int
show_args
);
char
*
DarwinProcess_getCmdLine
(
struct
kinfo_proc
*
k
,
int
show_args
);
void
DarwinProcess_setFromKInfoProc
(
Process
*
proc
,
struct
kinfo_proc
*
ps
,
time_t
now
,
bool
exists
);
void
DarwinProcess_setFromLibprocPidinfo
(
Process
*
proc
,
DarwinProcessList
*
dpl
,
bool
preExisting
);
void
DarwinProcess_parseThreads
(
Process
*
proc
,
time_t
now
,
bool
preExisting
);
void
DarwinProcess_setFromLibprocPidinfo
(
DarwinProcess
*
proc
,
DarwinProcessList
*
dpl
);
#endif
darwin/DarwinProcessList.c
View file @
907f8298
...
...
@@ -32,6 +32,7 @@ typedef struct DarwinProcessList_ {
processor_cpu_load_info_t curr_load;
uint64_t kernel_threads;
uint64_t user_threads;
uint64_t global_diff;
} DarwinProcessList;
}*/
...
...
@@ -60,6 +61,7 @@ unsigned ProcessList_allocateCPULoadInfo(processor_cpu_load_info_t *p) {
mach_msg_type_number_t
info_size
=
sizeof
(
processor_cpu_load_info_t
);
unsigned
cpu_count
;
// TODO Improving the accuracy of the load counts woule help a lot.
if
(
0
!=
host_processor_info
(
mach_host_self
(),
PROCESSOR_CPU_LOAD_INFO
,
&
cpu_count
,
(
processor_info_array_t
*
)
p
,
&
info_size
))
{
fprintf
(
stderr
,
"Unable to retrieve CPU info
\n
"
);
exit
(
4
);
...
...
@@ -139,7 +141,7 @@ void ProcessList_goThroughEntries(ProcessList* super) {
bool
preExisting
=
true
;
struct
kinfo_proc
*
ps
;
size_t
count
;
Process
*
proc
;
Darwin
Process
*
proc
;
struct
timeval
tv
;
gettimeofday
(
&
tv
,
NULL
);
/* Start processing time */
...
...
@@ -150,6 +152,14 @@ void ProcessList_goThroughEntries(ProcessList* super) {
ProcessList_allocateCPULoadInfo
(
&
dpl
->
curr_load
);
ProcessList_getVMStats
(
&
dpl
->
vm_stats
);
/* Get the time difference */
dpl
->
global_diff
=
0
;
for
(
int
i
=
0
;
i
<
dpl
->
super
.
cpuCount
;
++
i
)
{
for
(
size_t
j
=
0
;
j
<
CPU_STATE_MAX
;
++
j
)
{
dpl
->
global_diff
+=
dpl
->
curr_load
[
i
].
cpu_ticks
[
j
]
-
dpl
->
prev_load
[
i
].
cpu_ticks
[
j
];
}
}
/* Clear the thread counts */
super
->
kernelThreads
=
0
;
super
->
userlandThreads
=
0
;
...
...
@@ -166,17 +176,17 @@ void ProcessList_goThroughEntries(ProcessList* super) {
ps
=
ProcessList_getKInfoProcs
(
&
count
);
for
(
size_t
i
=
0
;
i
<
count
;
++
i
)
{
proc
=
ProcessList_getProcess
(
super
,
ps
[
i
].
kp_proc
.
p_pid
,
&
preExisting
,
DarwinProcess_new
);
proc
=
(
DarwinProcess
*
)
ProcessList_getProcess
(
super
,
ps
[
i
].
kp_proc
.
p_pid
,
&
preExisting
,
(
Process_New
)
DarwinProcess_new
);
DarwinProcess_setFromKInfoProc
(
proc
,
ps
+
i
,
tv
.
tv_sec
,
preExisting
);
DarwinProcess_setFromLibprocPidinfo
(
proc
,
dpl
,
preExisting
);
DarwinProcess_setFromKInfoProc
(
&
proc
->
super
,
ps
+
i
,
tv
.
tv_sec
,
preExisting
);
DarwinProcess_setFromLibprocPidinfo
(
proc
,
dpl
);
super
->
totalTasks
+=
1
;
if
(
!
preExisting
)
{
proc
->
user
=
UsersTable_getRef
(
super
->
usersTable
,
proc
->
st_uid
);
proc
->
super
.
user
=
UsersTable_getRef
(
super
->
usersTable
,
proc
->
super
.
st_uid
);
ProcessList_add
(
super
,
proc
);
ProcessList_add
(
super
,
&
proc
->
super
);
}
}
...
...
darwin/DarwinProcessList.h
View file @
907f8298
...
...
@@ -22,6 +22,7 @@ typedef struct DarwinProcessList_ {
processor_cpu_load_info_t
curr_load
;
uint64_t
kernel_threads
;
uint64_t
user_threads
;
uint64_t
global_diff
;
}
DarwinProcessList
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment