Documentation for dcom library Content: ======== 1. General introduction to dcom. 2. Addition of locking/unlocking mechanism into dcom. ======================================================================== CHAPTER 1. GENERAL INTRODUCTION TO DCOM ========================================================================= dcom, the master communications area for the DAQ system. This file describes the manner in which the dcom communications area works along with the subroutines used by other software needed to access this area. The master communication area is just one big segment of shared memory with an elaborate data structure mapped over it. The shared memory segment is allocated once and remains alive for ever. (i.e. until the next reboot of the computer) There are two user function calls used to access or map into the program user space this 'communications area'. These calls are the following: dcom_attach() #include struct dcom_str *dcom_attach(); dcom_attach returns a pointer which contains the starting address of the dcom memory area. Officially, the pointer is of type dcom_str which is the full structure of the dcom memory area. Details on the dcom_str structure come later. If the return value is NULL, then an error occured in trying to attach to the dcom shared memory segment. NOTE: This function tries to attach to an existing dcom shared memory segment. If it fails, it tries to create it. If it fails to create it, it then return a NULL pointer signaling that an error has occured. dcom_deattach() #include void dcom_deattach() dcom_deattach will release the dcom shared memory segment from the user program. This function should be called at program termination. ------------------------------------------------------------------------ Structure of the dcom shared memory segment. The dcom structure is defined as follows: /* * Header file for the daq communications buffer. * * */ #include #include #include #include #include #include #include #include #include #define DCOM_SHM_KEY 1 /* * What follows are all the union declerations. * */ union diu { char buffer[DI_SIZE]; struct di_com_str di; }; union dru { char buffer[DR_SIZE]; struct dr_com_str dr; }; union daqu { char buffer[DAQ_SIZE]; struct daq_com_str daq; }; union dlu { char buffer[DL_SIZE]; struct dl_com_str dl; }; union duiu { char buffer[DUI_SIZE]; struct dui_com_str dui; }; union dsmu { char buffer[DSM_SIZE]; struct dsm_com_str dsm; }; union drpu { char buffer[DRP_SIZE]; struct drp_com_str drp; }; /* * The main daq common area data structure definition. * */ struct dcom_str { union diu diu; union dru dru[MAX_D_R_EXECS]; union daqu daqu; union dlu dlu; union duiu duiu; union dsmu dsmu; union drpu drpu; }; The main structure of the dcom area is named dcom_str. This structure is made up of a set of union structures, one for each DAQ component. Each union structure is inturn define by its own union statement to be a union of a buffer array of some specified size and another sub structure which contains the definition of the data to be stored in this area. This sub structure is then defined in the file xxx_dcom.h where xxx is the name of the software component. For example di_dcom.h contains the structure of the di part of the dcom shared memory area. Each xxx_dcom.h file is located in library directory for each software component for DAQ. For example! The dl_dcom.h file is found in $DI_LIBRARY/dl_dcom.h (i.e. the data logger data structure) Currently it contains the following: /* * Header file for the daq communications buffer. * * */ #include #include #define DL_SIZE 0x1000 /* * Substructures and main structure for dl common. * */ struct dl_com_str { pid_t pid; }; If I want to read or write to the pid field in the dl section of the dcom shared memory area, one would use the following code: #include #include main() { struct dcom_str *dcom; dcom = dcom_attach(); if (dcom == NULL) { printf("Error attaching to dcom area\n"); exit(1); } dcom->dlu.dl.pid = getpid(); } Each person responsible for the structure of each component of the dcom shared memory area should edit his/her own xxx_dcom.h file in the $XXX_LIBRARY directory. ====================================================================== CHAPTER 2 : LOCKING/UNLOCKING MECHANISM FOR DCOM ====================================================================== 2.1. Idea: ---------- Under certain conditions parts of dcom want to be locked/unlocked by a process, i.e. preventing other processes from accessing it. E.g. two situations can be imagined: 1. When all the processes start up one wants to be sure that only one process at a time puts information about itself (e.g. pid...) into the dcom area. (Example in the code eg dd_ctl in the dd software). 2. Certain variables have to be modified by several processes. In this case race conditions have to be organised in a "civilised" way. (Example db_nbuf_vol in dd_dcom). 2.2. Implementation: -------------------- Upon creation of the dcom area a set of semaphores are created, one for each subarea of dcom. Currently seven areas are defined in dcom.h, namely DI, DR, DD, DL, DIU, DSM and DRP. Whenever a process wants to be sure to be the only one working on its dcom sub area, it clears the semaphore and reenables it once it is finished. If a process encounters a 0 value of its semaphore, it will wait until it is set back to 1. NOTE, that if a process clears a semaphore but does NOT reset it to 1, then this area will be kept locked for all other processes!! There also is a routine dcom_clear_sem(), which resets all the semaphore to 1 (which should only be done by run_control). 2.3. User calls: ---------------- int dcom_lock(int which_dcom) int dcom_unlock(int which_dcom), where which_dcom is DI_DCOM, DR_DCOM, DD_DCOM, DL_DCOM, DIU_DCOM, DSM_DCOM and DRP_DCOM, which are defined in dcom.h. Note: Only the corresponding subarea of dcom is locked, no other parts of dcom are affected. Furthermore: int dcom_clear_sem() --> see above int dcom_get_semcnt(int *sem_array), which returns all the semaphore values in the array sem_array. Upon successful termination a value of 0 is returned, a nonzero value indicates an error. No particular initialisation is needed for these semaphores, as the processes gets the necessary semaphore id while executing dcom_attach. Comments to C.Witzig. Apr 30, 1992.