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

📄 realtime.c

📁 linux集群服务器软件代码包
💻 C
字号:
/* $Id: realtime.c,v 1.20 2004/02/17 22:11:59 lars Exp $ */#include <portability.h>#include <sys/types.h>#include <stdlib.h>/* The BSD's do not use malloc.h directly. *//* They use stdlib.h instead */#ifndef BSD#ifdef HAVE_MALLOC_H#	include <malloc.h>#endif#endif#include <unistd.h>#ifdef _POSIX_MEMLOCK#	include <sys/mman.h>#endif#ifdef _POSIX_PRIORITY_SCHEDULING#	include <sched.h>#endif#include <string.h>#include <clplumbing/cl_log.h>#include <clplumbing/realtime.h>#include <clplumbing/uids.h>#include <time.h>static gboolean	cl_realtimepermitted = TRUE;static void cl_rtmalloc_setup(void);#if defined(SCHED_RR) && defined(_POSIX_PRIORITY_SCHEDULING)#	define DEFAULT_REALTIME	SCHED_RR#endif#define HOGRET	0xff/* * Slightly wacko recursive function to touch requested amount * of stack so we have it pre-allocated inside our realtime code * as per suggestion from mlockall(2) */#ifdef _POSIX_MEMLOCKstatic intcl_stack_hogger(char * inbuf, int kbytes){	unsigned char	buf[1024];		if (inbuf == NULL) {		memset(buf, HOGRET, sizeof(buf));	}else{		memcpy(buf, inbuf, sizeof(buf));	}	if (kbytes > 0) {		return cl_stack_hogger(buf, kbytes-1);	}else{		return buf[sizeof(buf)-1];	}/* #else	return HOGRET;*/}#endif/* * We do things this way to hopefully defeat "smart" malloc code which * handles large mallocs as special cases using mmap(). */static voidcl_malloc_hogger(int kbytes){	long	size		= kbytes * 1024;	int	chunksize	= 1024;	long	nchunks		= (int)(size / chunksize);	int	chunkbytes 	= nchunks * sizeof(void *);	void**	chunks		= malloc(chunkbytes);	int	j;	if (chunks == NULL) {		cl_log(LOG_INFO, "Could not preallocate (%d) bytes" 		,	chunkbytes);		return;	}	memset(chunks, 0, chunkbytes);	for (j=0; j < nchunks; ++j) {		chunks[j] = malloc(chunksize);		if (chunks[j] == NULL) {			cl_log(LOG_INFO, "Could not preallocate (%d) bytes" 		,	chunksize);		}else{			memset(chunks[j], 0, chunksize);		}	}	for (j=0; j < nchunks; ++j) {		if (chunks[j]) {			free(chunks[j]);			chunks[j] = NULL;		}	}	free(chunks);	chunks = NULL;}/* *	Make us behave like a soft real-time process. *	We need scheduling priority and being locked in memory. *	If you ask us nicely, we'll even grow the stack and heap *	for you before locking you into memory ;-). */voidcl_make_realtime(int spolicy, int priority,  int stackgrowK, int heapgrowK){#ifdef DEFAULT_REALTIME	struct sched_param	sp;	int			staticp;#endif	if (heapgrowK > 0) {		cl_malloc_hogger(heapgrowK);	}#ifdef _POSIX_MEMLOCK	if (stackgrowK > 0) {		int	ret;		if ((ret=cl_stack_hogger(NULL, stackgrowK)) != HOGRET) {			cl_log(LOG_INFO, "Stack hogger failed 0x%x"			,	ret);		}	}#endif	cl_rtmalloc_setup();	if (!cl_realtimepermitted) {		cl_log(LOG_INFO		,	"Request to set pid %ld to realtime ignored."		,	(long)getpid());		return;	}#ifdef DEFAULT_REALTIME	if (spolicy <= 0) {		spolicy = DEFAULT_REALTIME;	}	if (priority <= 0) {		priority = sched_get_priority_min(spolicy);	}	if (priority > sched_get_priority_max(spolicy)) {		priority = sched_get_priority_max(spolicy);	}	if ((staticp=sched_getscheduler(0)) < 0) {		cl_perror("unable to get scheduler parameters.");	}else{		memset(&sp, 0, sizeof(sp));		sp.sched_priority = priority;		if (sched_setscheduler(0, spolicy, &sp) < 0) {			cl_perror("Unable to set scheduler parameters.");		}	}#endif#ifdef _POSIX_MEMLOCK	if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) {		cl_perror("Unable to lock pid %d in memory", (int) getpid());	}else{		cl_log(LOG_INFO, "pid %d locked in memory.", (int) getpid());	}#endif}voidcl_make_normaltime(){#ifdef DEFAULT_REALTIME	struct sched_param	sp;	memset(&sp, 0, sizeof(sp));	sp.sched_priority = sched_get_priority_min(SCHED_OTHER);	if (sched_setscheduler(0, SCHED_OTHER, &sp) < 0) {		cl_perror("unable to (re)set scheduler parameters.");	}#endif#ifdef _POSIX_MEMLOCK	/* Not strictly necessary. */	munlockall();#endif}voidcl_disable_realtime(void){	cl_realtimepermitted = FALSE;}voidcl_enable_realtime(void){	cl_realtimepermitted = TRUE;}/* Give up the CPU for a little bit *//* This is similar to sched_yield() but allows lower prio processes to run */intcl_shortsleep(void){	static const struct timespec	req = {0,2000001L};	return nanosleep(&req, NULL);}static int	post_rt_morecore_count = 0;#ifdef HAVE_MALLINFOstatic long	init_malloc_arena = 0L;#endif/* Return the number of times we went after more core */intcl_nonrealtime_malloc_count(void){	return post_rt_morecore_count;}/* Return the number of times we went after more core */voidcl_realtime_malloc_check(void){	static	int lastcount = 0;	if (post_rt_morecore_count > lastcount) {		cl_log(LOG_WARNING		,	"Performed %d non-realtime malloc calls."		,	post_rt_morecore_count - lastcount);#ifdef HAVE_MALLINFO		cl_log(LOG_INFO		,	"Total non-realtime malloc bytes: %ld"		,	mallinfo().arena - init_malloc_arena);#endif		lastcount = post_rt_morecore_count;	}}#ifndef HAVE___DEFAULT_MORECOREstatic voidcl_rtmalloc_setup(void){	post_rt_morecore_count = 0;#ifdef HAVE_MALLINFO	init_malloc_arena = mallinfo().arena;#endif	return;}#else	/* HAVE___DEFAULT_MORECORE */#	include <malloc.h>static void	(*save_morecore_hook)(void);static void	cl_rtmalloc_morecore_fun(void);static voidcl_rtmalloc_setup(void){	save_morecore_hook = __after_morecore_hook;	 __after_morecore_hook = cl_rtmalloc_morecore_fun;}static voidcl_rtmalloc_morecore_fun(void){	post_rt_morecore_count++;}#endif

⌨️ 快捷键说明

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