📄 realtime.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 + -