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

📄 memsem.cc

📁 Source code for an Numeric Cmputer
💻 CC
字号:
/********************************************************************* Description: memsem.cc*   Uses a block of memory to implement a mutual exclusion semaphore.*   With LynxOs and SunOs using semop is very inefficient if the semaphore *   will usually be available. Other platforms may give you no semaphore*   operations.**   Example: You are communicating with another process via shared memory.*   You need a mutual exclusion semaphore because you don't want the reader*   to occasionally read the buffer while the writer has written only part*   of the message, but most of the time when the writer won't be using*   buffer and the reader should get access immediately. semop will take*   100 to 150 microseconds to return access, while mem_get_access should*   take less than a microsecond with less than 10 total_connections.**   Derived from a work by Fred Proctor & Will Shackleford** Author:* License: LGPL Version 2* System: Linux*    * Copyright (c) 2004 All rights reserved.** Last change: * $Revision: 1.7 $* $Author: paul_c $* $Date: 2005/06/13 14:38:48 $********************************************************************/#ifdef  __cplusplusextern "C" {#endif#include <stddef.h>		/* NULL */#ifdef  __cplusplus};#endif#include "timer.hh"		/* etime(), esleep() */#include "memsem.hh"		/* struct mem_access_object */#include "rcs_print.hh"		// rcs_print_error()#define TIMEOUT_MIN ((double) 1.0E-6)/******************************************************************* Take the mutual exclusion semaphore.** Parameters:* data should point to an area of memory accesable to all processes that*   is at least "total_connections" bytes long,* connection_number is a unique identifier for this process it should*  be between 0 and ("total_connections"-1)* total_connections is the maximum number of processes that can use this*  block of memory as a semaphore.* timeout - is the time allowed for getting the semaphore.*    (If timeout is negative then wait forever.)* semdelay - is the time to wait between tries for the semaphore.* read_only - Will the access to the buffer only to read the memory.* split_buffer - The buffer will be split so that one area may be read* while the other area is written to.* toggle_bit - If the buffer is split the toggle bit determines which area* will be read from and which may be written to. (O.K. its really a byte but* think of it as 1 bit since it should only be 0 or 1)** Returns: 0 for success: -1 for invalid parameters: or -2 if it timed out.***********************************************************************//*! \todo Another #if 0 */#if 0int mem_get_access(void *data, long connection_number,    long total_connections, double timeout, double semdelay,    int read_only, int split_buffer, char &toggle_bit)#endif     int mem_get_access(struct mem_access_object *mo){    register char *mylock;    register char current_lock;    register char *plock;    char *lastlock;    int semaphores_clear;    double start_time, time;    int split_buffer = 0;    int read_only;    int total_connections;    int connection_number;    double timeout;#ifdef DEBUG    rcs_print("mem_get_access: - Time = %lf\n", etime());    static int count = 0;    count++;#endif    /* Check Parameters. */    if ((total_connections = mo->total_connections) <=	(connection_number = mo->connection_number) || connection_number < 0)    {	return -1;    }    if (NULL == mo->data) {	return -1;    }    /* Check for a request for me to sleep */    int wait_requested = 1;    lastlock = ((char *) mo->data) + total_connections;    mylock = ((char *) mo->data) + connection_number;    time = start_time = etime();	/* get start time */    while (wait_requested	&& (time - start_time < mo->timeout / 2 || mo->timeout < 0)) {	wait_requested = 0;	for (plock = (char *) mo->data; plock < lastlock; plock++) {	    if (5 == (current_lock = *plock) && plock != mylock) {		wait_requested = 1;	    }	}	if (wait_requested) {	    esleep(mo->sem_delay);	}    }    /* Try the locks one time before checking time because checking the locks        generally takes much less time than checking the time. */    *mylock = 4;    mo->toggle_bit = ((char *) mo->data)[total_connections];    read_only = mo->read_only;#ifdef DEBUG    if (read_only) {	rcs_print("added sleep: %d - Time = %lf\n", __LINE__, etime());	esleep(0.02);    }#endif    if (read_only) {	split_buffer = mo->split_buffer;	if (split_buffer) {	    *mylock = 2 + mo->toggle_bit;	    return 0;	}	*mylock = 2;    } else {	*mylock = 1;    }#ifdef debug    if (read_only) {	rcs_print("added sleep: %d - time = %lf\n", __line__, etime());	esleep(0.01);    }#endif    semaphores_clear = 1;    lastlock = ((char *) mo->data) + total_connections;    mo->toggle_bit = ((char *) mo->data)[total_connections];    for (plock = (char *) mo->data; plock < lastlock; plock++) {	if (0 != (current_lock = *plock)) {	    if (plock != mylock) {		if (!(read_only && current_lock > 1) &&		    !(split_buffer && current_lock == 2 + mo->toggle_bit)		    && (current_lock != 5)) {		    semaphores_clear = 0;		}	    }	}    }#ifdef debug    if (0)			// read_only && 0 == count % 2)    {	rcs_print("added sleep: %d - time = %lf\n", __line__, etime());	esleep(0.01);    }#endif    if (semaphores_clear) {	return 0;    }    timeout = mo->timeout;    if (timeout < TIMEOUT_MIN && timeout > 0) {	*mylock = 0;	return (-2);    }    /* release the lock before going to sleep. */    *mylock = 5;    if (NULL != mo->sem) {	if (-1 == mo->sem->wait()) {	    *mylock = 0;	    return -1;	}    } else {	esleep(mo->sem_delay);	/* sleep for 100 microseconds */    }    if (read_only) {	*mylock = 2;    } else {	*mylock = 1;    }#ifdef debug    if (0)			// read_only && 0 == count % 7)    {	rcs_print("added sleep: %d - time = %lf\n", __line__, etime());	esleep(0.01);    }#endif    while ((timeout >= 0) ? ((time - start_time) < timeout) : 1) {	if (split_buffer) {	    mo->toggle_bit = ((char *) mo->data)[total_connections];	}	semaphores_clear = 1;	plock = (char *) mo->data;	mo->toggle_bit = ((char *) mo->data)[total_connections];	for (; plock < lastlock; plock++) {	    current_lock = *plock;	    if (0 != current_lock) {		if (plock != mylock &&		    !(read_only && current_lock > 1) &&		    !(split_buffer && current_lock == 2 + mo->toggle_bit)		    && (current_lock != 5)) {		    semaphores_clear = 0;		}	    }	}	if (semaphores_clear) {	    return 0;	}	if (NULL != mo->sem) {	    *mylock = 5;	    mo->sem->wait();	} else {	    *mylock = 5;	    esleep(mo->sem_delay);	/* sleep for 100 microseconds */	}	if (read_only) {	    *mylock = 2;	} else {	    *mylock = 1;	}#ifdef DEBUG	if (0)			// read_only && 0 == count % 4)	{	    rcs_print("added sleep: %d - Time = %lf\n", __LINE__, etime());	    esleep(0.01);	}#endif	time = etime();    }    *mylock = 0;    return (-2);}/******************************************************************* Give up the mutual exclusion semaphore.** Parameters:* data should point to an area of memory accesable to all processes that*   is at least "total_connections" bytes long,* connection_number is a unique identifier for this process it should*  be between 0 and ("total_connections"-1)** Returns: 0 for success: -1 for invalid parameters***********************************************************************/int mem_release_access(struct mem_access_object *mo){    int i;    int process_waiting = 0;#ifdef DEBUG    rcs_print("mem_release_access: - Time = %lf\n", etime());    static int count = 0;    count++;#endif    if (NULL == mo) {	rcs_print_error("mem_release_access: Invalid memory object.\n");    }    if (NULL == mo->data || mo->connection_number < 0) {	rcs_print_error("mem_release_access: Invalid memory object.\n");	return -1;    }    if (mo->sem != NULL) {	process_waiting = 0;	for (i = 0; i < mo->total_connections; i++) {	    if (((char *) mo->data)[i] == 5) {		process_waiting = 1;		break;	    }	}    }#ifdef DEBUG    if (0)			// (0 == count % 5)    {	rcs_print("added sleep: %d - Time = %lf\n", __LINE__, etime());	esleep(0.01);    }#endif    /* If were using a split buffer and this is the end of a write toggle the        toggle bit. */    if (mo->split_buffer && ((char *) mo->data)[mo->connection_number] == 1) {	((char *) mo->data)[mo->total_connections] = !(mo->toggle_bit);    }#ifdef DEBUG    if (0)			// 0 == count % 7)    {	rcs_print("added sleep: %d - Time = %lf\n", __LINE__, etime());	esleep(0.01);    }#endif    ((char *) mo->data)[mo->connection_number] = 0;#ifdef DEBUG    if (0)			// 0 == count % 11)    {	rcs_print("added sleep: %d - Time = %lf\n", __LINE__, etime());	esleep(0.01);    }#endif    if (mo->sem != NULL) {	if (process_waiting) {	    mo->sem->post();	}    }    return (0);}

⌨️ 快捷键说明

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