/*{ ** Name: main - print the LG/LK shared memory key ** ** Description: ** Used by build and install tools to clean up the LG/LK shared memory. ** ** Inputs: ** None ** ** Outputs: ** ** Returns: ** OK - success ** !OK - failure (CS*() routine failure, segment not mapped, ...) ** ** History: ** 21-nov-1992 (bryanp) ** Created to solve LG/LK memory cleanup problems. ** 15-may-1995 (thoro01) ** Added NO_OPTIM hp8_us5 to file. ** 10-may-1999 (walro03) ** Remove obsolete version string sqs_u42. ** 28-sep-2002 (devjo01) ** Add CXget_context, so NUMA cluster context can be established. */ int main(int argc, char *argv[]) { key_t key; #if defined(conf_BUILD_ARCH_32_64) && defined(BUILD_ARCH32) { char *lp64enabled; /* ** Try to exec the 64-bit version */ NMgtAt("II_LP64_ENABLED", &lp64enabled); if ( (lp64enabled && *lp64enabled) && ( !(STbcompare(lp64enabled, 0, "ON", 0, TRUE)) || !(STbcompare(lp64enabled, 0, "TRUE", 0, TRUE)))) { PCexeclp64(argc, argv); } } #endif /* hybrid */ if ( OK != CXget_context( &argc, argv, CX_NSC_STD_NUMA, NULL, 0 ) ) PCexit(FAIL); if ((key = ME_getkey("lglkdata.mem")) != (key_t)-1) SIprintf("0x%x\n", (i4)key); PCexit(OK); }
/*{ ** Name: CS_alloc_serv_segment() - Create shared memory for a server ** ** Description: ** Allocate a shared memory segment of "size" bytes. All data placed ** in this segment should be position independent. ** ** Upon success this function will create the shared memory segment with ** the given id and size. To actually access the shared memory segment ** the user must make a CS_map_server_segment() call. It is expected ** that this single request will fulfill all shared memory needs particular ** to a single server. It may be difficult or impossible to extend the ** shared memory resources of some machines to provide for more than 3 ** different shared memory segments mapped to a single process (the ** control segment, the locking/logging segment, and the server segment). ** ** It is expected that CS will call CS_alloc_serv_segment() and ** CS_map_serv_segment() once at server initialization. ** Slaves will only call the map function. ** ** This call is internal to CS is meant only to be called by CS, and may ** only exist on unix systems supporting shared memory. ** ** Inputs: ** size size in bytes of shared mem segment. ** ** Outputs: ** id on success set to id of segment. ** err_code system dependent error code. ** ** Returns: ** E_DB_OK ** ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 08-sep-88 (mmm) ** First Version ** 12-jun-89 (rogerk) ** Changed arguments to MEget_pages, MEdetach calls. They now use ** character name keys rather than a LOCATION pointer. Changed ** ME_loctokey call to ME_getkey. ** 26-aug-89 (rexl) ** Added calls to protect page allocator. ** 3-jul-1992 (bryanp) ** Explicitly ACLR the TAS objects when allocating server segment. ** 07-nov-1996 (canor01) ** Explicitly initialize the csi_spinlock object. */ STATUS CS_alloc_serv_segment(SIZE_TYPE size, u_i4 *server_seg_num, PTR *address, CL_ERR_DESC *err_code) { STATUS status = OK; CS_SERV_INFO *serv_info; PTR dummy; i4 i; SIZE_TYPE alloc_pages; char segname[48]; status = CS_find_server_slot(&i); serv_info = Cs_sm_cb->css_servinfo; if (!address) { address = &dummy; } if (status) { SETCLERR(err_code, 0, 0); /* since find_server_slot doesn't set */ } else { /* now allocate and initialize the server segment */ STcopy("server.", segname); CVna(i, segname+STlength(segname)); size = (size + ME_MPAGESIZE - 1) & ~ (ME_MPAGESIZE - 1); # ifdef SERV_MAP_ADDR *address = (PTR) SERV_MAP_ADDR; status = MEget_pages(ME_MZERO_MASK|ME_SSHARED_MASK|ME_CREATE_MASK| ME_ADDR_SPEC, size/ME_MPAGESIZE, segname, address, &alloc_pages, err_code); # else status = MEget_pages(ME_MZERO_MASK|ME_SSHARED_MASK|ME_CREATE_MASK, size/ME_MPAGESIZE, segname, address, &alloc_pages, err_code); # endif if (status) { /* Unable to create lg/lk shared memory segment */ status = FAIL; } else { /* initialize it's description in the master control block */ Cs_svinfo->csi_serv_desc.cssm_size = size; Cs_svinfo->csi_serv_desc.cssm_id = ME_getkey(segname); *server_seg_num = i; /* ** Explicitly clear these TAS objects, for machines such as the HP ** where MEfill'ing the memory with zeros does not initialize the ** TAS objects to "clear" state. */ CS_ACLR(&Cs_svinfo->csi_nullev); CS_ACLR(&Cs_svinfo->csi_events_outstanding); CS_ACLR(&Cs_svinfo->csi_wakeme); CS_SPININIT(&Cs_svinfo->csi_spinlock); for (i = 0; i < (sizeof(Cs_svinfo->csi_subwake) / sizeof(Cs_svinfo->csi_subwake[0])); i++) { CS_ACLR(&Cs_svinfo->csi_subwake[i]); } if (address == &dummy) MEdetach(segname, address, err_code); /* and free pages */ /* FIX ME - bunch of other stuff */ } } return(status); }
/*{ ** Name: CS_create_sys_segment() - Create system shared mem segment. ** ** Description: ** Create system control block. Only caller should be the system ** initialization program. Other users of the system shared memory ** segment should only map an already created shared memory segment. ** ** This procedure creates a shared memory segment. It then maps it into ** the current process and initializes it. It then unmaps it from the ** current process (so that the CS_map_sys_segment() can be used without ** any special casing). ** ** Currently the already created shared memory segment is destroyed ** before the new one is created. We may add a destroy procedure ** once the system installation program is fleshed out. ** ** Inputs: ** num_of_servers number of servers this installation ** should support. ** num_of_wakeups number of wakeupblocks this installation ** should support. ** Outputs: ** err_code system dependent error. ** ** Returns: ** OK successfully created the segment. ** FAIL failure to create shared mem segment. ** ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 01-jan-88 (mmm) ** Created. ** 21-jan-89 (mikem) ** set correct value in the CS_SMCNTRL for the LG/LK shared memory id. ** also add support for dynamic LGLK segment. ** 12-jun-89 (rogerk) ** Integrated Terminator changes. Changed args to MEget_pages calls. ** Changed shared memory key to character string, not LOCATION pointer. ** Changed ME_loctokey call to ME_getkey. ** 21-Jul-89 (anton) ** Don't need a sys V semaphore per server any more. ** 26-aug-89 (rexl) ** Added calls to protect page allocator. ** 28-Dec-89 (fredp) ** Add TRdisplay error message on failure of semget. ** 16-feb-90 (greg) ** NMgtAt is a VOID. ** 16-mar-90 (fredp) ** Added support for system-wide II_LG_MAP_ADDR variable. If it ** is set, it contains the hex address of where the lock segment ** should be mapped into memory (instead of the default LG_MAP_ADDR). ** If the system segment attach fails on Sun3, retry with a 1MB ** lower attach address since the start of the user stack dropped ** 1MB from that of SunOS 4.0.x. ** 3-jul-1992 (bryanp) ** We don't need to call LG/LK initialize anymore. ** Added num_of_wakeups argument and used it to set css_wakeups_off. ** 26-jul-1993 (bryanp) ** Removed the 5 extra semaphores that no-one needed nor used. This ** leaves a few unused variables in various control blocks, which ** eventually I'll get around to removing, as well. For now, ** removing the unneeded semaphores reduces the system resource ** usage of Ingres, which is a Good Thing. ** 31-jan-94 (mikem) ** bug #58298 ** Changed CS_handle_wakeup_events() to maintain a high-water mark ** for events in use to limit the scanning necessary to find ** cross process events outstanding. Previous to this each call to ** the routine would scan the entire array, which in the default ** configuration was 4k elements long. Changed CS_create_sys_segment() ** to initalize the new fields. ** 20-apr-94 (mikem) ** Bug #57043 ** Added a call to CS_clockinit() to CS_create_sys_segment(). This ** call is responsible for initializing new control information stored ** in the shared memory system segment which is used to manipulate ** the pseudo-quantum clock. This clock is used to maintain both ** quantum and timeout queues in CS. See csclock.c for more ** information. ** 19-sep-2002 (devjo01) ** Allocate shared memory from local RAD if Running NUMA. ** 5-Apr-2006 (kschendel) ** Use generated css version instead of constant. */ STATUS CS_create_sys_segment(i4 num_of_servers, i4 num_of_wakeups, CL_ERR_DESC *err_code) { SIZE_TYPE size; STATUS status; PTR address; SIZE_TYPE alloc_pages; char *string; char *addr_string; STATUS cv_status = OK; i4 meflags; /* the system shared memory control block looks as follows: ** ** ------------------------------ ** | control block | ** |----------------------------- ** | array of server info | ** | ... | ** | ... | ** |----------------------------- ** | array of wakeup blocks | ** | ... | ** | ... | ** ------------------------------ */ size = sizeof(CS_SMCNTRL) + ((num_of_servers + 1) * sizeof(CS_SERV_INFO)); size += (num_of_wakeups * sizeof(CS_SM_WAKEUP_CB)); /* round to ME_MPAGESIZE */ size = (size + ME_MPAGESIZE - 1) & ~(ME_MPAGESIZE - 1); /* ** Create shared segment for sysseg. ** Use SYSSEG.MEM as shared memory key. */ meflags = ME_MZERO_MASK|ME_SSHARED_MASK|ME_CREATE_MASK|ME_NOTPERM_MASK; address = (PTR) 0; if (CXnuma_user_rad()) meflags |= ME_LOCAL_RAD; status = MEget_pages(meflags, size/ME_MPAGESIZE, "sysseg.mem", &address, &alloc_pages, err_code); /* FIX ME - initialize all the server control blocks */ if (!status) { /* initialize the shared memory data base */ Cs_sm_cb = (CS_SMCNTRL *) address; Cs_sm_cb->css_css_desc.cssm_addr = (PTR) 0; Cs_sm_cb->css_css_desc.cssm_size = size; #ifdef __vms /* there's no such thing as a shared mem id in VMS */ Cs_sm_cb->css_css_desc.cssm_id = 0; #else Cs_sm_cb->css_css_desc.cssm_id = ME_getkey("sysseg.mem"); #endif Cs_sm_cb->css_numservers = num_of_servers; Cs_sm_cb->css_wakeup.css_numwakeups = num_of_wakeups; Cs_sm_cb->css_wakeup.css_minfree = 0; Cs_sm_cb->css_wakeup.css_maxused = 0; CS_clockinit(Cs_sm_cb); Cs_sm_cb->css_version = make_css_version(); CS_SPININIT(&Cs_sm_cb->css_spinlock); /* now allocate cross process semaphores */ # ifdef xCL_075_SYS_V_IPC_EXISTS Cs_sm_cb->css_semid = semget(Cs_sm_cb->css_css_desc.cssm_id, CSCP_NUM, 0600|IPC_CREAT); if (Cs_sm_cb->css_semid < 0) { TRdisplay("semget of %d semaphores failed\n", CSCP_NUM); TRdisplay("errno = %d\n",errno); SETCLERR(err_code, 0, 0); status = FAIL; } # endif } if (!status) { Cs_sm_cb->css_wakeups_off = (char *)&Cs_sm_cb->css_servinfo[num_of_servers] - (char *)Cs_sm_cb; /* initialize the server-server event structures */ Cs_sm_cb->css_events_off = Cs_sm_cb->css_wakeups_off + (num_of_wakeups * sizeof(CS_SM_WAKEUP_CB)); Cs_sm_cb->css_events_end = Cs_sm_cb->css_css_desc.cssm_size; Cs_sm_cb->css_nsem = 0; Cs_sm_cb->css_usem = 0; } /* FIX ME - initialize all the server control blocks */ #ifdef xCL_NEED_SEM_CLEANUP /* Init Shared Memory mutex chain mutex */ if (!status) { CS_cp_synch_init(&Cs_sm_cb->css_shm_mutex, &status); } #endif return(status); }