change array to linked list

This commit is contained in:
Iain
2021-07-23 19:36:29 +08:00
parent 2622ccaafc
commit 05dbd9577c
23 changed files with 702 additions and 192 deletions
+67 -58
View File
@@ -17,53 +17,54 @@
#define STAT_VSZ 22
#define STAT_RSS 23
extern Proc_Info Proc_List[LIMIT_PROCESS_NUMBER];
//Global Process Info Node List
list_t Proc_List;
inline void freeProcInfo(Proc_Info *proc) {
void printProcInfo(Proc_Info *pProcInfo) {
printf("PID:%d,name:%s,point:%d\n", pProcInfo->pid, pProcInfo->name, pProcInfo->point);
int i;
proc->pid = 0;
proc->point = 0;
strcpy(proc->name, "");
printf("cpu:");
for (i = 0; i < UPDATE_FREQUENCY; i++) {
proc->cpuInfo[i].utime = 0;
proc->cpuInfo[i].stime = 0;
proc->memInfo[i].vsz = 0;
proc->memInfo[i].vsz = 0;
printf("s=%ld u=%ld,", pProcInfo->cpuInfo[i].stime, pProcInfo->cpuInfo[i].utime);
}
return;
printf("\n");
printf("mem:");
for (i = 0; i < UPDATE_FREQUENCY; i++) {
printf("vsz=%ld rss=%ld,", pProcInfo->memInfo[i].vsz, pProcInfo->memInfo[i].rss);
}
printf("\n");
}
void freeProcInfoList() {
int i;
for (i = 0; i < LIMIT_PROCESS_NUMBER; i++) {
freeProcInfo(&Proc_List[i]);
}
return;
struct Proc_Info_ *newProcInfo(unsigned int pid, char name[LIMIT_PROCESS_Name_Length]) {
struct Proc_Info_ *proc;
proc = (struct Proc_Info_ *) malloc(sizeof(struct Proc_Info_));
memset(proc, 0, sizeof(struct Proc_Info_));
proc->pid = pid;
strcpy(proc->name, name);
#if defined(LOG)
printf("newProcInfoNode-Create:");
printProcInfo(proc);
#endif
return proc;
}
//not found,return -1
//found,return id
int foundProcNode(unsigned int pid) {
int i;
for (i = 0; i < LIMIT_PROCESS_NUMBER; i++) {
if ((Proc_List + i)->pid == pid) {
return i;
}
list_node_t *node;
list_iterator_t *it = list_iterator_new(&Proc_List, LIST_HEAD);
while ((node = list_iterator_next(it))) {
struct Proc_Info_ *proc_node;
proc_node = (struct Proc_Info_ *) node->val;
if (proc_node->pid == pid) {
return 0;
};
}
return -1;
}
int foundFreeProcNode() {
int i;
i = foundProcNode(0);
if (i == -1) {
perror("No free procInfo node in procList");
}
return i;
}
int setFreeProcNode(unsigned int pid) {
int setProcNode(unsigned int pid) {
//found PID name
char buf[BUFFER_SIZE_PROC_STATUS] = {0};
char PID_name[LIMIT_PROCESS_Name_Length] = {0};
@@ -81,19 +82,16 @@ int setFreeProcNode(unsigned int pid) {
sscanf(buf, "Name: %s", PID_name);
fclose(fp);
//compare PID name with whitelist
//compare PID name with whitelist and regex
//check PID in ProcList
if (foundProcNode(pid) != -1) {
if (foundProcNode(pid) == 0) {
return -1;
}
//found free Proc Node
int i = foundFreeProcNode();
//set Proc Info
Proc_List[i].pid = pid;
strcpy(Proc_List[i].name, PID_name);
struct Proc_Info_ *proc = newProcInfo(pid, PID_name);
list_rpush(&Proc_List, (void *) list_node_new(proc));
return 0;
}
@@ -107,7 +105,7 @@ int monitorProcDirChange() {
perror("scandir /proc");
else {
while (n--) {
printf("%s\n", namelist[n]->d_name);
//printf("%s\n", namelist[n]->d_name);
free(namelist[n]);
}
free(namelist);
@@ -222,36 +220,47 @@ int updateProcInfo(Proc_Info *proc) {
proc->cpuInfo[proc->point].utime = utime;
proc->cpuInfo[proc->point].stime = stime;
proc->memInfo[proc->point].vsz = vsz;
proc->memInfo[proc->point].rss = rss * 4;
proc->memInfo[proc->point].rss = rss * 4 * 1024;
fclose(fd);
return 0;
}
void initProcList() {
list_t *pProc_List = list_new();
Proc_List = *pProc_List;
}
void updateProcList() {
#if defined(LOG)
printf("/****** Proc Info ******/\n");
monitorProcDirChange();
int i;
for (i = 0; i < LIMIT_PROCESS_NUMBER; i++) {
printf("id=%d,", Proc_List[i].pid);
}
printf("\n");
setFreeProcNode(1);
setProcNode(1);
setProcNode(150361);
#endif
char file_path[64] = {0};
int currentProcNode;
for (currentProcNode = 0; currentProcNode < LIMIT_PROCESS_NUMBER; currentProcNode++) {
//check PID
if (Proc_List[currentProcNode].pid != 0) {
if (updateProcInfo(&Proc_List[currentProcNode]) == -1) {
//check path exist
sprintf(file_path, "/proc/%d", Proc_List[currentProcNode].pid);
if (access(file_path, F_OK)) {
freeProcInfo(&Proc_List[currentProcNode]);
}
struct Proc_Info_ *proc_node;
list_node_t *node;
list_iterator_t *it = list_iterator_new(&Proc_List, LIST_HEAD);
while ((node = list_iterator_next(it))) {
proc_node = (struct Proc_Info_ *) node->val;
printProcInfo(proc_node);
if (updateProcInfo(proc_node) == -1) {
//check path exist
sprintf(file_path, "/proc/%d", proc_node->pid);
if (access(file_path, F_OK)) {
list_node_t *node_to_delete = node;
printf("remove proc list node due to cannot access /proc/PID");
node = list_iterator_next(it);
list_remove(&Proc_List, node_to_delete);
free(proc_node);
};
}
};
}
return;
}
+3 -5
View File
@@ -9,6 +9,8 @@
#define LIMIT_PROCESS_NUMBER 64 //max monitor 64 process
#define LIMIT_PROCESS_Name_Length 128
#include "list.h"
//proc/PID/stat
typedef struct Proc_CPU_Time_ {
unsigned long utime; //user time
@@ -29,10 +31,6 @@ typedef struct Proc_Info_ {
Proc_Mem memInfo[UPDATE_FREQUENCY];
} Proc_Info;
void freeProcInfo(Proc_Info *proc);
void freeProcInfoList();
//kill this process
void findProcListByMem();
@@ -41,6 +39,6 @@ void findProcListByCPU();
void updateProcList();
Proc_Info Proc_List[LIMIT_PROCESS_NUMBER]; //max monitor 64 process
void initProcList();
#endif //ATOP_PROCESSINFO_H
+182
View File
@@ -0,0 +1,182 @@
#include "list.h"
/*
* Allocate a new list_t. NULL on failure.
*/
list_t *list_new(void) {
list_t *self;
if (!(self = LIST_MALLOC(sizeof(list_t))))
return NULL;
self->head = NULL;
self->tail = NULL;
self->free = NULL;
self->match = NULL;
self->len = 0;
return self;
}
/*
* Free the list.
*/
void list_destroy(list_t *self) {
unsigned int len = self->len;
list_node_t *next;
list_node_t *curr = self->head;
while (len--) {
next = curr->next;
if (self->free) self->free(curr->val);
LIST_FREE(curr);
curr = next;
}
LIST_FREE(self);
}
/*
* Append the given node to the list
* and return the node, NULL on failure.
*/
list_node_t *list_rpush(list_t *self, list_node_t *node) {
if (!node) return NULL;
if (self->len) {
node->prev = self->tail;
node->next = NULL;
self->tail->next = node;
self->tail = node;
} else {
self->head = self->tail = node;
node->prev = node->next = NULL;
}
++self->len;
return node;
}
/*
* Return / detach the last node in the list, or NULL.
*/
list_node_t *list_rpop(list_t *self) {
if (!self->len) return NULL;
list_node_t *node = self->tail;
if (--self->len) {
(self->tail = node->prev)->next = NULL;
} else {
self->tail = self->head = NULL;
}
node->next = node->prev = NULL;
return node;
}
/*
* Return / detach the first node in the list, or NULL.
*/
list_node_t *list_lpop(list_t *self) {
if (!self->len) return NULL;
list_node_t *node = self->head;
if (--self->len) {
(self->head = node->next)->prev = NULL;
} else {
self->head = self->tail = NULL;
}
node->next = node->prev = NULL;
return node;
}
/*
* Prepend the given node to the list
* and return the node, NULL on failure.
*/
list_node_t *list_lpush(list_t *self, list_node_t *node) {
if (!node) return NULL;
if (self->len) {
node->next = self->head;
node->prev = NULL;
self->head->prev = node;
self->head = node;
} else {
self->head = self->tail = node;
node->prev = node->next = NULL;
}
++self->len;
return node;
}
/*
* Return the node associated to val or NULL.
*/
list_node_t *list_find(list_t *self, void *val) {
list_iterator_t *it = list_iterator_new(self, LIST_HEAD);
list_node_t *node;
while ((node = list_iterator_next(it))) {
if (self->match) {
if (self->match(val, node->val)) {
list_iterator_destroy(it);
return node;
}
} else {
if (val == node->val) {
list_iterator_destroy(it);
return node;
}
}
}
list_iterator_destroy(it);
return NULL;
}
/*
* Return the node at the given index or NULL.
*/
list_node_t *list_at(list_t *self, int index) {
list_direction_t direction = LIST_HEAD;
if (index < 0) {
direction = LIST_TAIL;
index = ~index;
}
if ((unsigned) index < self->len) {
list_iterator_t *it = list_iterator_new(self, direction);
list_node_t *node = list_iterator_next(it);
while (index--) node = list_iterator_next(it);
list_iterator_destroy(it);
return node;
}
return NULL;
}
/*
* Remove the given node from the list, freeing it and it's value.
*/
void list_remove(list_t *self, list_node_t *node) {
node->prev ? (node->prev->next = node->next) : (self->head = node->next);
node->next ? (node->next->prev = node->prev) : (self->tail = node->prev);
if (self->free) self->free(node->val);
LIST_FREE(node);
--self->len;
}
+130
View File
@@ -0,0 +1,130 @@
//
// list.h
//
// Copyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca>
//
#ifndef __CLIBS_LIST_H__
#define __CLIBS_LIST_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
// Library version
#define LIST_VERSION "0.2.0"
// Memory management macros
#ifdef LIST_CONFIG_H
#define _STR(x) #x
#define STR(x) _STR(x)
#include STR(LIST_CONFIG_H)
#undef _STR
#undef STR
#endif
#ifndef LIST_MALLOC
#define LIST_MALLOC malloc
#endif
#ifndef LIST_FREE
#define LIST_FREE free
#endif
/*
* list_t iterator direction.
*/
typedef enum {
LIST_HEAD
, LIST_TAIL
} list_direction_t;
/*
* list_t node struct.
*/
typedef struct list_node {
struct list_node *prev;
struct list_node *next;
void *val;
} list_node_t;
/*
* list_t struct.
*/
typedef struct {
list_node_t *head;
list_node_t *tail;
unsigned int len;
void (*free)(void *val);
int (*match)(void *a, void *b);
} list_t;
/*
* list_t iterator struct.
*/
typedef struct {
list_node_t *next;
list_direction_t direction;
} list_iterator_t;
// Node prototypes.
list_node_t *
list_node_new(void *val);
// list_t prototypes.
list_t *
list_new(void);
list_node_t *
list_rpush(list_t *self, list_node_t *node);
list_node_t *
list_lpush(list_t *self, list_node_t *node);
list_node_t *
list_find(list_t *self, void *val);
list_node_t *
list_at(list_t *self, int index);
list_node_t *
list_rpop(list_t *self);
list_node_t *
list_lpop(list_t *self);
void
list_remove(list_t *self, list_node_t *node);
void
list_destroy(list_t *self);
// list_t iterator prototypes.
list_iterator_t *
list_iterator_new(list_t *list, list_direction_t direction);
list_iterator_t *
list_iterator_new_from_node(list_node_t *node, list_direction_t direction);
list_node_t *
list_iterator_next(list_iterator_t *self);
void
list_iterator_destroy(list_iterator_t *self);
#ifdef __cplusplus
}
#endif
#endif /* __CLIBS_LIST_H__ */
+61
View File
@@ -0,0 +1,61 @@
//
// iterator.c
//
// Copyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca>
//
#include "list.h"
/*
* Allocate a new list_iterator_t. NULL on failure.
* Accepts a direction, which may be LIST_HEAD or LIST_TAIL.
*/
list_iterator_t *
list_iterator_new(list_t *list, list_direction_t direction) {
list_node_t *node = direction == LIST_HEAD
? list->head
: list->tail;
return list_iterator_new_from_node(node, direction);
}
/*
* Allocate a new list_iterator_t with the given start
* node. NULL on failure.
*/
list_iterator_t *
list_iterator_new_from_node(list_node_t *node, list_direction_t direction) {
list_iterator_t *self;
if (!(self = LIST_MALLOC(sizeof(list_iterator_t))))
return NULL;
self->next = node;
self->direction = direction;
return self;
}
/*
* Return the next list_node_t or NULL when no more
* nodes remain in the list.
*/
list_node_t *list_iterator_next(list_iterator_t *self) {
list_node_t *curr = self->next;
if (curr) {
self->next = self->direction == LIST_HEAD
? curr->next
: curr->prev;
}
return curr;
}
/*
* Free the list iterator.
*/
void
list_iterator_destroy(list_iterator_t *self) {
LIST_FREE(self);
self = NULL;
}
+23
View File
@@ -0,0 +1,23 @@
//
// node.c
//
// Copyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca>
//
#include "list.h"
/*
* Allocates a new list_node_t. NULL on failure.
*/
list_node_t *
list_node_new(void *val) {
list_node_t *self;
if (!(self = LIST_MALLOC(sizeof(list_node_t))))
return NULL;
self->prev = NULL;
self->next = NULL;
self->val = val;
return self;
}