aboutsummaryrefslogtreecommitdiffstats
path: root/src/disptime.c
blob: deeee680fe6b64362963c021b5877a2668c33235 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "config2.h"
#include "common.h"
#include "sctcore.h"

#include <stdio.h>
#include <string.h>

#include <pthread.h>
#include <semaphore.h>

void* sctjudge_displaytime(void* arg){
    struct timespec timeinit, timecur, timepast;
    struct timespec timesleep;
    struct timespec timeexpire;

    timesleep.tv_sec = 0;
    timesleep.tv_nsec = (*(long*)arg);

#ifdef HAVE_CONF_PROCMON
    int i;

    pid_t pidcopy;

    const char* sysstatfile = PROC_PATH"/stat";
    char statfile[25], statusfile[25];
    FILE *statp, *statusp, *sysstatp;

    int strlencount, cpuinfostore;
    char firstrun = 1, hdrstore[10];

    unsigned long cpuuser, cpusystem, precpuuser, precpusystem;
    unsigned long syscpuall, presyscpuall, diffsyscpuall;

    unsigned short res_cpuuser, res_cpusystem;
    unsigned long vmsize;
#endif

    pthread_mutex_lock(&tdisplay_mx);
    tdisplay_yes = 1;
    pthread_mutex_unlock(&tdisplay_mx);

    sem_wait(&dispthr);

#ifndef HAVE_CONF_CAP
    enable_setuid();
#endif

    clock_gettime(CLOCK_REALTIME, &timeinit);

#ifdef HAVE_CONF_PROCMON
    pthread_mutex_lock(&pidmutex);
    pidcopy = pidchild;
    pthread_mutex_unlock(&pidmutex);
#endif

#ifdef HAVE_CONF_PROCMON
    sprintf(statfile, PROC_PATH"/%d/stat", pidcopy);
    sprintf(statusfile, PROC_PATH"/%d/status", pidcopy);
#endif

    do{
        clock_gettime(CLOCK_REALTIME, &timecur);
        difftimespec(&timeinit, &timecur, &timepast);
        printf("\r%4ld.%03ld 秒", timepast.tv_sec,
                timepast.tv_nsec / 1000000);
#ifdef HAVE_CONF_PROCMON
        statp = fopen(statfile, "r");
        statusp = fopen(statusfile, "r");
        sysstatp = fopen(sysstatfile, "r");
        if(statp != NULL && statusp != NULL && sysstatp != NULL){
            strlencount = 0;
            while(getc(statusp) != '\n'){
                strlencount++;
            }
            strlencount -= 8; /* 把前面的「Name:   」這 8 個字去掉 */
            /* 接下來從 /proc/[PID]/stat 取得 CPU 時間 */
            fscanf(statp, "%*d"); /* 讀掉 PID */
            while(getc(statp) != '('); /* 讀掉 command name 的左括弧 */
            for(i=1; i<= strlencount; i++){ /* 讀掉整個 command name */
                getc(statp);
            }
            while(getc(statp) != ')'); /* 讀掉 command name 的右括弧 */
            fscanf(statp, "%*s %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u"
                    "%lu %lu %*d %*d %*d %*d %*d %*d %*u %lu", 
                    &cpuuser, &cpusystem, &vmsize);
            syscpuall = 0;
            while(!feof(sysstatp)){
                fscanf(sysstatp, "%9s", hdrstore);
                if(!strcmp(hdrstore, "cpu")){
                    while(fscanf(sysstatp, "%d", &cpuinfostore) == 1){
                        syscpuall += cpuinfostore;
                    }
                    break;
                }else{
                    while(getchar() != '\n');
                }
            }
            if(!firstrun){
                diffsyscpuall = syscpuall - presyscpuall;
                if(diffsyscpuall){
                    res_cpuuser = 1000 * (cpuuser - precpuuser) / 
                        diffsyscpuall;
                    res_cpusystem = 1000 * (cpusystem - precpusystem) / 
                        diffsyscpuall;
                    printf("  user%%: %2hd.%hd  sys%%: %2hd.%hd",
                        res_cpuuser / 10, res_cpuuser % 10,
                        res_cpusystem / 10, res_cpusystem % 10);
                }else{
                    fputs("  user%: ?     sys%: ?   ", stdout);
                }
            }else{
                fputs("  user%: ?     sys%: ?   ", stdout);
            }
            precpuuser = cpuuser;
            precpusystem = cpusystem;
            presyscpuall = syscpuall;
            printf("  VM: %lu KiB", vmsize / 1024);
            fputs("                    ", stdout);
        }
        if(statp != NULL){
            fclose(statp);
        }
        if(statusp != NULL){
            fclose(statusp);
        }
        if(sysstatp != NULL){
            fclose(sysstatp);
        }
        firstrun = 0;
#endif
        fflush(stdout);

        clock_gettime(CLOCK_REALTIME, &timecur);
        timeexpire.tv_sec = timecur.tv_sec + timesleep.tv_sec;
        timeexpire.tv_nsec = timecur.tv_nsec + timesleep.tv_nsec;
        checktimespec(&timeexpire);
    }while(sem_timedwait(&dispthr, &timeexpire));

    pthread_mutex_lock(&tdisplay_mx);
    tdisplay_yes = 0;
    pthread_mutex_unlock(&tdisplay_mx);

    return NULL;
}