CUBRID Engine  latest
broker_process_size.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 
20 /*
21  * broker_process_size.c - Get process size
22  * Solaris, HPUX - by system call
23  * others - by 'ps' cmd (popen)
24  * return values
25  * > 1 success
26  * 1 cannot get process information
27  * <= 0 no such process
28  */
29 
30 #ident "$Id$"
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <errno.h>
35 
36 #if !defined(WINDOWS)
37 #include <unistd.h>
38 #else
39 #include <winsock2.h>
40 #include <windows.h>
41 #include <process.h>
42 #include <pdh.h>
43 #include <pdhmsg.h>
44 #include <io.h>
45 #endif
46 
47 #if defined(SOLARIS)
48 #include <fcntl.h>
49 #include <sys/procfs.h>
50 #elif defined(HPUX)
51 #include <sys/pstat.h>
52 #elif defined(AIX)
53 #include <procinfo.h>
54 #elif defined(UNIXWARE7)
55 #include <sys/procfs.h>
56 #include <fcntl.h>
57 #elif defined(LINUX) || defined(ALPHA_LINUX)
58 #include <ctype.h>
59 #include <fcntl.h>
60 #include <string.h>
61 #include <sys/procfs.h>
62 #elif defined(OSF1)
63 #include <fcntl.h>
64 #include <sys/procfs.h>
65 #endif
66 
67 #include "cas_common.h"
68 #include "broker_process_size.h"
69 
70 #if defined(HPUX)
71 #include "hp_pstat.h"
72 #endif
73 
74 #define GETSIZE_PATH "getsize"
75 
76 #if defined(LINUX) || defined(ALPHA_LINUX)
77 static char *skip_token (char *p);
78 #endif
79 
80 #if defined(WINDOWS)
81 #define IS_COUNTER_VALUE_PTR_NULL() \
82  (cntvalue_pid == NULL || cntvalue_workset == NULL || \
83  cntvalue_pct_cpu == NULL || cntvalue_num_thr == NULL)
84 
85 static void alloc_counter_value ();
86 
87 typedef PDH_STATUS (__stdcall * PDHOpenQuery) (LPCSTR, DWORD_PTR, PDH_HQUERY *);
88 typedef PDH_STATUS (__stdcall * PDHCloseQuery) (PDH_HQUERY);
89 typedef PDH_STATUS (__stdcall * PDHAddCounter) (PDH_HQUERY, LPCSTR, DWORD_PTR, PDH_HCOUNTER *);
90 typedef PDH_STATUS (__stdcall * PDHCollectQueryData) (PDH_HQUERY);
91 typedef PDH_STATUS (__stdcall * PDHGetFormattedCounterArray) (PDH_HCOUNTER, DWORD, LPDWORD, LPDWORD,
92  PPDH_FMT_COUNTERVALUE_ITEM_A);
93 PDHOpenQuery fp_PdhOpenQuery;
94 PDHCloseQuery fp_PdhCloseQuery;
95 PDHAddCounter fp_PdhAddCounter;
96 PDHCollectQueryData fp_PdhCollectQueryData;
97 PDHGetFormattedCounterArray fp_PdhGetFormattedCounterArray;
98 
99 HCOUNTER counter_pid;
100 HCOUNTER counter_pct_cpu;
101 HCOUNTER counter_workset;
102 HCOUNTER counter_num_thr;
103 PDH_FMT_COUNTERVALUE_ITEM *cntvalue_pid = NULL;
104 PDH_FMT_COUNTERVALUE_ITEM *cntvalue_pct_cpu = NULL;
105 PDH_FMT_COUNTERVALUE_ITEM *cntvalue_workset = NULL;
106 PDH_FMT_COUNTERVALUE_ITEM *cntvalue_num_thr = NULL;
107 HQUERY pdh_h_query;
108 int num_counter_value;
109 unsigned long pdh_num_proc;
110 #endif
111 
112 
113 #if defined(SOLARIS)
114 int
115 getsize (int pid)
116 {
117  int procfd;
118  struct prpsinfo info;
119  const char *procdir = "/proc";
120  char pname[128];
121 
122  if (pid <= 0)
123  {
124  return -1;
125  }
126 
127  sprintf (pname, "%s/%05d", procdir, pid);
128 
129 retry:
130  if ((procfd = open (pname, O_RDONLY)) == -1)
131  {
132  return -1;
133  }
134 
135  if (ioctl (procfd, PIOCPSINFO, (char *) &info) == -1)
136  {
137  int saverr = errno;
138 
139  close (procfd);
140  if (saverr == EAGAIN)
141  {
142  goto retry;
143  }
144  if (saverr != ENOENT)
145  {
146  ;
147  }
148  return 1;
149  }
150 
151  close (procfd);
152 
153  return (int) (info.pr_bysize / 1024);
154 }
155 #elif defined(HPUX)
156 int
157 getsize (int pid)
158 {
159  int page_size = sysconf (_SC_PAGESIZE);
160  INT64 psize;
161  struct pst_status info;
162 
163  if (pid <= 0)
164  {
165  return -1;
166  }
167 
168  if (HP_PSTAT_GETPROC (&info, pid) < 0)
169  {
170  if (errno == ESRCH)
171  {
172  return -1;
173  }
174  return 1;
175  }
176 
177  psize = info.pst_vdsize + info.pst_vtsize + info.pst_vssize;
178  psize *= (page_size / 1024); /* psize by kilobyte */
179  return (int) (psize);
180 }
181 #elif defined(AIX)
182 int
183 getsize (int pid)
184 {
185  struct procentry64 entry;
186  int page_size = sysconf (_SC_PAGESIZE);
187  pid_t tmp_pid = pid;
188 
189  if (pid <= 0)
190  {
191  return -1;
192  }
193 
194  if (getprocs64 (&entry, sizeof (entry), NULL, 0, &tmp_pid, 1) < 0)
195  {
196  if (kill (pid, 0) < 0)
197  {
198  if (errno == ESRCH)
199  {
200  return -1;
201  }
202  }
203  return 1;
204  }
205  if (entry.pi_pid != pid)
206  {
207  return -1;
208  }
209 
210  return (int) (((INT64) entry.pi_dvm) * ((INT64) page_size) / 1024);
211 }
212 #elif defined(UNIXWARE7)
213 int
214 getsize (int pid)
215 {
216  char proc_file[128];
217  psinfo_t pinfo;
218  int read_len;
219  int fd;
220  int page_size = sysconf (_SC_PAGESIZE);
221 
222  if (pid <= 0)
223  {
224  return -1;
225  }
226 
227  sprintf (proc_file, "/proc/%d/psinfo", pid);
228  fd = open (proc_file, O_RDONLY);
229  if (fd < 0)
230  {
231  return -1;
232  }
233 
234  read_len = read (fd, &pinfo, sizeof (pinfo));
235  close (fd);
236  if (read_len < sizeof (pinfo))
237  {
238  return 8;
239  }
240  if (pinfo.pr_size <= 0)
241  {
242  pinfo.pr_size = 2;
243  }
244 
245  return (int) (((INT64) pinfo.pr_size) * ((INT64) page_size) / 1024);
246 }
247 #elif defined(LINUX) || defined(ALPHA_LINUX)
248 int
249 getsize (int pid)
250 {
251  char buf[4096];
252  char *p;
253  int fd;
254  int read_len, i;
255  INT64 psize;
256 
257  if (pid <= 0)
258  {
259  return -1;
260  }
261 
262  sprintf (buf, "/proc/%d/stat", pid);
263  fd = open (buf, O_RDONLY);
264  if (fd < 0)
265  {
266  return -1;
267  }
268 
269  read_len = read (fd, buf, sizeof (buf) - 1);
270  close (fd);
271 
272  if (read_len < 0 || read_len >= (int) sizeof (buf))
273  {
274  return 1;
275  }
276  buf[read_len] = '\0';
277 
278  p = strchr (buf, ')');
279  p++;
280  for (i = 0; i < 20; i++)
281  {
282  p = skip_token (p);
283  }
284 
285  psize = atoll (p);
286  return (int) (psize / 1024);
287 }
288 
289 static char *
290 skip_token (char *p)
291 {
292  while (isspace (*p))
293  p++;
294  while (*p && !isspace (*p))
295  p++;
296  return p;
297 }
298 #elif defined(OSF1)
299 int
300 getsize (int pid)
301 {
302  int page_size = sysconf (_SC_PAGESIZE);
303  int procfd;
304  struct prpsinfo info;
305  const char *procdir = "/proc";
306  char pname[128];
307 
308  if (pid <= 0)
309  {
310  return -1;
311  }
312 
313  sprintf (pname, "%s/%05d", procdir, pid);
314 
315 retry:
316  if ((procfd = open (pname, O_RDONLY)) == -1)
317  {
318  return -1;
319  }
320 
321  if (ioctl (procfd, PIOCPSINFO, (char *) &info) == -1)
322  {
323  int saverr = errno;
324 
325  close (procfd);
326  if (saverr == EAGAIN)
327  {
328  goto retry;
329  }
330  if (saverr != ENOENT)
331  {
332  ;
333  }
334  return 1;
335  }
336 
337  close (procfd);
338 
339  return (int) (((INT64) info.pr_size) * ((INT64) page_size) / 1024);
340 }
341 #elif defined(WINDOWS)
342 static void
343 alloc_counter_value ()
344 {
345  PDH_FMT_COUNTERVALUE_ITEM *tmp_pid = NULL;
346  PDH_FMT_COUNTERVALUE_ITEM *tmp_cpu = NULL;
347  PDH_FMT_COUNTERVALUE_ITEM *tmp_workset = NULL;
348  PDH_FMT_COUNTERVALUE_ITEM *tmp_num_thr = NULL;
349 
350  int _mem_size = sizeof (PDH_FMT_COUNTERVALUE_ITEM) * num_counter_value;
351  tmp_pid = (PDH_FMT_COUNTERVALUE_ITEM *) realloc (cntvalue_pid, _mem_size);
352  if (tmp_pid == NULL)
353  {
354  cntvalue_pid = NULL;
355  }
356  else
357  {
358  cntvalue_pid = tmp_pid;
359  }
360 
361  tmp_workset = (PDH_FMT_COUNTERVALUE_ITEM *) realloc (cntvalue_workset, _mem_size);
362  if (tmp_workset == NULL)
363  {
364  cntvalue_workset = NULL;
365  }
366  else
367  {
368  cntvalue_workset = tmp_workset;
369  }
370 
371  tmp_cpu = (PDH_FMT_COUNTERVALUE_ITEM *) realloc (cntvalue_pct_cpu, _mem_size);
372  if (tmp_cpu == NULL)
373  {
374  cntvalue_pct_cpu = NULL;
375  }
376  else
377  {
378  cntvalue_pct_cpu = tmp_cpu;
379  }
380 
381  tmp_num_thr = (PDH_FMT_COUNTERVALUE_ITEM *) realloc (cntvalue_num_thr, _mem_size);
382  if (tmp_num_thr == NULL)
383  {
384  cntvalue_num_thr = NULL;
385  }
386  else
387  {
388  cntvalue_num_thr = tmp_num_thr;
389  }
390 }
391 
392 int
393 getsize (int pid)
394 {
395  return 1;
396 }
397 
398 int
399 pdh_get_value (int pid, int *workset, float *pct_cpu, int *br_num_thr)
400 {
401  unsigned long i;
402 
403  if (pid <= 0)
404  {
405  *workset = 0;
406  *pct_cpu = 0;
407  if (br_num_thr)
408  {
409  *br_num_thr = 0;
410  }
411  return 0;
412  }
413 
414  for (i = 0; i < pdh_num_proc; i++)
415  {
416  if (cntvalue_pid[i].FmtValue.longValue == pid)
417  {
418  *workset = (int) (cntvalue_workset[i].FmtValue.largeValue / 1024);
419  *pct_cpu = (float) (cntvalue_pct_cpu[i].FmtValue.doubleValue);
420  if (br_num_thr)
421  {
422  *br_num_thr = (int) (cntvalue_num_thr[i].FmtValue.largeValue);
423  }
424  return 0;
425  }
426  }
427 
428  return -1;
429 }
430 
431 int
432 pdh_init ()
433 {
434  HMODULE h_module;
435  PDH_STATUS pdh_status;
436  CHAR path_buffer[128];
437 
438  h_module = LoadLibrary ("pdh.dll");
439  if (h_module == NULL)
440  {
441  return -1;
442  }
443 
444  fp_PdhOpenQuery = (PDHOpenQuery) GetProcAddress (h_module, "PdhOpenQueryA");
445  if (fp_PdhOpenQuery == NULL)
446  {
447  return -1;
448  }
449 
450  fp_PdhAddCounter = (PDHAddCounter) GetProcAddress (h_module, "PdhAddCounterA");
451  if (fp_PdhAddCounter == NULL)
452  {
453  return -1;
454  }
455 
456  fp_PdhCollectQueryData = (PDHCollectQueryData) GetProcAddress (h_module, "PdhCollectQueryData");
457  if (fp_PdhCollectQueryData == NULL)
458  {
459  return -1;
460  }
461 
462  fp_PdhGetFormattedCounterArray =
463  (PDHGetFormattedCounterArray) GetProcAddress (h_module, "PdhGetFormattedCounterArrayA");
464  if (fp_PdhGetFormattedCounterArray == NULL)
465  {
466  return -1;
467  }
468 
469  fp_PdhCloseQuery = (PDHCloseQuery) GetProcAddress (h_module, "PdhCloseQuery");
470  if (fp_PdhCloseQuery == NULL)
471  {
472  return -1;
473  }
474 
475  pdh_status = (*fp_PdhOpenQuery) (0, 0, &pdh_h_query);
476  if (pdh_status != ERROR_SUCCESS)
477  {
478  return -1;
479  }
480 
481  strcpy (path_buffer, "\\Process(*)\\ID Process");
482  pdh_status = (*fp_PdhAddCounter) (pdh_h_query, path_buffer, 0, &counter_pid);
483  if (pdh_status != ERROR_SUCCESS)
484  {
485  return -1;
486  }
487 
488  strcpy (path_buffer, "\\Process(*)\\Working Set");
489  pdh_status = (*fp_PdhAddCounter) (pdh_h_query, path_buffer, 0, &counter_workset);
490  if (pdh_status != ERROR_SUCCESS)
491  {
492  return -1;
493  }
494 
495  strcpy (path_buffer, "\\Process(*)\\% Processor Time");
496  pdh_status = (*fp_PdhAddCounter) (pdh_h_query, path_buffer, 0, &counter_pct_cpu);
497  if (pdh_status != ERROR_SUCCESS)
498  {
499  return -1;
500  }
501 
502  strcpy (path_buffer, "\\Process(*)\\Thread Count");
503  pdh_status = (*fp_PdhAddCounter) (pdh_h_query, path_buffer, 0, &counter_num_thr);
504  if (pdh_status != ERROR_SUCCESS)
505  {
506  return -1;
507  }
508 
509  num_counter_value = 128;
510 
511  alloc_counter_value ();
512  if (IS_COUNTER_VALUE_PTR_NULL ())
513  {
514  return -1;
515  }
516  memset (cntvalue_pid, 0, sizeof (PDH_FMT_COUNTERVALUE_ITEM) * num_counter_value);
517  memset (cntvalue_workset, 0, sizeof (PDH_FMT_COUNTERVALUE_ITEM) * num_counter_value);
518  memset (cntvalue_pct_cpu, 0, sizeof (PDH_FMT_COUNTERVALUE_ITEM) * num_counter_value);
519  memset (cntvalue_num_thr, 0, sizeof (PDH_FMT_COUNTERVALUE_ITEM) * num_counter_value);
520 
521  return 0;
522 }
523 
524 int
525 pdh_collect ()
526 {
527  unsigned long in_size;
528  PDH_STATUS pdh_status;
529  int i, retry_count = 10;
530  char success_flag = FALSE;
531 
532  if (IS_COUNTER_VALUE_PTR_NULL ())
533  {
534  alloc_counter_value ();
535  if (IS_COUNTER_VALUE_PTR_NULL ())
536  goto collect_error;
537  }
538 
539  for (i = 0; i < retry_count; i++)
540  {
541  pdh_status = (*fp_PdhCollectQueryData) (pdh_h_query);
542  if (pdh_status != ERROR_SUCCESS)
543  {
544  continue;
545  }
546  in_size = sizeof (PDH_FMT_COUNTERVALUE_ITEM) * num_counter_value;
547 
548  pdh_status = (*fp_PdhGetFormattedCounterArray) (counter_pid, PDH_FMT_LONG, &in_size, &pdh_num_proc, cntvalue_pid);
549  if (pdh_status != ERROR_SUCCESS)
550  {
551  if (pdh_status == PDH_MORE_DATA)
552  {
553  num_counter_value *= 2;
554  alloc_counter_value ();
555  if (IS_COUNTER_VALUE_PTR_NULL ())
556  {
557  goto collect_error;
558  }
559  }
560  continue;
561  }
562  pdh_status =
563  (*fp_PdhGetFormattedCounterArray) (counter_workset, PDH_FMT_LARGE, &in_size, &pdh_num_proc, cntvalue_workset);
564  if (pdh_status != ERROR_SUCCESS)
565  {
566  continue;
567  }
568  pdh_status =
569  (*fp_PdhGetFormattedCounterArray) (counter_pct_cpu, PDH_FMT_DOUBLE, &in_size, &pdh_num_proc, cntvalue_pct_cpu);
570  if (pdh_status != ERROR_SUCCESS)
571  {
572  continue;
573  }
574  pdh_status =
575  (*fp_PdhGetFormattedCounterArray) (counter_num_thr, PDH_FMT_LONG, &in_size, &pdh_num_proc, cntvalue_num_thr);
576  if (pdh_status != ERROR_SUCCESS)
577  {
578  continue;
579  }
580 
581  success_flag = TRUE;
582  break;
583  }
584 
585  if (success_flag == TRUE)
586  {
587  return 0;
588  }
589 
590 collect_error:
591  pdh_num_proc = 0;
592  return -1;
593 }
594 #else
595 int
596 getsize (int pid)
597 {
598  FILE *pp;
599  char cmd[256];
600  char buf[256];
601  int i, c;
602  INT64 psize;
603 
604  if (pid <= 0)
605  {
606  return -1;
607  }
608 
609  sprintf (cmd, "%s %d", GETSIZE_PATH, pid);
610  pp = popen (cmd, "r");
611  if (pp == NULL)
612  {
613  return -1;
614  }
615  i = 0;
616  while ((c = getc (pp)) != EOF)
617  {
618  buf[i++] = c;
619  }
620  buf[i] = '\0';
621  pclose (pp);
622  psize = atoll (buf);
623 
624  if (psize <= 0)
625  {
626  if (kill (pid, 0) < 0)
627  {
628  if (errno == ESRCH)
629  {
630  return -1;
631  }
632  }
633  return 1;
634  }
635 
636  return (int) psize;
637 }
638 #endif
int page_size
Definition: unloaddb.c:52
#define TRUE
Definition: broker_admin.c:49
#define GETSIZE_PATH
#define NULL
Definition: freelistheap.h:34
pid_t pid
Definition: dynamic_load.c:955
#define FALSE
Definition: broker_admin.c:50
int i
Definition: dynamic_load.c:954
int getsize(int pid)
const char ** p
Definition: dynamic_load.c:945