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

📄 alarm.mx

📁 一个内存数据库的源代码这是服务器端还有客户端
💻 MX
字号:
@' The contents of this file are subject to the MonetDB 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://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html@'@' 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 MonetDB Database System.@'@' The Initial Developer of the Original Code is CWI.@' Portions created by CWI are Copyright (C) 1997-2007 CWI.@' All Rights Reserved.@f alarm@a M.L. Kersten, P. Boncz@+ Timers and Timed InterruptsThis module handles various signaling/timer functionalities.The Monet interface supports two timer commands: @emph{ alarm} and @emph{ sleep}.Their argument is the number of seconds to wait before the timer goes off.The @emph{ sleep} command blocks till the alarm goes off.The @emph{ alarm} command continues directly, executes off a MILstring when it goes off.The parameterless routines @emph{ time} and @emph{ ctime} provide access tothe cpu clock.They return an integer and string, respectively.@{@malmodule alarm;command sleep(secs:int):void address ALARMsleep comment "sleep X secs";command alarm(secs:int, action:str):void address ALARMsetalarm comment "execute action in X secs";command timers() :bat[:str,:str] address ALARMtimerscomment "give a list of all active timers";command usec() :lng address ALARMuseccomment "return cpu microseconds info";command time() :int address ALARMtime comment "time in millisecs";command epoch() :int address ALARMepoch comment "current time as unix epoch";command ctime() :str address ALARMctime comment "current time as a string";command prelude():voidaddress ALARMprelude comment "Initialize alarm module";command epilogue():voidaddress ALARMepilogue comment "Finalize alarm module";alarm.prelude();@* Implementation@+ The Clock Interrupt GeneratorA clock event generator, called @%timer@, has been added to the database kernel.It accepts a message @%CLKalarm(sec, usec)@, which generates an alarmafter the time indicated.The timer maintains a small stack of timing events sorted in priority of firing.The top contains the next timer event to go off.The timer is disabled when no timer events are outstanding.@h#include <mal.h>#include <signal.h>#define MAXtimer                200typedef struct {	str action;		/* MIL action (as a string) */	MT_Sema sema;		/* barrier */	time_t alarm_time;	/* time when the alarm goes off */} monet_timer_t;@c#include "mal_config.h"#include "alarm.h"#include <time.h>#ifdef WIN32#ifndef LIBALARM#define alarm_export extern __declspec(dllimport)#else#define alarm_export extern __declspec(dllexport)#endif#else#define alarm_export extern#endifalarm_export str ALARMprelude(void);alarm_export str ALARMepilogue(void);alarm_export str ALARMusec(lng *ret);alarm_export str ALARMsleep(int *res, int *secs);alarm_export str ALARMsetalarm(int *res, int *secs, str *action);alarm_export str ALARMtimers(int *res);alarm_export str ALARMctime(str *res);alarm_export str ALARMepoch(int *res);alarm_export str ALARMtime(int *res);static monet_timer_t timer[MAXtimer];static int timerTop = 0;@@-The timer is awakened by a clock interrupt. The interrupt granularityis OS-dependent. The timer should be initialized as long as thereare outstanding timer events.@c#ifdef SIGALRMvoidCLKinitTimer(int sec, int usec){	int i = sec - time(0);	(void) usec;	TRGDEBUG THRprintf(GDKout, "#CLKinitTimer: set timer to %d secs \n", i);	alarm(i);}#endif@-A new alarm is pushed onto the stack using @%CLKalarm@.The parameter is the real-time value to be approximated.@c#ifdef SIGALRMvoidCLKalarm(time_t t, str action){	int j;	int k;	TRGDEBUG THRprintf(GDKout, "#CLKalarm: push " LLFMT "\n", (lng) t);	if (timerTop == MAXtimer) {		GDKerror("CLKalarm: timer stack overflow\n");		return;	}	for (j = 0; j < timerTop; j++) {		if (timer[j].alarm_time > t)			break;	}	for (k = timerTop; k > j; k--) {		timer[k] = timer[k - 1];	}	timer[k].alarm_time = t;	if (action) {		timer[k].action = GDKstrdup(action);	} else {		timer[k].action = 0;		MT_init_sema(timer[k].sema, 0);	}	if (k == timerTop++) {		CLKinitTimer(t, 0);	/* set it sooner */	}}#endif@-Once a timer interrupt occurs, we should inspect the timer queue andemit a notify signal.@c#ifdef SIGALRM/* HACK to pacify compiler */#if (defined(__INTEL_COMPILER) && (SIZEOF_VOID_P > SIZEOF_INT))#undef  SIG_ERR			/*((__sighandler_t)-1 ) */#define SIG_ERR   ((__sighandler_t)-1L)#endifstatic RETSIGTYPECLKsignal(int nr){	/* int restype; */	int k = timerTop;	int t;	(void) nr;	if (signal(SIGALRM, CLKsignal) == SIG_ERR) {		GDKsyserror("CLKsignal: call failed\n");	}	TRGDEBUG THRprintf(GDKout, "#alarm signal (timeTop=%d)\n", timerTop);	if (timerTop == 0) {		return;	}	t = time(0);	while (k-- && t >= timer[k].alarm_time) {		if (timer[k].action) {			TRGDEBUG THRprintf(GDKout, "#eval(%s)\n", timer[k].action);			/* monet_eval(timer[k].action, &restype); */			GDKfree(timer[k].action);		} else {			MT_up_sema(timer[k].sema, "CLKsignal");		}		timerTop--;	}	if (timerTop > 0) {		CLKinitTimer(timer[timerTop - 1].alarm_time, 0);	}}#endifbat *CLKprelude(void){#ifdef SIGALRM	(void) signal(SIGALRM, CLKsignal);#endif	return NULL;}voidCLKepilogue(void){	int k;#if (defined(SIGALRM) && defined(SIG_IGN))/* HACK to pacify compiler */#if (defined(__INTEL_COMPILER) && (SIZEOF_VOID_P > SIZEOF_INT))#undef  SIG_IGN			/*((__sighandler_t)1 ) */#define SIG_IGN   ((__sighandler_t)1L)#endif	(void) signal(SIGALRM, SIG_IGN);#endif	for (k = 0; k < timerTop; k++) {		if (timer[k].action)			GDKfree(timer[k].action);	}}intCMDsleep(int *secs){	if (*secs < 0) {		GDKerror("CMDsleep: negative delay\n");		return GDK_FAIL;	} else {#ifdef __CYGWIN__		/* CYGWIN cannot handle SIGALRM with sleep */		lng t = GDKusec() + (*secs)*1000000;				while (GDKusec() < t)			;#else		MT_sleep_ms(*secs * 1000);#endif	}	return GDK_SUCCEED;}intCMDalarm(int *secs, str action){	if (*secs < 0) {		GDKerror("CMDalarm: negative delay\n");		return GDK_FAIL;	} else {#ifndef SIGALRM		(void)action;		GDKerror("CMDalarm: not implemented\n");		return GDK_FAIL;#else		CLKalarm(time(0) + *secs, action);#endif	}	return GDK_SUCCEED;}@-Problem with CMDtimers is that they use static buffers thatmay be overwritten under parallel processing.Therefore, the code below is dangerous (!) and the re-entrant codeshould be used.  However, on Windows where ctime_r is not available,ctime is actually thread-safe.@cintCMDtimers(BAT **retval){	char buf[27];	int k;	*retval = BATnew(TYPE_str, TYPE_str, timerTop);	if (*retval == NULL)		return GDK_FAIL;	BATroles(*retval, "alarm", "action");	for (k = 0; k < timerTop; k++) {		time_t t = timer[k].alarm_time;#ifdef HAVE_CTIME_R3		ctime_r(&t, buf, sizeof(buf));#else#ifdef HAVE_CTIME_R		ctime_r(&t, buf);#else		strncpy(buf, ctime(&t), sizeof(buf));#endif#endif		BUNins(*retval, buf, timer[k].action ? timer[k].action : "barrier", FALSE);	}	return GDK_SUCCEED;}intCMDctime(str *retval){	time_t t = time(0);#ifdef HAVE_CTIME_R3	char buf[26];	*retval = GDKstrdup(ctime_r(&t, buf, sizeof(buf)));#else#ifdef HAVE_CTIME_R	char buf[26];	*retval = GDKstrdup(ctime_r(&t, buf));#else	*retval = GDKstrdup(ctime(&t));#endif#endif	return GDK_SUCCEED;}intCMDepoch(int *retval)		/* XXX should be lng */{	*retval = (int) time(0);	return GDK_SUCCEED;}/* should return lng */intCMDusec(lng *retval){	*retval = GDKusec();	return GDK_SUCCEED;}intCMDtime(int *retval){	*retval = GDKms();	return GDK_SUCCEED;}@- WrappingWrapping the Version 4 code base@c#include "mal.h"#include "mal_exception.h"voidALARMinitTimer(int sec, int usec){	(void) sec;	(void) usec;#ifdef SIGALRM	CLKinitTimer(sec, usec);#endif}#ifdef SIGALRMstrALARMalarm(int t, str *action){	CLKalarm(t, *action);	return MAL_SUCCEED;}#endifstrALARMprelude(){#ifdef SIGALRM	(void) signal(SIGALRM, (void (*)()) CLKsignal);#endif	return MAL_SUCCEED;}strALARMepilogue(){	CLKepilogue();	return MAL_SUCCEED;}strALARMusec(lng *ret){	CMDusec(ret);	return MAL_SUCCEED;}strALARMsleep(int *res, int *secs){	(void) res;		/* fool compilers */	CMDsleep(secs);	return MAL_SUCCEED;}strALARMsetalarm(int *res, int *secs, str *action){	(void) res;	(void) secs;	(void) action;		/* foolc compiler */	throw(MAL, "alarm.setalarm", "Not yet implemented");}strALARMtimers(int *res){	(void) res;		/* fool compiler */	throw(MAL, "alarm.timers", "Not yet implemented");}strALARMctime(str *res){	CMDctime(res);	return MAL_SUCCEED;}strALARMepoch(int *res){	CMDepoch(res);	return MAL_SUCCEED;}strALARMtime(int *res){	CMDtime(res);	return MAL_SUCCEED;}@}

⌨️ 快捷键说明

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