📄 garbage_linux.c
字号:
* * Comes from task_struct in linux/sched.h */typedef struct { int pid; /* process id */ char *cmd, /* command line string vector for /proc/<pid>/cmdline */ state; /* single-char code for process state [R, S, D, Z, or T] */ int ppid, /* pid of parent process */ pgrp, /* process group id */ session, /* session id */ tty, /* full device number of controlling terminal */ tpgid; /* terminal process group id */ unsigned long flags, /* kernel flags for the process */ min_flt, /* number of minor page faults since process start */ cmin_flt, /* cumulative min_flt of process and child processes */ maj_flt, /* number of major page faults since process start */ cmaj_flt, /* cumulative maj_flt of process and child processes */ utime, /* user-mode CPU time accumulated by process */ stime; /* kernel-mode CPU time accumulated by process */ long cutime, /* cumulative utime of process and reaped children */ cstime, /* cumulative stime of process and reaped children */ priority, /* kernel scheduling priority */ nice, /* standard unix nice level of process */ timeout, /* ? */ it_real_value; /* ? */ unsigned long start_time, /* start time of process -- seconds since 1-1-70 */ vsize; /* number of pages of virtual memory ... */ long rss; /* resident set size from /proc/<pid>/stat (pages) */ unsigned long rss_rlim, /* resident set size limit? */ start_code, /* address of beginning of code segment */ end_code, /* address of end of code segment */ start_stack, /* address of the bottom of stack for the process */ kstk_esp, /* kernel stack pointer */ kstk_eip; /* kernel instruction pointer */ char /* Linux 2.1.7x and up have more signals. This handles 88. */ /* long long (instead of char xxxxxx[24]) handles 64 */ signal[24], /* mask of pending signals */ blocked[24], /* mask of blocked signals */ sigignore[24], /* mask of ignored signals */ sigcatch[24]; /* mask of caught signals */ unsigned long wchan, /* address of kernel wait channel proc is sleeping in */ nswap, /* ? */ cnswap; /* cumulative nswap ? */ int exit_signal, processor;} proc_t;#ifdef PKCS64BOOL IsValidProcessEntry ( pid_t_64 pid, time_t_64 RegTime );#elseBOOL IsValidProcessEntry ( pid_t pid, time_t RegTime );#endifint Stat2Proc ( int pid, proc_t *p );#if AIXstatic pthread_t GCThread; /* Garbage Collection thread's handle */#else pthread_t GCThread; /* Garbage Collection thread's handle */#endifstatic BOOL ThreadRunning = FALSE; /* If we're already running or not */#if THREADEDstatic void *GCMain ( void *Ptr );static void GCCancel ( void *Ptr );#elsevoid *GCMain ( void *Ptr );void GCCancel ( void *Ptr );#endif/********************************************************************************* * StartGCThread - * * Entry point that starts the garbage collection thread * *********************************************************************************/BOOL StartGCThread ( Slot_Mgr_Shr_t *MemPtr ) { int err; pthread_attr_t attr;#if !(THREADED) return TRUE;#endif if ( ThreadRunning ) { DbgLog (DL0, "StartGCThread: Thread already running."); return FALSE; } if ( ( err = pthread_create( &GCThread, NULL, GCMain, ((void *)MemPtr) ) ) != 0 ) { DbgLog(DL0,"StartGCThread: pthread_create returned %s (%d; %#x)", SysConst(err), err, err ); return FALSE; } ThreadRunning = TRUE;#ifdef DEV // Only development builds LogLog ( "StartGCThread: garbage collection thread started as ID %d (%#x) by ID %d (%#x)", GCThread, GCThread, pthread_self(), pthread_self() );#endif return TRUE; }/********************************************************************************* * StopGCThread - * * Entry point which causes the Garbage collection thread to terminate * Waits for the thread to terminate before continuing * *********************************************************************************/ BOOL StopGCThread ( void *Ptr ) { int err; Slot_Mgr_Shr_t *MemPtr = (Slot_Mgr_Shr_t *) Ptr; void *Status;#if !(THREADED) return TRUE;#endif if ( ! ThreadRunning ) { DbgLog(DL0,"StopGCThread was called when the garbage collection thread was not running"); return FALSE; } DbgLog(DL0, "StopGCThread: tid %d is stopping the garbage collection thread (tid %d)", pthread_self(), GCThread); /* Cause the GC thread to be cancelled */ if ( ( err = pthread_cancel(GCThread)) != 0 ) { DbgLog(DL0,"StopGCThread: pthread_cancel returned %s (%d; %#x)", SysConst(err), err, err ); return FALSE; } /* Synchronize with the GC thread (aka: wait for it to terminate) */ if ( (err = pthread_join ( GCThread, &Status ) ) != 0 ) { DbgLog(DL0,"StopGCThread: pthread_join returned %s (%d; %#x)", SysConst(err), err, err ); return FALSE; } if ( Status != PTHREAD_CANCELED ) { DbgLog(DL0,"Hmm. Thread was cancelled, but didn't return the appropriate return status"); } ThreadRunning = FALSE; return TRUE;}/********************************************************************************* * GCMain - * * The Garbage collection thread's main() * Basically, run until cancelled by another thread * *********************************************************************************/void *GCMain ( void *Ptr) { int OrigCancelState; int OrigCancelType; int LastCancelState; int i; Slot_Mgr_Shr_t *MemPtr = (Slot_Mgr_Shr_t *) Ptr; ASSERT ( MemPtr != NULL ); sleep(2); // SAB Linux likes to have us delay// Linux threading model appears to have some issues with regards to// signals.... Need to look at this FIXME.. /* setup */ /* Block the signals that go to the main thread */ /* FIXME: We probably want to make it so that signals go only to the main thread by default */// SBADE .... FIXME... remove the blocking of signals see what happens..// GCBlockSignals(); /* Make it so that we can only be cancelled when we reach a cancellation point */ /* cancellation points are listed here: http://techlib.austin.ibm.com/techlib/manuals/adoclib/aixprggd/genprogc/termthre.htm#D3A4499176manu */ /* PTHREAD_CANCEL_DEFERRED should be the default */#if THREADED pthread_setcancelstate ( PTHREAD_CANCEL_ENABLE, &OrigCancelState ); pthread_setcanceltype ( PTHREAD_CANCEL_DEFERRED, &OrigCancelType ); /* push cleanup routines */ pthread_cleanup_push ( GCCancel, MemPtr );#endif DbgLog(DL0, "Garbage collection running... PID %d\n",getpid()); while ( 1 ) { DbgLog(DL0, "Garbage collection running..."); /* Don't allow cancellations while mucking with shared memory or holding mutexes */#if THREADED pthread_setcancelstate ( PTHREAD_CANCEL_DISABLE, &LastCancelState );#endif CheckForGarbage(MemPtr);#if THREADED /* re-enable cancellations */ pthread_setcancelstate ( PTHREAD_CANCEL_ENABLE, &LastCancelState ); /* Test for cancellation by the main thread */ pthread_testcancel();#endif DbgLog(DL5, "Garbage collection finished."); /* now we pause */ sleep(10); } /* end while 1 */#if THREADED /* Yeah, yeah. Has to be here because some implementations use macros that have to be balanced */ pthread_cleanup_pop ( 0 );#endif /* return implicitly calls pthread_cancel() */ /* but it'll never really get executed; pthread_testcancel() implicitly calls pthread_exit() if there's a cancellation pending */ return NULL;}/********************************************************************************* * GCCancel - * * Cleanup routine called when Garbage collection thread exits/is cancelled * *********************************************************************************/void GCCancel ( void *Ptr ) { Slot_Mgr_Shr_t *MemPtr = (Slot_Mgr_Shr_t *) Ptr; /* Yeah, yeah. Doesn't do anything, but I had plans */ DbgLog(DL3, "GCCancel: tid: %d running cleanup routine", pthread_self()); return;}/********************************************************************************* * CheckForGarbage - * * The routine that actually does cleanup * *********************************************************************************/BOOL CheckForGarbage ( Slot_Mgr_Shr_t *MemPtr ) { int SlotIndex; int ProcIndex; int Err; BOOL ValidPid; ASSERT( MemPtr != NULL_PTR ); #ifdef DEV DbgLog(DL5, "Thread %d is checking for garbage", pthread_self()); #endif /* DEV */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -