⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prgcapi.c

📁 Netscape NSPR库源码
💻 C
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//*  * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * 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 Original Code is the Netscape Portable Runtime (NSPR). *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1998-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#include <stdarg.h>#include <string.h>#include <stdio.h>#include "prenv.h"#include "prmem.h"#include "prmon.h"#include "prlog.h"#include "prthread.h"#if defined(XP_MAC)#include "pprthred.h"#else#include "private/pprthred.h"#endif#include "gcint.h"/*** Generic GC implementation independent code for the NSPR GC*/RootFinder *_pr_rootFinders;CollectorType *_pr_collectorTypes;/* GC State information */GCInfo _pr_gcData;GCBeginGCHook *_pr_beginGCHook;void *_pr_beginGCHookArg;GCBeginGCHook *_pr_endGCHook;void *_pr_endGCHookArg;GCBeginFinalizeHook *_pr_beginFinalizeHook;void *_pr_beginFinalizeHookArg;GCBeginFinalizeHook *_pr_endFinalizeHook;void *_pr_endFinalizeHookArg;FILE *_pr_dump_file;int _pr_do_a_dump;GCLockHook *_pr_GCLockHook;extern PRLogModuleInfo *_pr_msgc_lm;/************************************************************************/static PRStatus PR_CALLBACKpr_ScanOneThread(PRThread* t, void** addr, PRUword count, void* closure){#if defined(XP_MAC)#pragma unused (t, closure)#endif    _pr_gcData.processRootBlock(addr, count);    return PR_SUCCESS;}/*** Scan all of the threads C stack's and registers, looking for "root"** pointers into the GC heap. These are the objects that the GC cannot** move and are considered "live" by the GC. Caller has stopped all of** the threads from running.*/static void PR_CALLBACK ScanThreads(void *arg){    PR_ScanStackPointers(pr_ScanOneThread, arg);}/************************************************************************/PR_IMPLEMENT(GCInfo *) PR_GetGCInfo(void){    return &_pr_gcData;}PR_IMPLEMENT(PRInt32) PR_RegisterType(GCType *t){    CollectorType *ct, *ect;    int rv = -1;    LOCK_GC();    ct = &_pr_collectorTypes[0];    ect = &_pr_collectorTypes[FREE_MEMORY_TYPEIX];    for (; ct < ect; ct++) {	if (ct->flags == 0) {	    ct->gctype = *t;	    ct->flags = _GC_TYPE_BUSY;	    if (0 != ct->gctype.finalize) {		ct->flags |= _GC_TYPE_FINAL;	    }	    if (0 != ct->gctype.getWeakLinkOffset) {		ct->flags |= _GC_TYPE_WEAK;	    }	    rv = ct - &_pr_collectorTypes[0];	    break;	}    }    UNLOCK_GC();    return rv;}PR_IMPLEMENT(PRStatus) PR_RegisterRootFinder(    GCRootFinder f, char *name, void *arg){    RootFinder *rf = PR_NEWZAP(RootFinder);    if (rf) {	    rf->func = f;	    rf->name = name;	    rf->arg = arg;	    LOCK_GC();	    rf->next = _pr_rootFinders;	    _pr_rootFinders = rf;	    UNLOCK_GC();	    return PR_SUCCESS;    }    return PR_FAILURE;}PR_IMPLEMENT(int) PR_RegisterGCLockHook(GCLockHookFunc* f, void *arg){    GCLockHook *rf = 0;    rf = (GCLockHook*) calloc(1, sizeof(GCLockHook));    if (rf) {	rf->func = f;	rf->arg = arg;	LOCK_GC();        /* first dummy node */        if (! _pr_GCLockHook) {          _pr_GCLockHook = (GCLockHook*) calloc(1, sizeof(GCLockHook));          _pr_GCLockHook->next = _pr_GCLockHook;          _pr_GCLockHook->prev = _pr_GCLockHook;        }        rf->next = _pr_GCLockHook;        rf->prev = _pr_GCLockHook->prev;        _pr_GCLockHook->prev->next = rf;        _pr_GCLockHook->prev = rf;	UNLOCK_GC();	return 0;    }    return -1;}/*PR_IMPLEMENT(void) PR_SetGCLockHook(GCLockHook *hook, void *arg){    LOCK_GC();    _pr_GCLockHook = hook;    _pr_GCLockHookArg2 = arg;    UNLOCK_GC();}PR_IMPLEMENT(void) PR_GetGCLockHook(GCLockHook **hook, void **arg){    LOCK_GC();    *hook = _pr_GCLockHook;    *arg = _pr_GCLockHookArg2;    UNLOCK_GC();}*/  PR_IMPLEMENT(void) PR_SetBeginGCHook(GCBeginGCHook *hook, void *arg){    LOCK_GC();    _pr_beginGCHook = hook;    _pr_beginGCHookArg = arg;    UNLOCK_GC();}PR_IMPLEMENT(void) PR_GetBeginGCHook(GCBeginGCHook **hook, void **arg){    LOCK_GC();    *hook = _pr_beginGCHook;    *arg = _pr_beginGCHookArg;    UNLOCK_GC();}PR_IMPLEMENT(void) PR_SetEndGCHook(GCEndGCHook *hook, void *arg){    LOCK_GC();    _pr_endGCHook = hook;    _pr_endGCHookArg = arg;    UNLOCK_GC();}PR_IMPLEMENT(void) PR_GetEndGCHook(GCEndGCHook **hook, void **arg){    LOCK_GC();    *hook = _pr_endGCHook;    *arg = _pr_endGCHookArg;    UNLOCK_GC();}PR_IMPLEMENT(void) PR_SetBeginFinalizeHook(GCBeginFinalizeHook *hook, void *arg){    LOCK_GC();    _pr_beginFinalizeHook = hook;    _pr_beginFinalizeHookArg = arg;    UNLOCK_GC();}PR_IMPLEMENT(void) PR_GetBeginFinalizeHook(GCBeginFinalizeHook **hook,                                            void **arg){    LOCK_GC();    *hook = _pr_beginFinalizeHook;    *arg = _pr_beginFinalizeHookArg;    UNLOCK_GC();}PR_IMPLEMENT(void) PR_SetEndFinalizeHook(GCEndFinalizeHook *hook, void *arg){    LOCK_GC();    _pr_endFinalizeHook = hook;    _pr_endFinalizeHookArg = arg;    UNLOCK_GC();}PR_IMPLEMENT(void) PR_GetEndFinalizeHook(GCEndFinalizeHook **hook, void **arg){    LOCK_GC();    *hook = _pr_endFinalizeHook;    *arg = _pr_endFinalizeHookArg;    UNLOCK_GC();}#ifdef DEBUG#include "prprf.h"#if defined(WIN16)static FILE *tracefile = 0;#endifPR_IMPLEMENT(void) GCTrace(char *fmt, ...){	    va_list ap;    char buf[400];    va_start(ap, fmt);    PR_vsnprintf(buf, sizeof(buf), fmt, ap);    va_end(ap);#if defined(WIN16)    if ( tracefile == 0 )    {        tracefile = fopen( "xxxGCtr", "w" );    }    fprintf(tracefile, "%s\n", buf );    fflush(tracefile);#else    PR_LOG(_pr_msgc_lm, PR_LOG_ALWAYS, ("%s", buf));#endif}#endifvoid _PR_InitGC(PRWord flags){    static char firstTime = 1;    if (!firstTime) return;    firstTime = 0;    _MD_InitGC();    if (flags == 0) {	char *ev = PR_GetEnv("GCLOG");	if (ev && ev[0]) {	    flags = atoi(ev);	}    }    _pr_gcData.flags = flags;    _pr_gcData.lock = PR_NewMonitor();    _pr_collectorTypes = (CollectorType*) PR_CALLOC(256 * sizeof(CollectorType));    PR_RegisterRootFinder(ScanThreads, "scan threads", 0);    PR_RegisterRootFinder(_PR_ScanFinalQueue, "scan final queue", 0);}extern void pr_FinalizeOnExit(void);#ifdef DEBUG#ifdef GC_STATSPR_PUBLIC_API(void) PR_PrintGCAllocStats(void);#endif #endif   PR_IMPLEMENT(void) PR_ShutdownGC(PRBool finalizeOnExit){    /* first finalize all the objects in the heap */    if (finalizeOnExit) {        pr_FinalizeOnExit();    }#ifdef DEBUG#ifdef GC_STATS    PR_PrintGCAllocStats();#endif /* GC_STATS */#endif /* DEBUG */    /* then the chance for any future allocations */    /* finally delete the gc heap */    /* write me */}/******************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -