reclaim.c
来自「OTP是开放电信平台的简称」· C语言 代码 · 共 551 行 · 第 1/2 页
C
551 行
/* ``The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved via the world wide web at http://www.erlang.org/. * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' * * $Id$ */#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vxWorks.h>#include <version.h>#include <string.h>#include <types.h>#include <sigLib.h>#include <ioLib.h>#include <iosLib.h>#include <fioLib.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <symLib.h>#include <sysLib.h>#include <sysSymTbl.h>#include <loadLib.h>#include <taskLib.h>#include <taskVarLib.h>#include <taskHookLib.h>#include <tickLib.h>#include <time.h>#include <rngLib.h>#include <semLib.h>#include <selectLib.h>#include <sockLib.h>#include <a_out.h>#include <wdLib.h>#include <timers.h>#include <ctype.h>#include <sys/stat.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/tcp.h>#include <stdarg.h>#include <stdio.h>#include <math.h>#include <limits.h>#include <stdlib.h>#include <string.h>#define RECLAIM_NO_ALIAS /* No #defines for open/malloc/fopen etc */#include "reclaim.h"#include "reclaim_private.h"#undef open#undef creat#undef socket#undef accept#undef close#undef fopen#undef fdopen#undef freopen#undef fclose/* XXX Should do opendir/closedir too... */#undef malloc#undef calloc#undef realloc#undef free#undef cfree#ifdef _ARCH_PPC #define MAX_FILES_SYM_NAME "maxFiles"#else#define MAX_FILES_SYM_NAME "_maxFiles"#endif/* * Use another free() function upon task deletion? * Note! When changing free function, the new free function will have to * be able to cope with ALL previously used malloced areas, that is * it has to be able to find out how things are malloced * to free them in the right way! */static FreeFunction reclaim_free_function = NULL;/* delete hook handling (see below) */static int hook_added = 0; /* Initated at first reclaim_init, an extra non MT-safe check that we only get initialized once *//* Forward... */static void save_reclaim(WIND_TCB *tcbp);struct mall_data { struct mall_data *next; char *self;};struct task_data { FUNCPTR version; /* To recognize when we have reloaded */ int max_files; /* It may change... */ struct fd_set open_fds; struct mall_data *mall_data; FUNCPTR delete_hook; caddr_t hook_data; FILE *open_fps[1]; /* Will be max_files long */} *task_data = NULL;static int max_files = 50; /* default configAll.h */int reclaim_max_files(void){ return max_files;}#ifdef DEBUG#define check_hook() \((task_data != NULL || \ fdprintf(2,"check_hook() TID = 0x%08x, Called from line %d\n", \ (unsigned int)taskIdSelf(),\ __LINE__)) && \(task_data != NULL || \ (taskVarAdd(0, (int *)&task_data) == OK && \ (task_data = (struct task_data *)\ calloc(1, sizeof(struct task_data) + max_files*sizeof(FILE *))) != NULL && \ (task_data->version = (FUNCPTR)save_reclaim) != NULL && \ (task_data->max_files = max_files) != 0 && \ fdprintf(2,"taskVar Added for 0x%08x\n",(unsigned int)taskIdSelf()))))#else#define check_hook() \(task_data != NULL || \ (taskVarAdd(0, (int *)&task_data) == OK && \ (task_data = (struct task_data *)\ calloc(1, sizeof(struct task_data) + max_files*sizeof(FILE *))) != NULL && \ (task_data->version = (FUNCPTR)save_reclaim) != NULL && \ (task_data->max_files = max_files) != 0))#endif/* * Global initialization of the reclaim data structures, mainly * the max_files variable. This HAS to be called by some task before * the first task that utilizes this exit's, preferrably before any * task makes the first use of this library. */STATUS reclaim_init(void){ int *mp; SYM_TYPE type; struct task_data *tdp; int i; if (!hook_added) { /* race condition */ ++hook_added; /* Try to find the maxFiles value */ if (symFindByNameAndType(sysSymTbl, MAX_FILES_SYM_NAME, (char **)&mp, &type, N_EXT | N_BSS, N_EXT | N_BSS) == OK || symFindByNameAndType(sysSymTbl, MAX_FILES_SYM_NAME, (char **)&mp, &type, N_EXT | N_DATA, N_EXT | N_DATA) == OK) {#ifdef DEBUG fdprintf(2, "Found maxFiles=%d\n", *mp);#endif if (*mp <= FD_SETSIZE) max_files = *mp; else max_files = FD_SETSIZE; } if (task_data != NULL && task_data->max_files != max_files) { /* fix our own iff we have one */ if ((tdp = (struct task_data *) realloc(task_data, sizeof(struct task_data) + max_files*sizeof(FILE *))) != NULL) { task_data = tdp; for (i = task_data->max_files; i < max_files; i++) task_data->open_fps[i] = NULL; task_data->max_files = max_files; } } /* Make sure taskVariables are deleted AFTER our hook is run. */ taskVarInit(); if(taskDeleteHookAdd((FUNCPTR)save_reclaim) != OK) { fprintf(stderr, "Panic: taskDeleteHook cannot be added for reclaim.\n"); return ERROR; } return OK; } else return ERROR;}/* N.B.!! We do *not* execute in the context of the dying task here, but rather that of tExcTask - we do get a pointer to the task's TCB though - this pointer is in fact also the task's ID. */static void save_reclaim(WIND_TCB *tcbp){ int i, var, oldfd; struct task_data *tdp; struct mall_data *mdp, *mdnextp; if ((var = taskVarGet((int)tcbp, (int *)&task_data)) != ERROR && var != 0) { tdp = (struct task_data *)var; if (tdp->version == (FUNCPTR)save_reclaim) { /* Only handle our own */#ifdef DEBUG fdprintf(2, "Reclaiming for task id 0x%x:\nFiles: ", (int)tcbp);#endif /* Ugh! VxWorks doesn't even flush stdout/err - we need to get at those (which are task-private of course, i.e. we can't just do fflush(stdout) here) - we could be really pedantic and try to redefine stdout/err (which "are" function calls) too, snarfing the values when they are used - but besides the overhead this is problematic since they are actually #defines already... We'll peek in the TCB instead (no documentation of course). And of course, we must also meddle with the *file descriptor* indirections, or we'll just flush out on tExcTask's descriptors... */ for (i = 1; i <= 2; i++) { if (tcbp->taskStdFp[i] != NULL) {#ifdef DEBUG fdprintf(2, "fflush(%s) ", i == 1 ? "stdout" : "stderr");#endif oldfd = ioTaskStdGet(0, i); ioTaskStdSet(0, i, tcbp->taskStd[i]); fflush(tcbp->taskStdFp[i]); ioTaskStdSet(0, i, oldfd); } } for (i = 3; i < tdp->max_files; i++) { if (FD_ISSET(i, &tdp->open_fds)) {#ifdef DEBUG fdprintf(2, "close(%d) ", i);#endif (void) close(i); } if (tdp->open_fps[i] != NULL) {#ifdef DEBUG fdprintf(2, "fclose(%0x%x) ", (int)tdp->open_fps[i]);#endif (void) fclose(tdp->open_fps[i]); } } i = 0; mdp = tdp->mall_data; while (mdp != NULL) { mdnextp = mdp->next; if(reclaim_free_function != NULL) (*reclaim_free_function)(mdp->self); else free(mdp->self); i++; mdp = mdnextp; }#ifdef DEBUG fdprintf(2, "\nFreeing memory: total %d mallocs\n", i);#endif if (tdp->delete_hook != NULL) {#ifdef DEBUG fdprintf(2, "Calling delete hook at 0x%08x\n", tdp->delete_hook);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?